运行《自己动手写操作系统》中例子时的问题
代码如下:
- Assembly code
;-------------------------------------------;boot.asm;Usage : nasm boot.asm -o boot.bin;-------------------------------------------%include "pm.inc"org 07c00h jmp STARTSECTION .gdt; base limit attrGDT_NULL :Descriptor 0, 0, 0 ;Null descriptorGDT_DESC_CODE32 :Descriptor 0, SegCode32Len - 1, DA_C + DA_32GDT_DESC_VIDEO :Descriptor 0B8000h, 0ffffh, DA_DRW ;Graphic Memory descriptor;End of GdtGdtLen equ $-GDT_NULL ;Gdt lengthGdtPtr dw GdtLen-1 ;Gdt limit dd 0;Selector Code32Selector equ GDT_DESC_CODE32 - GDT_NULLVideoSelector equ GDT_DESC_VIDEO - GDT_NULL;End of selcetor[SECTION .s16][BITS 16]START: mov ax, cs mov ds, ax mov es, ax mov ss, ax mov sp, 0100h ;init the base of code32selector xor eax, eax mov ax, cs shl eax, 4 add eax, SEG_CODE32 mov word [GDT_DESC_CODE32 + 2], ax shr eax, 16 mov word [GDT_DESC_CODE32 + 4], ax mov word [GDT_DESC_CODE32 + 7], ax ;init gdtr xor eax, eax mov ax, ds shl eax, 4 add eax, GDT_NULL ;eax <- gdt base mov dword [GdtPtr + 2], eax ;eax -> GdtPtr ;loda gdtr lgdt [GdtPtr] ;close interrupt cli ;open A20 in al, 92h or al, 00000010b out 92h, al ;ready to protected mode mov eax, cr0 or eax, 1 mov cr0, eax ;jmp to protected mode jmp dword Code32Selector:0 ;Code32Selector32 -> cs, 0->ip;End of Section .s16[SECTION .s32][BITS 32]SEG_CODE32: mov ax, VideoSelector mov gs, ax ;Graphic Segement Selector mov edi, (80 * 14 + 77) * 2 ;Column 15, Row 77 mov ah, 0Ch ;Background : Black Font Color : Red mov al, 'P' mov [gs:edi], ax ;stop jmp $SegCode32Len equ $-SEG_CODE32;End of Section .s32times 386-($-$$) db 0 ; 填充剩下的空间,使生成的二进制代码恰好为512字节 dw 0xaa55 ;这个是结束标志符
最后边的那段填充空间是我自己在例子上添加的,如果不添加,生成的二进制文件不够512字节,而且最后两位不是以55AA结尾,运行bochs会报no bootable device found的错误,加上这段就没有这个错误了,但是会有新的问题,log如下:
00000000000i[ ] ACPI support: no
00000000000i[ ] NE2000 support: no
00000000000i[ ] PCI support: no, enabled=no
00000000000i[ ] SB16 support: no
00000000000i[ ] USB support: no
00000000000i[ ] VGA extension support: vbe
00000000000i[MEM0 ] allocated memory at 0xb4f78008. after alignment, vector=0xb4f79000
00000000000i[MEM0 ] 32.00MB
00000000000i[MEM0 ] mem block size = 0x00100000, blocks=32
00000000000i[MEM0 ] rom at 0xfffe0000/131072 ('/usr/share/bochs/BIOS-bochs-latest')
00000000000i[MEM0 ] rom at 0xc0000/40448 ('/usr/share/vgabios/vgabios.bin')
00000000000e[DEV ] Bochs is not compiled with SB16 support
00000000000i[CMOS ] Using local time for initial clock
00000000000i[CMOS ] Setting initial clock to: Thu Dec 1 12:27:40 2011 (time0=1322713660)
00000000000i[DMA ] channel 4 used by cascade
00000000000i[DMA ] channel 2 used by Floppy Drive
00000000000i[FDD ] fd0: 'Image' ro=0, h=2,t=80,spt=18
00000000000i[VGA ] interval=300000
00000000000i[MEM0 ] Register memory access handlers: 0x00000000000a0000 - 0x00000000000bffff
00000000000i[XGUI ] test_alloc_colors: 16 colors available out of 16 colors tried
00000000000i[XGUI ] font 8 wide x 16 high, display depth = 24
00000000000i[MEM0 ] Register memory access handlers: 0x00000000e0000000 - 0x00000000e0ffffff
00000000000i[VGA ] VBE Bochs Display Extension Enabled
00000000000i[ ] init_dev of 'unmapped' plugin device by virtual method
00000000000i[ ] init_dev of 'biosdev' plugin device by virtual method
00000000000i[ ] init_dev of 'speaker' plugin device by virtual method
00000000000i[SPEAK] Failed to open /dev/console: Resource temporarily unavailable
00000000000i[SPEAK] Deactivating beep on console
00000000000i[ ] init_dev of 'extfpuirq' plugin device by virtual method
00000000000i[ ] init_dev of 'ioapic' plugin device by virtual method
00000000000i[IOAP ] initializing I/O APIC
00000000000i[MEM0 ] Register memory access handlers: 0x00000000fec00000 - 0x00000000fec00fff
00000000000i[ ] init_dev of 'keyboard' plugin device by virtual method
00000000000i[KBD ] will paste characters every 1000 keyboard ticks
00000000000i[ ] init_dev of 'harddrv' plugin device by virtual method
00000000000i[HD ] CD on ata0-1: '/dev/cdrom'
00000000000i[CD1 ] load cdrom with path=/dev/cdrom
00000000000i[CD1 ] Using direct access for cdrom.
00000000000i[HD ] Media present in CD-ROM drive
00000000000i[CD1 ] cdrom: Data track 1, length 19944
00000000000i[HD ] Capacity is 19944 sectors (38.95 MB)
00000000000i[HD ] Using boot sequence floppy, none, none
00000000000i[HD ] Floppy boot signature check is enabled
00000000000i[ ] init_dev of 'serial' plugin device by virtual method
00000000000i[SER ] com1 at 0x03f8 irq 4
00000000000i[ ] init_dev of 'parallel' plugin device by virtual method
00000000000i[PAR ] parallel port 1 at 0x0378 irq 7
00000000000i[ ] register state of 'unmapped' plugin device by virtual method
00000000000i[ ] register state of 'biosdev' plugin device by virtual method
00000000000i[ ] register state of 'speaker' plugin device by virtual method
00000000000i[ ] register state of 'extfpuirq' plugin device by virtual method
00000000000i[ ] register state of 'ioapic' plugin device by virtual method
00000000000i[ ] register state of 'keyboard' plugin device by virtual method
00000000000i[ ] register state of 'harddrv' plugin device by virtual method
00000000000i[ ] register state of 'serial' plugin device by virtual method
00000000000i[ ] register state of 'parallel' plugin device by virtual method
00000000000i[SYS ] bx_pc_system_c::Reset(HARDWARE) called
00000000000i[CPU0 ] cpu hardware reset
00000000000i[APIC0] allocate APIC id=0 (MMIO enabled) to 0x00000000fee00000
00000000000i[CPU0 ] CPUID[0x00000000]: 00000003 756e6547 6c65746e 49656e69
00000000000i[CPU0 ] CPUID[0x00000001]: 00000f03 00000800 00000000 07cbfbff
00000000000i[CPU0 ] CPUID[0x00000002]: 00410601 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x00000003]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x00000004]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x00000007]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x80000000]: 80000004 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x80000001]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x80000002]: 20202020 20202020 20202020 6e492020
00000000000i[CPU0 ] CPUID[0x80000003]: 286c6574 50202952 69746e65 52286d75
00000000000i[CPU0 ] CPUID[0x80000004]: 20342029 20555043 20202020 00202020
00000000000i[ ] reset of 'unmapped' plugin device by virtual method
00000000000i[ ] reset of 'biosdev' plugin device by virtual method
00000000000i[ ] reset of 'speaker' plugin device by virtual method
00000000000i[ ] reset of 'extfpuirq' plugin device by virtual method
00000000000i[ ] reset of 'ioapic' plugin device by virtual method
00000000000i[ ] reset of 'keyboard' plugin device by virtual method
00000000000i[ ] reset of 'harddrv' plugin device by virtual method
00000000000i[ ] reset of 'serial' plugin device by virtual method
00000000000i[ ] reset of 'parallel' plugin device by virtual method
00000000000i[XGUI ] [x] Mouse on
00000003305i[BIOS ] $Revision: 1.247 $ $Date: 2010/04/04 19:33:50 $
00000318057i[KBD ] reset-disable command received
00000442371i[VBIOS] VGABios $Id$
00000442442i[VGA ] VBE known Display Interface b0c0
00000442474i[VGA ] VBE known Display Interface b0c5
00000443143i[VBIOS] VBE Bios $Id$
00000760659i[BIOS ] Starting rombios32
00000761138i[BIOS ] Shutdown flag 0
00000761777i[BIOS ] ram_size=0x02000000
00000762239i[BIOS ] ram_end=32MB
00000802861i[BIOS ] Found 1 cpu(s)
00000819037i[BIOS ] bios_table_addr: 0x000fbc18 end=0x000fcc00
00000831660i[BIOS ] bios_table_cur_addr: 0x000fbc18
00001200000i[XGUI ] charmap update. Font Height is 16
00004665588i[BIOS ] IDE time out
00016897668i[BIOS ] Booting from 0000:7c00
00016897756e[CPU0 ] jump_protected: gate type 0 unsupported
00016897756e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d)
00016897756e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x08)
00016897756i[CPU0 ] CPU is in protected mode (active)
00016897756i[CPU0 ] CS.d_b = 16 bit
00016897756i[CPU0 ] SS.d_b = 16 bit
00016897756i[CPU0 ] | EAX=60000011 EBX=00000000 ECX=00090000 EDX=00000000
00016897756i[CPU0 ] | ESP=00000100 EBP=00000000 ESI=000e0000 EDI=0000ffac
00016897756i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
00016897756i[CPU0 ] | SEG selector base limit G D
00016897756i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00016897756i[CPU0 ] | CS:0000( 0004| 0| 0) 00000000 0000ffff 0 0
00016897756i[CPU0 ] | DS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
00016897756i[CPU0 ] | SS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
00016897756i[CPU0 ] | ES:0000( 0005| 0| 0) 00000000 0000ffff 0 0
00016897756i[CPU0 ] | FS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
00016897756i[CPU0 ] | GS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
00016897756i[CPU0 ] | EIP=00007c74 (00007c74)
00016897756i[CPU0 ] | CR0=0x60000011 CR2=0x00000000
00016897756i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00016897756i[CPU0 ] 0x00007c74>> jmp far 0008:00000000 : 66EA000000000800
00016897756e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00016897756i[SYS ] bx_pc_system_c::Reset(HARDWARE) called
00016897756i[CPU0 ] cpu hardware reset
加红的那段应该就是exception,有哪位大侠能帮忙分析一下,谢谢了
[解决办法]
修改之后的内存值:
0x00007c04 <bogus+ 0>:0x000000000x000000000x7c8000140x00409800
0x00007c14 <bogus+ 16>:0x8000ffff0x0000920b0x7c0400170x00000000
0x00007c24 <bogus+ 32>:0xd88ec88c0xd08ec08e
修改之前的内存值:
0x00007c04 <bogus+ 0>:0x000000000x000000000x7c7c00140x00400000
0x00007c14 <bogus+ 16>:0x8000ff000x0000920b0x7c0400170x00000000
0x00007c24 <bogus+ 32>:0xd88ec88c0xd08ec08e
红色的部分是第2个描述符的第33位到64位,正确的情况下type为0x98,错误的情况下是0x00(被覆盖了),所以会报:
00016897756e[CPU0 ] jump_protected: gate type 0 unsupported
00016897756e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d)
00016897756e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x08)