我目前正在开发我的引导加载程序,但我有问题。
我使用 Bochs 测试引导加载程序,编译引导加载程序并制作磁盘映像:
rm disk.bin
rm boot.bin
rm post.bin
nasm bootloader.asm -o boot.bin
nasm postmbr.asm -o post.bin
cat boot.bin post.bin > disk.bin
这是 bootloader.asm:
[BITS 16] ;Tells the assembler that its a 16 bit code
[ORG 0x7C00] ;Origin, tell the assembler that where the code will
MOV SI, HelloString ;Store string pointer to SI
MOV AH, 02h ; read sector command
MOV AL, 01h
MOV CX, 0001h
MOV DH, 00h
MOV DL, 80h ;disk
MOV AX, 7E00h
MOV ES, AX ;buffer
MOV BX, 00h ;offset
CALL PrintString
JMP 0x7E00 ;Infinite loop, hang it here.
PrintCharacter: ;Procedure to print character on screen
;Assume that ASCII value is in register AL
MOV AH, 0Eh ;Tell BIOS that we need to print one charater on screen.
MOV BH, 00h ;Page no.
MOV BL, 07h ;Text attribute 0x07 is lightgrey font on black background
INT 10h ;Call video interrupt
RET ;Return to calling procedure
PrintString: ;Procedure to print string on screen
;Assume that string starting pointer is in register SI
next_character: ;Lable to fetch next character from string
MOV AL, [SI] ;Get a byte from string and store in AL register
INC SI ;Increment SI pointer
OR AL, AL ;Check if value in AL is zero (end of string)
JZ exit_function ;If end then return
CALL PrintCharacter ;Else print the character which is in AL register
JMP next_character ;Fetch next character from string
exit_function: ;End label
RET ;Return from procedure
;Data
HelloString db 'Loading OS demo...', 0 ;HelloWorld string ending with 0
TIMES 510 - ($ - $$) db 0 ;Fill the rest of sector with 0
DW 0xAA55 ;Add boot signature at the end of bootloader
和 postmbr.asm:
[BITS 16] ;Tells the assembler that its a 16 bit code
MOV SI, HelloString ;Store string pointer to SI
CALL PrintString ;Call print string procedure
JMP $ ;Infinite loop, hang it here.
PrintCharacter: ;Procedure to print character on screen
;Assume that ASCII value is in register AL
MOV AH, 0x0E ;Tell BIOS that we need to print one charater on screen.
MOV BH, 0x00 ;Page no.
MOV BL, 0x07 ;Text attribute 0x07 is lightgrey font on black background
INT 0x10 ;Call video interrupt
RET ;Return to calling procedure
PrintString: ;Procedure to print string on screen
;Assume that string starting pointer is in register SI
next_character: ;Lable to fetch next character from string
MOV AL, [SI] ;Get a byte from string and store in AL register
INC SI ;Increment SI pointer
OR AL, AL ;Check if value in AL is zero (end of string)
JZ exit_function ;If end then return
CALL PrintCharacter ;Else print the character which is in AL register
JMP next_character ;Fetch next character from string
exit_function: ;End label
RET ;Return from procedure
;Data
HelloString db 'Hello World', 0 ;HelloWorld string ending with 0
TIMES 512 - ($ - $$) db 0 ;Fill the rest of sector with 0
这是来自 Bochs 的崩溃日志:
00000004661i[BIOS ] $Revision: 11318 $ $Date: 2012-08-06 19:59:54 +0200 (Mo, 06. Aug 2012) $
00000319074i[KBD ] reset-disable command received
00000321808i[BIOS ] Starting rombios32
00000322242i[BIOS ] Shutdown flag 0
00000322837i[BIOS ] ram_size=0x02000000
00000323258i[BIOS ] ram_end=32MB
00000363787i[BIOS ] Found 1 cpu(s)
00000377969i[BIOS ] bios_table_addr: 0x000fa438 end=0x000fcc00
00000396429i[BIOS ] bios_table_cur_addr: 0x000fa438
00000524046i[VBIOS] VGABios $Id: vgabios.c,v 1.75 2011/10/15 14:07:21 vruppert Exp $
00000524117i[BXVGA] VBE known Display Interface b0c0
00000524149i[BXVGA] VBE known Display Interface b0c5
00000527074i[VBIOS] VBE Bios $Id: vbe.c,v 1.64 2011/07/19 18:25:05 vruppert Exp $
00000800003i[XGUI ] charmap update. Font Height is 16
00000866078i[BIOS ] ata0-0: PCHS=1/1/2 translation=none LCHS=1/1/2
00004743252i[BIOS ] IDE time out
00016726470i[BIOS ] Booting from 0000:7c00
00016755553e[CPU0 ] write_virtual_word_32(): segment limit violation
00016755553e[CPU0 ] write_virtual_word_32(): segment limit violation
00016755553e[CPU0 ] write_virtual_word_32(): segment limit violation
00016755553i[CPU0 ] CPU is in real mode (active)
00016755553i[CPU0 ] CS.mode = 16 bit
00016755553i[CPU0 ] SS.mode = 16 bit
00016755553i[CPU0 ] EFER = 0x00000000
00016755553i[CPU0 ] | EAX=000000aa EBX=00000007 ECX=00090001 EDX=00000080
00016755553i[CPU0 ] | ESP=00000001 EBP=00000000 ESI=000e7c45 EDI=0000ffac
00016755553i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of DF if tf SF zf af PF cf
00016755553i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00016755553i[CPU0 ] | CS:0000( 0004| 0| 0) 00000000 0000ffff 0 0
00016755553i[CPU0 ] | DS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
00016755553i[CPU0 ] | SS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
00016755553i[CPU0 ] | ES:7e00( 0005| 0| 0) 0007e000 0000ffff 0 0
00016755553i[CPU0 ] | FS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
00016755553i[CPU0 ] | GS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
00016755553i[CPU0 ] | EIP=0000fd34 (0000fd34)
00016755553i[CPU0 ] | CR0=0x60000010 CR2=0x00000000
00016755553i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00016755553i[CPU0 ] 0x0000fd34>> pusha : 60
00016755553e[CPU0 ] exception(): 3rd (12) exception with no resolution, shutdown status is 00h, resetting
00016755553i[SYS ] bx_pc_system_c::Reset(HARDWARE) called
00016755553i[CPU0 ] cpu hardware reset
00016755553i[APIC0] allocate APIC id=0 (MMIO enabled) to 0x00000000fee00000
00016755553i[CPU0 ] CPUID[0x00000000]: 00000002 68747541 444d4163 69746e65
00016755553i[CPU0 ] CPUID[0x00000001]: 00000633 00010800 00000008 17cbfbff
00016755553i[CPU0 ] CPUID[0x00000002]: 00000000 00000000 00000000 00000000
00016755553i[CPU0 ] CPUID[0x80000000]: 80000008 68747541 444d4163 69746e65
00016755553i[CPU0 ] CPUID[0x80000001]: 00000633 00000000 00000000 c1c3f3ff
00016755553i[CPU0 ] CPUID[0x80000002]: 20444d41 6c687441 74286e6f 7020296d
00016755553i[CPU0 ] CPUID[0x80000003]: 65636f72 726f7373 00000000 00000000
00016755553i[CPU0 ] CPUID[0x80000004]: 00000000 00000000 00000000 00000000
00016755553i[CPU0 ] CPUID[0x80000005]: 01ff01ff 01ff01ff 40020140 40020140
00016755553i[CPU0 ] CPUID[0x80000006]: 00000000 42004200 02008140 00000000
00016755553i[CPU0 ] CPUID[0x80000007]: 00000000 00000000 00000000 00000000
00016755553i[CPU0 ] CPUID[0x80000008]: 00002028 00000000 00000000 00000000
00016755553i[ ] reset of 'cmos' plugin device by virtual method
00016755553i[ ] reset of 'dma' plugin device by virtual method
00016755553i[ ] reset of 'pic' plugin device by virtual method
00016755553i[ ] reset of 'pit' plugin device by virtual method
00016755553i[ ] reset of 'floppy' plugin device by virtual method
00016755553i[ ] reset of 'vga' plugin device by virtual method
00016755553i[ ] reset of 'ioapic' plugin device by virtual method
00016755553i[ ] reset of 'keyboard' plugin device by virtual method
00016755553i[ ] reset of 'harddrv' plugin device by virtual method
00016755553i[ ] reset of 'unmapped' plugin device by virtual method
00016755553i[ ] reset of 'biosdev' plugin device by virtual method
00016755553i[ ] reset of 'speaker' plugin device by virtual method
00016755553i[ ] reset of 'extfpuirq' plugin device by virtual method
00016755553i[ ] reset of 'parallel' plugin device by virtual method
00016755553i[ ] reset of 'serial' plugin device by virtual method
这是 Bochs 的配置文件:
# configuration file generated by Bochs
plugin_ctrl: unmapped=1, biosdev=1, speaker=1, extfpuirq=1, parallel=1, serial=1
config_interface: textconfig
display_library: x
memory: host=32, guest=32
romimage: file="/usr/share/bochs/BIOS-bochs-latest"
vgaromimage: file="/usr/share/bochs/VGABIOS-lgpl-latest"
boot: disk
floppy_bootsig_check: disabled=0
# no floppya
# no floppyb
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-master: type=disk, mode=flat, translation=auto, path="disk.bin", cylinders=1, heads=1, spt=2, biosdetect=auto, model="Generic 1234"
ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15
ata2: enabled=0
ata3: enabled=0
pci: enabled=0
vga: extension=vbe, update_freq=5
cpu: count=1, ips=4000000, model=bx_generic, reset_on_triple_fault=1, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0
cpuid: family=6, model=0x03, stepping=3, mmx=1, apic=xapic, sse=sse2, sse4a=0, sep=1, aes=0, xsave=0, xsaveopt=0, movbe=0, adx=0, smep=0, mwait=1
cpuid: vendor_string="AuthenticAMD"
cpuid: brand_string="AMD Athlon(tm) processor"
print_timestamps: enabled=0
port_e9_hack: enabled=0
private_colormap: enabled=0
clock: sync=none, time0=local, rtc_sync=0
# no cmosimage
# no loader
log: -
logprefix: %t%e%d
panic: action=ask
error: action=report
info: action=report
debug: action=ignore
keyboard: type=mf, serial_delay=250, paste_delay=100000, keymap=
user_shortcut: keys=none
mouse: enabled=0, type=ps2, toggle=ctrl+mbutton
parport1: enabled=1, file=""
parport2: enabled=0
com1: enabled=1, mode=null, dev=""
com2: enabled=0
com3: enabled=0
com4: enabled=0
我不知道出了什么问题,我还没有在其他平台上测试过我的引导加载程序。