Introduction To Bootloader
Introduction To Bootloader
Introduction to Bootloader
Introduction to Bootloader
Merck Hung [email protected], 洪豪謙
Agenda
1. 簡單的 Bootloader 範例
2. 關於 FAT BPB Structure
3. 關於 MBR Signature
4. 開發工具
5. 組合語言
6. Partition Table
7. INT 16h 取得 Keyboard Input
8. VGA RAM 於螢幕列印字串
9. 跳轉 C 語言
10. 實際測試 Bootloader 開機
Olux Organization
Introduction to Bootloader
1. 簡單的 Bootloader 範例
以下是一簡單的 Bootloader 範例, 一開始部分是傳統 FAT12 的 Structure.
以現在的機器來說, 這部分不要也可以開機, 但如果有的話相容性較佳.
0x?? indicates that any 8-bit value is allowed in that byte. What this forms is a three-byte Intel
x86 unconditional branch (jump) instruction that jumps to the start of the operating system
bootstrap code. This code typically occupies the rest of sector 0 of the volume following the
BPB and possibly other sectors. Either of these forms is acceptable. JmpBoot[0] = 0xEB is the
more frequently used format.
BS_OEMName 3 8 “MSWIN4.1” There are many misconceptions about this field. It is only a name string.
Microsoft operating systems don’t pay any attention to this field. Some FAT drivers do. This is
the reason that the indicated string, “MSWIN4.1”, is the recommended setting, because it is the
setting least likely to cause compatibility problems. If you want to put something else in here,
that is your option, but the result may be that some FAT drivers might not recognize the volume.
Typically this is some indication of what system formatted the volume.
BPB_BytsPerSec 11 2 Count of bytes per sector. This value may take on only the following values: 512, 1024, 2048 or
4096. If maximum compatibility with old implementations is desired, only the value 512 should
be used. There is a lot of FAT code in the world that is basically “hard wired” to 512 bytes per
sector and doesn’t bother to check this field to make sure it is 512. Microsoft operating systems
will properly support 1024, 2048, and 4096.
Note: Do not misinterpret these statements about maximum compatibility. If the media being
recorded has a physical sector size N, you must use N and this must still be less than or equal to
4096. Maximum compatibility is achieved by only using media with specific sector sizes.
BPB_SecPerClus 13 1 Number of sectors per allocation unit. This value must be a power of 2 that is greater than 0.
The legal values are 1, 2, 4, 8, 16, 32, 64, and 128. Note however, that a value should never be
used that results in a “bytes per cluster” value (BPB_BytsPerSec * BPB_SecPerClus) greater
than 32K (32 * 1024). There is a misconception that values greater than this are OK. Values that
cause a cluster size greater than 32K bytes do not work properly; do not try to define one. Some
versions of some systems allow 64K bytes per cluster value. Many application setup programs
will not work correctly on such a FAT volume.
BPB_RsvdSecCn 14 2 Number of reserved sectors in the Reserved region of the volume starting at the first sector of
t the volume. This field must not be 0. For FAT12 and FAT16 volumes, this value should never
be anything other than 1. For FAT32 volumes, this value is typically 32. There is a lot of FAT
code in the world “hard wired” to 1 reserved sector for FAT12 and FAT16 volumes and that
doesn’t bother to check this field to make sure it is 1. Microsoft operating systems will properly
support any non-zero value in this field.
Olux Organization
Introduction to Bootloader
BPB_NumFATs 16 1 The count of FAT data structures on the volume. This field should always contain the value 2
for any FAT volume of any type. Although any value greater than or equal to 1 is perfectly
valid, many software programs and a few operating systems’ FAT file system drivers may not
function properly if the value is something other than 2. All Microsoft file system drivers will
support a value other than 2, but it is still highly recommended that no value other than 2 be
used in this field.
The reason the standard value for this field is 2 is to provide redundancy for the FAT data
structure so that if a sector goes bad in one of the FATs, that data is not lost because it is
duplicated in the other FAT. On non-disk-based media, such as FLASH memory cards, where
such redundancy is a useless feature, a value of 1 may be used to save the space that a second
copy of the FAT uses, but some FAT file system drivers might not recognize such a volume
properly.
BPB_RootEntCnt 17 2 For FAT12 and FAT16 volumes, this field contains the count of 32-byte directory entries in the
root directory. For FAT32 volumes, this field must be set to 0. For FAT12 and FAT16 volumes,
this value should always specify a count that when multiplied by 32 results in an even multiple
of BPB_BytsPerSec. For maximum compatibility, FAT16 volumes should use the value 512.
BPB_TotSec16 19 2 This field is the old 16-bit total count of sectors on the volume. This count includes the count of
all sectors in all four regions of the volume. This field can be 0; if it is 0, then BPB_TotSec32
must be non-zero. For FAT32 volumes, this field must be 0. For FAT12 and FAT16 volumes,
this field contains the sector count, and BPB_TotSec32 is 0 if the total sector count “fits” (is
less than 0x10000).
BPB_Media 21 1 0xF8 is the standard value for “fixed” (non-removable) media. For removable media, 0xF0 is
frequently used. The legal values for this field are 0xF0, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD,
0xFE, and 0xFF. The only other important point is that whatever value is put in here must also
be put in the low byte of the FAT[0] entry. This dates back to the old MS-DOS 1.x media
determination noted earlier and is no longer usually used for anything.
BPB_FATSz16 22 2 This field is the FAT12/FAT16 16-bit count of sectors occupied by ONE FAT. On FAT32
volumes this field must be 0, and BPB_FATSz32 contains the FAT size count.
BPB_SecPerTrk 24 2 Sectors per track for interrupt 0x13. This field is only relevant for media that have a geometry
(volume is broken down into tracks by multiple heads and cylinders) and are visible on interrupt
0x13. This field contains the “sectors per track” geometry value.
BPB_NumHeads 26 2 Number of heads for interrupt 0x13. This field is relevant as discussed earlier for
BPB_SecPerTrk. This field contains the one based “count of heads”. For example, on a 1.44
MB 3.5-inch floppy drive this value is 2.
BPB_HiddSec 28 4 Count of hidden sectors preceding the partition that contains this FAT volume. This field is
generally only relevant for media visible on interrupt 0x13. This field should always be zero on
media that are not partitioned. Exactly what value is appropriate is operating system specific.
BPB_TotSec32 32 4 This field is the new 32-bit total count of sectors on the volume. This count includes the count
of all sectors in all four regions of the volume. This field can be 0; if it is 0, then BPB_TotSec16
must be non-zero. For FAT32 volumes, this field must be non-zero. For FAT12/FAT16 volumes,
this field contains the sector count if BPB_TotSec16 is 0 (count is greater than or equal to
0x10000).
Olux Organization
Introduction to Bootloader
3. 關於 MBR Signature
BIOS會要求 MBR 內的 Bootloader, 在 512 bytes 的邊界上, 務必要有 0xAA55 的 MBR Signature.
如無則 BIOS 會認為此顆硬碟無法開機.
在組合語言中, 我們利用 DUP Pseudo Macro 來填滿 0, 讓 0xAA55 正好對齊 512 bytes 邊界.
Olux Organization
Introduction to Bootloader
4. 開發工具
在組合語言的開發中, 我們將會使用 MASM 6.11 來組譯我們的 Bootloader.
而 C語言方面, 則使用 “Digital Mars C/C++ Compilers” 來做.
ASSEMBLER = ml.exe
CC = sc.exe
EXE2ROM = utils\exe2rom.exe
ASSEMBLE_FLAGS = /Fm /Fl /c
CC_FLAGS = -c -ms
OBJS =
all: sldr
sldr:
$(ASSEMBLER) $(ASSEMBLE_FLAGS) [email protected]
$(CC) -ms -c cstart.c
$(CC) -ms sldr.obj cstart.obj
$(EXE2ROM) -s0x7c00 SLDR.EXE sldr.bin
clean:
rm -rf *.img *.bin *.EXE *.exe *.map *.obj *.lst *.MAP *.STS *.CV4 DELETED
Olux Organization
Introduction to Bootloader
5. 組合語言
SubRoutine 的要素
scnClrScr PROC NEAR PUBLIC
push ds
push ax
push bx
push cx
ClrScr:
; Clear Screen
mov ds:[bx], ax
add bx, 2
sub cx, 2
jnz ClrScr
pop cx
pop bx
pop ax
pop ds
ret
scnClrScr ENDP
Flow Control
liChkSnapshotRequest PROC NEAR PUBLIC
push es
push di
push ax
; Check Flag
cmp es:[di].liCtlInfo.SnapshotRequest, 0
je notSet
notSet:
Olux Organization
Introduction to Bootloader
6. Partition Table
基本上 MBR 有 512 bytes 可供使用, 但其中需扣除 Partition Table 的大小才是真正 MBR
Bootloader 可用的空間.
Field Sample
Byte Offset Meaning
Length Value
Boot Indicator. Indicates whether the partition is the system
partition. Legal values are:
00 BYTE 0x80
00 = Do not use for booting.
80 = System partition.
01 BYTE 0x01 Starting Head.
Starting Sector. Only bits 0-5 are used. Bits 6-7 are the upper two
02 6 bits 0x01
bits for the Starting Cylinder field.
Starting Cylinder. This field contains the lower 8 bits of the cylinder
03 10 bits 0x00 value. Starting cylinder is thus a 10-bit number, with a maximum
value of 1023.
System ID. This byte defines the volume type. In Windows NT, it
04 BYTE 0x06 also indicates that a partition is part of a volume that requires the
use of the HKEY_LOCAL_MACHINE\SYSTEM\DISK Registry subkey.
05 BYTE 0x0F Ending Head.
Ending Sector. Only bits 0-5 are used. Bits 6-7 are the upper two
06 6 bits 0x3F
bits for the Ending Cylinder field.
Ending Cylinder. This field contains the lower 8 bits of the cylinder
07 10 bits 0x196 value. Ending cylinder is thus a 10-bit number, with a maximum
value of 1023.
3F 00 00
08 DWORD Relative Sector.
00
51 42 06
12 DWORD Total Sectors.
00
Olux Organization
Introduction to Bootloader
取得 Keyboard Input
7. INT 16h取得
;##############################################################################
; wait_input -- Call BIOS service to get keyboard input
;
; Input :
; None
;
; Output:
; AH = Scan code
; AL = ASCII code
;
; Modified:
; None
;
wait_input MACRO
xor ax, ax
int 16h
ENDM
9. 跳轉 C 語言
jmp _main
jmp $
MAIN endp
;###############################################################################
; Data area
;
_TEXT16 ENDS
EXTERN _main:FAR
_TEXT ENDS