![]() |
---|
This is retired content. This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. |
Brett Muzzey
Microsoft Corporation
January 2001
Summary: This paper describes CEPC boot loader models, such as Loadcepc.exe and alternative loaders, and contains code for a sample boot loader for use with Microsoft Windows CE Platform Builder 3.0. (19 printed pages).
Introduction
A boot loader resides on the target device and manages the boot
process. You can also use the boot loader to download code, such as
a Microsoft Windows CE operating system (OS) image, from the
development workstation to the target device. Once the OS is
loaded, you can use the boot loader to monitor and debug the target
device. Because the boot loader is used only for development, you
do not need to include it with your Windows CE platform. A CEPC enables you to develop Windows CE–based applications and
device drivers on, providing a readily available platform to test
and evaluate the features of the Windows CE OS. Microsoft Windows
CE Platform Builder 3.0 includes a fully operational board support
package (BSP) for a CEPC so that you can build test platforms for a
CEPC without having to develop an OEM adaptation layer (OAL) or BSP
from scratch. Because CEPC is a generic hardware specification, not a
particular hardware platform, there is no way to write a single
boot loader that can bring up every possible CEPC. An ISA Ethernet
or a PCMCIA Ethernet card would each require changes to the boot
loader. Platform Builder 3.0 includes Loadcepc.exe, an MS–DOS–based boot
loader that allows you to install a generic Windows CE–based image
on any desktop computer. Loadcepc.exe allows for easy image
bring-up, but it relies on an MS-DOS boot floppy and basic
input/output system (BIOS). Loadcepc.exe is only one boot loader
method; Loadcepc.exe is not the only boot loader model, and a boot
loader need not be tied to MS-DOS. You can use any of the following boot loader models to develop a
boot loader for a CEPC. Also included is sample code for a boot loader written for an
AMD ElanSC400 board. Use the Loadcepc.exe model to create a boot loader that is
targeted at supporting the broadest range of computer platforms. It
is typically used in a development environment, as it is flexible
and easily accepts parameters for display resolution, Ethernet and
serial port debugging, and so on. The Loadcepc.exe loader that
includes Eboot.bin, used to perform Ethernet downloads, is
dependent upon an MS–DOS boot disk floppy and two BIOS features:
system BIOS and Video Electronics Standard Association (VESA) BIOS.
Loadcepc.exe relies on the system BIOS to handle chip set
configuration and bus enumeration and configuration. In cases where
native video driver support is not available—Windows CE supports
many different native drivers—it uses the VESA BIOS to set the
video mode. Loadcepc.exe only uses the CEPC to load an image; Windows CE is
in no way dependent upon MS–DOS. See the
Getting Started Guideor
Building a CEPCin Platform Builder help for specifics and
step-by-step instructions on using the Loadcepc.exe model. One alternative to using the Loadcepc.exe model with an MS–DOS
boot floppy is to store the boot loader image on disk as a system
file and allowing the existing BIOS to load it. This lets you
quickly boot an image, but loses the command-line configuration
available in Loadcepc.exe; however, you could introduce a
configuration file, stored on the media, and read by the loader at
boot time. This model also requires a large disk volume if you want
to store the CE–based image on disk. Another boot loader model is a BIOS extension, which can be used
if you want to avoid running MS–DOS but are willing to rely on the
BIOS for chip-set configuration. You place your boot loader in a
BIOS extension that plugs into a network boot programmable ROM
(PROM) socket or is available in some other fashion to being
decoded or detected in the BIOS extension address range. No hard or
floppy disk is required, but you may need to have a PROM programmer
to create this boot ROM. With this mode, there are no Loadcepc.exe
parameters available at boot time. This model would typically be used in a setting where the
Windows CE–based devices are clients on a host network and could
rely on a server for boot image at all times. It is simpler than
the Flashable ROM model since the computer BIOS has done much of
the chip-set configuration prior to invoking the BIOS
extension. An additional boot loader model is a ROM boot loader where you
place a boot loader directly in ROM and replace the standard
computer BIOS. This is a chip set-specific model and is also the
most complex alternate model to Loadcepc.exe. The loader must
initialize low level RAM, northbridge, southbridge, PCI bus
enumeration, VESA video BIOS configuration, and so on. This model has a similar implementation to the BIOS extension
model, but would only be used in a homogeneous environment since
each new board or chip set would require a different boot loader.
This is the primary loader model used by non-x86 platforms. This sample boot loader for Windows CE has been written for an
AMD ElanSC400 evaluation board. It loads Windows CE without
requiring MS–DOS or the Loadcepc.exe utility. This section presents
sections of a sample loader implementation, organized into logical
steps that are described in brief detail. Since this sample boot loader seeks to replace MS–DOS and
Loadcepc.exe, it must emulate the required aspects of these
components. Some of the drivers in the CEPC environment take
parameters from Loadcepc.exe. These parameters are normally passed
to Loadcepc.exe through the MS–DOS command line, and are then made
available to the drivers by a pointer to a reserved global memory
area. See the LOADRBUF reserved area in
%_WINCEROOT%\PLATFORM\CEPC\FILES\CONFIG.BIB. This sample boot loader defines the parameters and sets a
pointer to the parameter buffer before transferring control to
Windows CE. This boot loader is set up to use either an ISA-based graphics
adapter or a custom VESA local bus graphics adapter. The boot
loader automatically detects which graphics adapter is installed
and configures the hardware accordingly. The ISA graphics adapter uses the video BIOS to set up the mode
before passing control to Windows CE. No video BIOS is present or
required for some VESA bus devices, for example, the IGS 2010 card,
since the IGS video driver handles the device configuration. The sample boot loader defines memory based on the physical
devices available, configures the ISA bus and I/O devices,
initializes the graphics mode, delivers run parameters to the CEPC,
and passes control to the Windows CE kernel. The following steps are required.
Define the temp stack, as it needs to be in place when it
receives control. Windows CE will set up its own stack when it gets
control, but not immediately. The AbsCall macro forces a far call to a particular fixed
segment or offset. The OpSizePrefix macro makes it easier to add 66h prefixes to
instructions. Create a user-defined data type for an interrupt descriptor. In
a similar fashion, the Global Descriptor Table (GDT) would be
defined, see
Define a flash-based GDTfor more
information. At reset, the x86 processor will be executing in real mode, for
example 16-bit segmented mode. The initial boot loader code will
need to be assembled for this environment. An alternative is to use
a 32-bit compiler/assembler and use operand and address prefixes to
hand code the initial loader instructions. Enable two banks of 32-bit dynamic RAM (DRAM). This is the standard memory configuration shipped with the SC400
evaluation board starts at 0 and goes as high as 16 MB. The loader
could choose to dynamically size DRAM or could assume a size at
build time. The SDRAM controller for the platform then gets
programmed with the memory limit, bank size, and page size
information. Create the memory map so that the ROMCS0 will point to the boot
loader in the 128 KB dip socket. ROMCS1 and 2 are used to hold the
CE–based image. Since the memory map will have 32 MB of DRAM, and 8
MB of flash memory, not counting the 128 KB just below 1 MB, the
memory map will be set up as follows: The following code documents the number of wait states for the
physical flash device. You should configure the number of wait
states required by your specific flash memory device. Set the processor to 100 megahertz (MHz). Set up the bus and external systems. Set up MMSE (PCMCIA slot B window 3) to start at 32 MB for 4
MB Set up MMSF to start at 36 MB for 4 MB Enable MMS windows E, and F only. Set up the ElanSC400 evaluation board I/O device initialization
constants. Define a flash-based GDT as this is a ROM–based GDT containing
three descriptors. The first is the same for all GDTs and is called
the null descriptor. It is there to allow the OS to invalidate a
selector without causing a general protection (GP) fault. If anyone
tries to use a selector that is loaded with the null descriptor, a
GP fault will occur. The other two selectors provide a flat 32 GB address space. This
means that the segment will have a starting address of 0, and the
32-bit EIP, etc. will be the linear address. Although the selectors
are being used by the hardware for address calculation, they are
not relevant. One of the descriptors is set up to support the code
segment, and must be loaded into CS. The other is set up for data
segments, and may be loaded into DS-GS. X86 architecture requires
separate descriptors for CS than for DS-GS because the protection
mechanism does not allow writing to CS or executing code from
DS-GS. Set up the video BIOS extension to allow it to set up its own
int 10h handler, you need a dummy extension in place. The video
BIOS extension makes an int 10h call to disable the display-a
standard computer BIOS would normally have a simple routine set up
for int 10h by this time. Returning AX = 0 tells the video BIOS
that the int 10h function is not supported by the system BIOS. Pass control directly through a FAR jump by the X86 reset vector
hook in the boot loader. The sample code completes minimal chip
initialization, transitions into protect mode, and then passes
control to the CE OS which must be set up to reside at 3 MB
(02000000h) by an entry in the Windows CE .bib file. Initialize the supported SC400, SuperIO, ISA or VESA graphics
adapter. The sample code carries out basic SC400 initialization,
and then enables the graphics adapter by leveraging its BIOS
extension ROM. At this point, a temporary stack is needed. Get addressability to the ROM–based constants. The following code carries out basic initialization for the
ElanSC400. At this point DRAM is enabled. For the SC400, the first two reads of the index register after
POR give the ID mechanism, 88H followed by 0H. Set up the real-time clock divide chain as soon as possible, as
the real-time clock on the SC400 can take several seconds to
stabilize. There are two options for graphics with this demonstration: you
can use an ISA–based graphics adapter which has its video BIOS on
board, or you can put an IGS VESA local bus card on the SC400
evaluation board, and remove the ISA graphics adapter from the
system. If you use the ISA–based graphics adapter, you will be
limited to 320x240 resolution. The following code automatically
detects if the VESA card is installed. If so, the VESA bus is
enabled. This limits the use of certain SC400 options, so please
refer to the SC400 user manual to understand the trade-offs you
incur when using the VESA local bus. Currently, the CE driver for IGS does not initialize the
graphics chip. It can change the mode, but nothing else. Thus,
leverage the IGS VGA BIOS which is provided free of charge by IGS.
Since the IGS card has no option ROM like a normal ISA card would
for storing the VGA BIOS, this software component must be blown
into the RFA. An ISA card would decode this at C0000h, so it should be put
into the same location when booting from the RFA. However, by
default, the C0000 segment is not part of the ROMCS0 decode. Cycles
to that address range go to ISA so an ISA VGA card can decode them.
Thus, if booting from RFA, be sure to enable the C000 segment for
ROMCS0 linear decode. The ElanSC400 evaluation board routes a few of the SuperIO's
GPIOs back to the VESA slot. Normally, these signals are pulled
high on the board. The GPIO port for these GPIO signals is located
at 78h in the I/O map by default. To determine if the VESA video
card is installed, read the GPIO port. If bits 6 and 7 are set,
then no card is installed. This is the only way to know whether ISA
or VL card is present. For an IGS card on the VESA bus, no initialization is required.
The VESA bus must be enabled. Hook int 10h (video) and point it to a dummy handler ready for
when the VGA BIOS extension gets control. Get 32 bit pointer to dummy interrupt 10h handler in EAX. Poke the pointer into the IVT. Call VGA BIOS extension to install its own int 10h handler For ISA VGA support, the sample code calls the graphics card int
10h handler to set 320x200 8 BPP graphics Initializes the DRAM-based GDTR structure, and also switches the
CPU to protected mode. First, generate a flat pointer to the protected code entry
point. Next, poke the selector portion of the pointer with the code
descriptor. Load the pointer. Use the opsize prefix to get the full 48-bit
pointer. Configure the drivers at run time. This is part of the boot
loader block information that gets passed in reserved memory from
the boot loader to the Windows CE OS C declarations in
Loadcepc.exe. Setup the minimum possible in terms of data selectors and stack
pointers. It then jumps to the boot loader main() function. All of the following are required. The stack is at the top of DRAM. The CEPC environment differs from environments such as the
Hitachi D9000 hardware development platform (ODO) board. The
Loadcepc.exe utility acts as a boot loader which leverages MS–DOS
and BIOS. Since this assembly language boot loader seeks to replace
BIOS, MS–DOS, and Loadcepc.exe, it must emulate the required
aspects of these components. Some of the drivers in the CEPC
environment take parameters from Loadcepc.exe. These parameters are
normally passed to Loadcepc.exe by the MS–DOS command line, and are
then available to the drivers using a pointer in a reserved global
memory area (see the LOADRBUF reserved area in the
\WINCE\PLATFORM\CEPC\FILES\CONFIG.BIB file). By default, the 32-bit
pointer to the parameter array is at 001FFFFCh. The following code
places a pointer to the parameter array that is defined locally in
this boot loader. Jump to the kernel entry point by jumping to the offset 0 in the
image. There is a jump there to the actual entry point. The
starting location of the CE-based image is configured using
settings in the CONFIG.BIB file. For more information on Windows CE ROM image data formats, see
the Platform Builder help. The following two documents are of interest because the loader
needs to know how to read these two file types and place the code,
data, and so on, in the correct location:
For general information on Microsoft file systems of interest
when loading the OS image from local device storage like a hard
disk drive or a Compact Flash/ATA Disk card, see this
Microsoft Web Site. For more information on boot sectors and how they interface with
startup code, go to http://www.nondot.org/sabre/os/S1Booting/. For general information on creating a boot loader, see the
following information:
For Ethernet download code and supporting functions see the
ETHDBG directory located at
WINCE300\PUPLIB\COMMOM\OAK\DRIVERS\ETHDBG.
Loadcepc.exe
Disk Resident
BIOS Extension
ROM Boot Loader
Sample Boot Loader
Alternate graphics configurations
Define a temporary stack
Define general structures
Begin 16-bit code segment
Enable DRAM
Create a memory map and configure chip
selects
Initialize CSC registers
Configure ISA bus and external system
configurations
Set up I/O devices
Define a flash-based GDT
Begin 16-bit executable code
Begin startup
Initialize the graphics adapter
Configure clocks
Initialize graphics
Load the GDTR
Configure drivers
Set up data selectors and stack
pointer
Load CEPC parameters
Jump to entry point in the Windows CE
kernel
For More Information
Introduction
Boot loader
Description
Loadcepc.exe
Relies on system BIOS and MS-DOS
Disk Resident
Eboot.bin is physically stored on disk
BIOS Extension
Boot loader is placed as a BIOS extension into a
network PROM socket
Flashable ROM
Boot loader is placed directly in ROM, replacing
system BIOS
Loadcepc.exe
Disk Resident
BIOS Extension
ROM Boot Loader
Sample Boot Loader
Alternate graphics configurations
Define a temporary stack
.486p =00FFFFFC TopOfStack = 00FFFFFCh ; ESP goes
at top of 16 MB DRAM =001FFFFC ParamBlockPtr = 001FFFFCh ; Must
match LOADRBUF in Config.bib
AbsCall MACRO SegValue,OfsValue db 09Ah ; Far
call dw OfsValue,SegValue ENDM
OpSizePrefix MACRO db 66h ENDM
Define general structures
00000000 idesc STRUC 00000000 01*(0000) off_15_0
DW 0 00000002 01*(0000) sel DW 0 00000004 01*(00) DB 0 00000005
01*(86) dpl DB 10000110b 00000006 01*(0000) off_31_16 DW 0 00000008
idesc ENDS
Begin 16-bit code segment
0000 CODE SEGMENT PARA PUBLIC USE16 'CODE' assume
cs:CODE
Enable DRAM
0000 SC400RegInit: 0000 AB00 dw 0AB00h 0002 AB01
dw 0AB01h 0004 0004 dw 0004h ; Max out DRAM timings. May change if
using slower DRAM. 0006 4005 dw 4005h ; Enable refresh, use 32 kHz
osc for refresh
Create a memory map and configure chip
selects
; FFFF0000 - FFFFFFFF ; used only by far jump to
boot loader below 1 MB ; 00280000 - FFFEFFFF ; unused by anything ;
00240000 - 027FFFFF ; 4 MB accessed via MMSF which generates ROMCS2
; 00200000 - 023FFFFF ; 4 MB accessed via MMSE which generates
ROMCS1 ; 01000000 - 01FFFFFF ; Space for 16 MB more of system DRAM
; 00100000 - 00FFFFFF ; 15 MB system DRAM for Windows CE ; 000F0000
- 000FFFFF ; boot loader code and data (ROMCS0) ; 000D0000 -
000EFFFF ; unused by anything ; 000C0000 - 000CFFFF ; reserved for
graphics adapter ROM ; 000B0000 - 000BFFFF ; unused by anything ;
000A0000 - 000AFFFF ; graphics buffer ; 00000000 - 0009FFFF ;
System RAM used only by boot loader 0008 9031 dw 9031h ; Point
MMSE->ROMCS1, and MMSF>ROMCS2 000A 0FB1 dw 0FB1h ; Force
routing of CS2 to GPIO_CS0 000C 02A6 dw 02A6h ; GPIO_CS0 low to
support ROMCS2, CS1 = high 000E 05A0 dw 05A0h ; GPIO_CS0,
GPIO_CS1=outputs
0010 0226 dw 0226h ; 2 wait states for ROMCS1
accesses--supports 90 ns flash memory 0012 0228 dw 0228h ; 2 wait
states for ROMCS2 accesses --supports 90 ns flash memory 0014 1425
dw 1425h ; Configure romcs1 for fast speed, 16-bit application ROM
interface 0016 1427 dw 1427h ; Configure romcs2 for fast speec,
16-bit application ROM interface 0018 C030 dw 0C030h ; Enable
caching for MMSE and MMS F 001A 00F1 dw 00F1h ; Force standard
PCMCIA mode so MMS C-F are available 001C 02D0 dw 02D0h ; Enable
PCMCIA controller--required for 3e0/3e1 access for mms
Initialize CSC registers
001E 0580 dw 0580h ; CPU clk:hyper = 100 MHz,
high = 33 MHz, low = 8 MHz 0020 4140 dw 4140h ; Enable hyper speed
mode
Configure ISA bus and external system
configurations
0022 5F38 dw 5F38h ; Select ISA
IOCS16,iochrdy,PIRQ1,PIRQ0&AEN signals Vs. GPIOs 0024 1439 dw
1439h ; select ISA signals vs. kbd rows, enable LBL2 0026 08C1 dw
08C1h ; Enable external keyboard I/F 0028 01D1 dw 01D1h ; Enable
SC400 internal UART at 3f8 002A 40D8 dw 40D8h ; Make SC400 internal
UART use IRQ4 002C 1ED4 dw 1ED4h ; Route pirq0->IRQ14 (IDE
support) and pirq1->IRQ1 (keyboard support) 002E 0CD5 dw 0CD5h ;
Route pirq2->IRQ12--required for PS/2 mouse support 0030 03D6 dw
03D6h ; Route pirq4->IRQ3 (PCNET ISA network card support) 0032
01E5 dw 01E5h ; Enable proper termination for all configurations
above SC400MMSInit:
0034 0068 dw 0068h 0036 2069 dw 2069h 0038 FF6A
dw 0FF6Ah 003A 236B dw 236Bh 003C 006C dw 006Ch 003E 206D dw
206Dh
0040 0070 dw 0070h 0042 2471 dw 2471h 0044 FF72
dw 0FF72h 0046 2773 dw 2773h 0048 0074 dw 0074h 004A 1C75 dw
1C75h
004C 1846 dw 1846h =000D SC400MMSTableLen = ($ -
SC400MMSInit) / 2
Set up I/O devices
004E SuperIO_Reg_Initial_Values: 004E 00 FF 4A db
000h, 11111111b, 01001010b ; Enable UART, FDC, IDE 0051 01 CC 0C db
001h, 11001100b, 00001100b ; Set UART 1 to base 2E8 0054 05 FF 05
db 005h, 11111111b, 00000101b ; Enable keyboard, disable RTC 0057
0A FF 80 db 00Ah, 11111111b, 80h ; CS 0 address low 005A 10 FF 06
db 010h, 11111111b, 06h ; CS 0 address high 005D 0B B8 90 db 00Bh,
10111000b, 90h ; CS 0 enable 0060 0C FF 80 db 00Ch, 11111111b, 80h
; CS 1 address low 0063 11 FF 00 db 011h, 11111111b, 00h ; CS 1
address high 0066 0D 38 90 db 00Dh, 00111000b, 90h ; CS 1 enable
=0009 Num_SuperIO_Initial_Values = ($ - SuperIO_Reg_Initial_Values)
/ 3
Define a flash-based GDT
0069 CE_GDT: ; start of descriptor table =0000
GDT_NULL_SLCTR = ($-CE_GDT) ; null descriptor 0069 0000 dw 0000h ;
Segment limit 15:0 006B 00 00 00 db 00h, 00h, 00h ; Segment base
23:0 006E 00 db 00h ; Segment control bits - bits 3:0 =
exe,e/c,w/r,a 006F 00 db 00h ; Bits 7:6 = G,DB, bits 5:4 = n/a,
bits 3:0=Segment limit + 19:16 0070 00 db 00h ; Segment base 31:24
=0008 GDT_CODE_SLCTR = ($-CE_GDT) ; Code segment descriptor;
Executable segment starts at 0 + and is 4 GB long. 0071 FFFF dw
0FFFFh ; Segment limit 15:0 0073 00 00 00 db 00h, 00h, 00h ;
Segment base 23:0 0076 9E db 10011110b ; Segment control bits: 7=P,
6:5=DPL, 4=DT, 3:0=exe,c,r,a 0077 CF db 11001111b ; Bits 7:6 =
G,DB, bits 5:4 = n/a, bits 3:0=Segment limit + =0010 GDT_DATA_SLCTR
= ($-CE_GDT) ; Data segment descriptor; DS-ES segments start at 0
and are 4 GB long. 0079 FFFF dw 0FFFFh ; Segment limit 15:0 007B 00
00 00 db 00h, 00h, 00h ; Segment base 23:0 007E 92 db 10010010b ;
Segment control bits: 7=P, 6:5=DPL, 4=DT, 3:0=exe,e,w,a 007F CF db
11001111b ; Bits 7:6 = G,DB, bits 5:4 = n/a, bits 3:0=Segment limit
+ 19:16 0080 00 db 00h ; Segment base 31:24
Begin 16-bit executable code
PUBLIC InitialInt10hHandler 0081
InitialInt10hHandler PROC 0081 B8 0000 mov ax,0 ; Indicate
non-handled function. 0084 CF IRET 0085 InitialInt10hHandler ENDP
The SC400 PMU only changes modes on edges of the 32 kHz clock. 0085
Wait2Falling32KhzClkEdges PROC 0085 B0 82 mov al,82h 0087 E6 22 out
22h,al 0089 WaitForFirstDrop: 0089 E4 23 in al, 23h 008B A8 08 test
al, 8 008D 75 FA jnz WaitForFirstDrop 008F WaitForFirstRise: 008F
E4 23 in al, 23h 0093 74 FA jz WaitForFirstRise 0095
WaitFor2ndDrop: 0095 E4 23 in al, 23h 0097 A8 08 test al, 8 0099 75
FA jnz WaitFor2ndDrop 009B C3 ret 009C Wait2Falling32KhzClkEdges
ENDP
Begin startup
009C Start Up:
Initialize the graphics adapter
009C B8 9000 mov ax, 09000h 009F 8E D0 mov ss, ax
00A1 B8 FFFE mov ax, 0FFFEh 00A4 8B E0 mov sp, ax
00A6 8C C8 mov ax, cs 00A8 8E D8 mov ds, ax
00AA BE 0000r mov si, offset SC400RegInit 00AD B9
001A mov cx, SC400RegTableLen 00B0 BA 0022 mov dx, 22h ; The SC400
CSC index reg 00B3 F3> 6F rep outsw ; Blast out the inits
00B5 BE 0034r mov si, offset SC400MMSInit 00B8 B9
000D mov cx, SC400MMSTableLen 00BB BA 03E0 mov dx, 3E0h ; The SC400
CSC index reg 00BE F3> 6F rep outsw ; Blast out the inits 00C0
BA 0398 mov dx,398h ;Superio index register on the ElanSC400
evaluation board
00C3 EC in al,dx 00C4 EC in al,dx 00C5 BE 004Er
mov si, offset SuperIO_Reg_Initial_Values 00C8 B9 0009 mov cx,
Num_SuperIO_Initial_Values 00CB Output_Super: 00CB 2E: 8B 04 mov
ax, cs:[si] ; get index into '306's indexed regs ; and mask to AH
00CE EE out dx,al ; Output index 00CF 42 inc dx 00D0 EC in al,dx
00D1 F6 D4 not ah ; Get save mask 00D3 22 C4 a nd al,ah 00D5 F6 D4
not ah ; Get replace mask 00D7 2E: 22 64 02 and ah,cs:[si+2] 00DB
83 C6 03 add si,3 00DE 0A C4 or al,ah 00E0 EE out dx,al ; Must do
twice for SuperIO 00E1 EE out dx,al 00E2 4A dec dx 00E3 E2 E6 loop
Output_Super
Configure clocks
00E5 B0 8A mov al,0Ah + 80h 00E7 E6 70 out 70h,al
00E9 E4 71 in al,71h 00EB 24 8F and al,10001111b ;mask off divider
bits 00ED 0C 20 or al,00100000b ;or in divider enable bit 00EF E6
71 out 71h,al ;enable the oscillator
Initialize graphics
0106 B3 00 mov bl, 0 ; Will be set to 1 if VESA
present 0108 E4 78 in al, 78h ; Check for VESA bus option card 010A
24 C0 and al, 0C0h 010C 3C C0 cmp al, 0C0h 010E 74 16 je
UseISAVideo ; If both bits are set then no VESA
0110 B0 14 mov al, 14h ; Enable VL Bus and hold
it in reset 0112 E6 22 out 22h, al 0114 E4 23 in al, 23h 0116 0C 18
or al, 18h 0118 E6 23 out 23h, al 011A B0 14 mov al,14h ; Remove
the reset from the VESA bus 011C E6 22 out 22h,al 011E E4 23 in
al,23h 0120 24 EF and al,0efh 0122 E6 23 out 23h,al 0124 EB 1F jmp
PastISAGraphicsInit 0126 UseISAVideo:
0126 B8 0000 mov ax, 0 ; Get IVT addressability
0129 8E D8 mov ds, ax
012B B8 0000s mov ax, seg InitialInt10hHandler
012E 66| C1 E0 10 shl eax, 16 0132 B8 0081r mov ax, offset
InitialInt10hHandler
0135 BB 0040 mov bx,10h*4 ; 10h*40 gives int 10h
IVT slot 0138 66| 89 07 mov [bx], eax ; DS:[40h]= pointer to
IHR
AbsCall 0C000h,3 ; call far 0C000h:0003 1 593
013B 9A db 09Ah ; Far call 1 594 013C 0003 C000 dw 3,0C000h
0140 B8 0013 mov ax, 0013h ; ah=set_mode=0,
al=mode=13h 0143 CD 10 int 10h ; 320x200x8Bpp (mode 13h) 0145
PastISAGraphicsInit: 0145 B8 0000s mov ax,data ; Get addressability
to data 0148 8E D8 mov ds,ax Set up a linear pointer to the GDT.
The GDT is in flash. 014A 66| B8 00000000 mov eax, 0 0150 B8 0000s
mov ax, code ; In flash, so it is relative to the CODE seg 0153 66|
C1 E0 04 shl eax,4 0157 66| BB 00000000 mov ebx, 0 015D BB 0069r
mov bx,offset CE_GDT; Must use bx with 16-bit offset 0160 66| 03 C3
add eax, ebx ; and then do the seg:offset merge later 0163 66| A3
0008r mov PtrToGdt, eax 0167 B8 0017 mov ax, (3*8) - 1 ; GDT has 3
entries 016A A3 0006r mov GDTLimit, ax
Load the GDTR
016D 66| B8 00000000 mov eax, 0 0173 B8 0000s mov
ax, code32 0176 66| C1 E0 04 shl eax, 4 017A 66| 05 00000004r add
eax, offset ProtectCodeEntryPoint 0180 66| A3 0000r mov
PtrToProtModeEntry, eax
0184 B8 0008 mov ax, 8 0187 A3 0004r mov
ProtModeEntrySelector, ax
OpSizePrefix 1 638 018A 66 db 66h 018B 0F 01 16
0006r lgdt GDT_Pointer 0190 0F 20 C0 mov eax, cr0 ; Get the current
CR0 0193 0C 01 or al, 1 ; Set the PE bit to enable protected mode
0195 0F 22 C0 mov cr0, eax ; Go to pmode, but STILL 16 bit ("D"
bit=0) 0198 EB 00 jmp FlushPipeline 019A FlushPipeline: 019A 66| FF
2E 0000r jmp fword ptr PtrToProtModeEntry 019F CODE ENDS ; End of
16-bit code segment 00000000 CODE32 SEGMENT PARA PUBLIC USE32
'CODE32' assume cs:CODE32
Configure drivers
UCHAR ucVideoMode; // Upper nibble: 0xh = Unknown
adapter type 1xh = ATI based graphics adapter 2xh = S3 Trio64 based
graphics adapter 3xh = Tseng labs based graphics adapter 4x-fxh =
Unknown adapter type Lower nibble: 0 = 320x200 x 8BPP color 1 =
480x240 color 2 = 640x480 color 3-FFh = undefined UCHAR ucComPort;
// UCHAR ucBaudDivisor; // UCHAR ucPCIConfigType; // PUBLIC
ParameterArray 00000000 ParameterArray: 00000000 00 db 0 ; parm[0]
= video mode (0 = 320x200x8BPP) 00000001 00 db 0 ; parm[1] = not
used (changing the debug com port does not work) 00000002 01 db 1 ;
parm[2] = baud rate divisor (1=115200kbs, 2 = 57600, etc.) 00000003
00 db 0 ; parm[3] = PCI config (0 = NO PCI, i.e. ISA) 00000004
ProtectCodeEntryPoint:
Set up data selectors and stack
pointer
00000004 66| B8 0010 mov ax, GDT_DATA_SLCTR
00000008 8E D8 mov ds, ax 0000000A 8E C0 mov es, ax 0000000C 8E D0
mov ss, ax 0000000E BC 00FFFFFC mov esp, TopOfStack
Load CEPC parameters
Compute the segmentation to generate a linear
pointer to the parameter block. 00000013 B8 00000000s mov eax,
CODE32 00000018 C1 E0 04 shl eax, 4 0000001B 05 00000000r add eax,
offset ParameterArray 00000020 A3 001FFFFC mov [ds:ParamBlockPtr],
eax ; Create ptr to parms
Jump to entry point in the Windows CE
kernel
00000025 BE 02000000 mov esi, 02000000h ; first
address of ROM space at 32 MB 0000002A FF E6 jmp esi 0000002C
CODE32 ENDS ; End of 32-bit code segment END StartUp
For More Information