第二阶段 bootLoader 未在 bochs 中加载,LINUX (ubuntu 16.04),Brokenthorn osdev 系列

Second stage bootLoader not loading in bochs, LINUX (ubuntu 16.04), Brokenthorn osdev series

我正在关注 brokenthorn OS 开发系列,直到现在我能够成功 运行 bootloader stage1 但是在 [=33] 上的 bochs 模拟器中从 FAT12 软盘加载第二阶段 bootloader 有一些问题=] machine(ubuntu 16.04)(虽然在虚拟盒子中工作正常)。这是我的 stage1 引导加载程序:

bits 16

org  0                      ;we will set segments later

start:  jmp main

;***** BPB Parameter block *****
;must start 3 bytes after start (jmp main is of 3 byte)

bpbOEM          db "My OS   "           ; OEM identifier (Cannot exceed 8 bytes!)
bpbBytesPerSector:      DW 512
bpbSectorsPerCluster:   DB 1
bpbReservedSectors:     DW 1
bpbNumberOfFATs:    DB 2
bpbRootEntries:     DW 224
bpbTotalSectors:    DW 2880
bpbMedia:       DB 0xf8  ;; 0xF1
bpbSectorsPerFAT:   DW 9
bpbSectorsPerTrack:     DW 18
bpbHeadsPerCylinder:    DW 2
bpbHiddenSectors:   DD 0
bpbTotalSectorsBig:     DD 0
bsDriveNumber:          DB 0
bsUnused:       DB 0
bsExtBootSignature:     DB 0x29
bsSerialNumber:         DD 0xa0a1a2a3
bsVolumeLabel:          DB "MOS FLOPPY "
bsFileSystem:           DB "FAT12   "

Print:
    ;string pointed by ds:si, terminated by 0
    lodsb                   ;load next byte pointed by si to al
    or al, al               ;if al is zero
    jz PrintDone
    mov ah, 0eh             ;prepare fro bios vedio interuppt call
    int 10h
    jmp Print
    PrintDone:
        ret

ReadSectors :
    ;cx = no fo sectors to ReadSectors
    ;ax = strating sectors
    ;ES:BX = buffer to read to

    .MAIN :
        mov di, 0x0005       ;we will try 5 times if failed
    .SECTORLOOP :
        push ax
        push bx
        push cx
        call LBACHS          ;we will get absolute sector, absolute head and absolute track information from here
        mov ah, 0x02         ;prepare bios read interrupt
        mov al, 0x01         ;we will read one sector
        mov ch, byte[absoluteTrack]
        mov cl, byte[absoluteSector]
        mov dh, byte[absoluteHead]
        mov dl, byte[bsDriveNumber]
        int 0x13            ;bios read interrupt call
        jnc .SUCCESS        ;if sucessful
        xor ax, ax          ;retying again
        int 0x13            ;reset disk interuppt call
        dec di              ;decrease a try
        pop cx
        pop bx
        pop ax
        jnz .SECTORLOOP
        int 0x18            ;start basic

        .SUCCESS:
            pop cx
            pop bx
            pop ax
            add bx, word[bpbBytesPerSector]         ;next read buffer location
            inc ax                                  ;next sector to read
            loop .MAIN
            ret

ClusterLBA:
;convert custer no to LBACHS
;LBA = (cluster - 2)*sectors per cluster
        sub ax, 0x0002
        xor cx, cx
        mov cl, byte[bpbSectorsPerCluster]
        mul cx
        add ax, word[datasector]                    ;base of data sectors
        ret

LBACHS:
;convert LBA to CHS
;absolute sector = (logical sector % sector per track) + 1
;absolute head = (logical sector / sectors per track) % no of heads
;absoluteTrack = logical sector / (sectors per track * no of heads)
        xor dx, dx  
        div word [bpbSectorsPerTrack]
        inc dl
        mov byte[absoluteSector], dl
        xor dx, dx
        div word[bpbHeadsPerCylinder]
        mov byte[absoluteHead], dl
        mov byte[absoluteTrack], al
        ret

main:
        cli
        mov ax, 0x07C0                                       ;0x7C0*2^4 = 0x7C00
        mov ds, ax                                          ;setup segment registers
        mov es, ax
        mov fs, ax
        mov gs, ax

        ;create stack
        mov ax, 0x0000
        mov ss, ax
        mov sp, 0xFFFF
        sti

        ;display Starting
        mov si, msgStart
        call Print

        ;load root directory table
        LOAD_ROOT:
            ;size of root directory = 32*(no of root entries)/(bytes per sector) SECTORS
            xor cx, cx
            xor dx, dx
            mov ax, 0x0020
            mul word[bpbRootEntries]
            div word[bpbBytesPerSector]
            xchg ax, cx                         ;size of root in cx

            ;location root directory = reserved sectors + (no of FATS * sectors per FAT)
            mov al, byte [bpbNumberOfFATs]
            mul word [bpbSectorsPerFAT]
            add ax, word[bpbReservedSectors]
            mov word [datasector], ax
            add word [datasector], cx            ;start of data sector

            ;read root directory into memory 0x7C0:0x0200 = 7C00+0200
            mov bx, 0x0200
            call ReadSectors

            ;find stage2 boot loader
            mov cx, word[bpbRootEntries]
            mov di, 0x0200                      ;address of root table in memory
            .LOOP:
                push cx
                mov cx, 0x000B                  ;11 character name
                mov si, ImageName               ;Image name
                push di
                rep cmpsb
                    pop di
                    je LOAD_FAT
                    pop cx
                    add di, 0x0020              ;next entry in root table
                    loop .LOOP
                    jmp FAILURE

            LOAD_FAT:
            ;save starting cluster of boot image
            mov dx, word[di+0x001A]
            mov word[cluster], dx

            ;compute size of FAT and store in cx = no of FAT * sectors per FAT
            xor ax, ax
            mov al, byte[bpbNumberOfFATs]
            mul word[bpbSectorsPerFAT]
            mov cx, ax

            ;location of FAT in ax = no of reserved Sectors
            mov ax, word[bpbReservedSectors]

            ;read FAT in memory at 0x7C0:0x0200
            mov bx, 0x0200
            call ReadSectors

            ;load image file into memory at 0050:0000 => 0x500)
            mov ax, 0x0050
            mov es, ax
            mov bx, 0x0000
            push bx

            LOAD_IMAGE:

            mov ax, word[cluster]
            pop bx
            call ClusterLBA
            xor cx, cx
            mov cl, byte[bpbSectorsPerCluster]
            call ReadSectors
            push bx

            ;compute next cluster, remember cluster entries are of 12 bits = 3/2 bytes
            mov ax, word[cluster]
            mov cx, ax
            mov dx, ax
            shr dx, 0x0001          ;devide by 2
            add cx, dx              ;equals to 3/2*cluster number
            mov bx, 0x0200          ;location of FAT in memory
            add bx, cx              ;we moved 3/2*cluster no bytes from start
            mov dx, word[bx]        ;read 2 bytes in dx
            test ax, 0x0001         ;if this was odd cluster =>  lower 12 bits, else =>higher 12 bits will be used
            jnz .ODD_CLUSTER

            .EVEN_CLUSTER:
                and dx, 0000111111111111b
                jmp .DONE

            .ODD_CLUSTER:
                shr dx, 0x0004

            .DONE:
                mov word[cluster], dx   ;new cluster location
                cmp dx, 0x0FF0          ;if this was last cluster
                jb LOAD_IMAGE

            DONE:
                mov si, msgStageTwo
                call Print
                push word 0x0050      ;segment address
                push word 0x0000      ;offset in segment
                retf                  ;far return, both of the above value will be used

            FAILURE:
                mov si, msgFailure
                call Print
                mov ah, 0x00
                int 0x16            ;wait for key press
                int 0x19            ;reboot


            absoluteSector db 0x00
            absoluteHead   db 0x00
            absoluteTrack  db 0x00

            datasector     dw 0x0000
            cluster        dw 0x0000
            ImageName      db "KRNLDR  SYS"         ;must be 11 bytes
            msgStart     db 0x0D,0x0A, "Boot Loader starting (0x7c00)....", 0x0D, 0x0A, 0x00
            msgStageTwo  db "Jumping to stage2 (0x500)", 0x0D, 0x0A, 0x0D, 0x0A, 0x00
            msgFailure  db 0x0D, 0x0A, "ERROR : Press Key to Reboot", 0x0A, 0x00

            times 510-($-$$) db 0
            dw 0xAA55                               ;boot signature

我正在尝试在内存地址 0x500 处查找并加载第二阶段引导加载程序。似乎第二阶段没有在 0x500 加载。 Bochs 在打印 "jumping to second stage" 后挂起(在跳转到第二阶段之前打印调用)。这是bochs日志:

00000000000i[     ] Bochs x86 Emulator 2.6
00000000000i[     ]   Built from SVN snapshot on September 2nd, 2012
00000000000i[     ] System configuration
00000000000i[     ]   processors: 1 (cores=1, HT threads=1)
00000000000i[     ]   A20 line support: yes
00000000000i[     ] IPS is set to 4000000
00000000000i[     ] CPU configuration
00000000000i[     ]   level: 6
00000000000i[     ]   SMP support: no
00000000000i[     ]   APIC support: xapic
00000000000i[     ]   FPU support: yes
00000000000i[     ]   MMX support: yes
00000000000i[     ]   3dnow! support: no
00000000000i[     ]   SEP support: yes
00000000000i[     ]   SSE support: sse2
00000000000i[     ]   XSAVE support: no 
00000000000i[     ]   AES support: no
00000000000i[     ]   MOVBE support: no
00000000000i[     ]   ADX support: no
00000000000i[     ]   x86-64 support: yes
00000000000i[     ]   1G paging support: no
00000000000i[     ]   MWAIT support: yes
00000000000i[     ]   AVX support: no
00000000000i[     ]   VMX support: 1
00000000000i[     ] Optimization configuration
00000000000i[     ]   RepeatSpeedups support: yes
00000000000i[     ]   Fast function calls: yes
00000000000i[     ]   Handlers Chaining speedups: no
00000000000i[     ] Devices configuration
00000000000i[     ]   NE2000 support: yes
00000000000i[     ]   PCI support: yes, enabled=yes
00000000000i[     ]   SB16 support: yes
00000000000i[     ]   USB support: yes
00000000000i[     ]   VGA extension support: vbe cirrus
00000000000i[MEM0 ] allocated memory at 0x7f8a9189c010. after alignment, vector=0x7f8a9189d000
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[     ] lt_dlhandle is 0x3fb0540
00000000000i[PLGIN] loaded plugin libbx_hdimage.so
00000000000i[     ] lt_dlhandle is 0x3fb0ed0
00000000000i[PLGIN] loaded plugin libbx_pci.so
00000000000i[     ] lt_dlhandle is 0x3fb1a50
00000000000i[PLGIN] loaded plugin libbx_pci2isa.so
00000000000i[     ] lt_dlhandle is 0x3fb2460
00000000000i[PLGIN] loaded plugin libbx_acpi.so
00000000000i[     ] lt_dlhandle is 0x3fb2e60
00000000000i[PLGIN] loaded plugin libbx_cmos.so
00000000000i[     ] lt_dlhandle is 0x3fb37a0
00000000000i[PLGIN] loaded plugin libbx_dma.so
00000000000i[     ] lt_dlhandle is 0x3fb4230
00000000000i[PLGIN] loaded plugin libbx_pic.so
00000000000i[     ] lt_dlhandle is 0x3fb4ad0
00000000000i[PLGIN] loaded plugin libbx_pit.so
00000000000i[     ] lt_dlhandle is 0x3fb5500
00000000000i[PLGIN] loaded plugin libbx_floppy.so
00000000000i[     ] lt_dlhandle is 0x3fb60f0
00000000000i[PLGIN] loaded plugin libbx_vga.so
00000000000i[     ] lt_dlhandle is 0x3fb6880
00000000000i[PLGIN] loaded plugin libbx_ioapic.so
00000000000i[     ] lt_dlhandle is 0x3fb72c0
00000000000i[PLGIN] loaded plugin libbx_keyboard.so
00000000000i[     ] lt_dlhandle is 0x3fb7b60
00000000000i[PLGIN] loaded plugin libbx_harddrv.so
00000000000i[     ] lt_dlhandle is 0x3fc9c50
00000000000i[PLGIN] loaded plugin libbx_pci_ide.so
00000000000i[PLGIN] init_dev of 'pci' plugin device by virtual method
00000000000i[PCI  ] 440FX Host bridge present at device 0, function 0
00000000000i[PLGIN] init_dev of 'pci2isa' plugin device by virtual method
00000000000i[PCI  ] PIIX3 PCI-to-ISA bridge present at device 1, function 0
00000000000i[PLGIN] init_dev of 'cmos' plugin device by virtual method
00000000000i[CMOS ] Using local time for initial clock
00000000000i[CMOS ] Setting initial clock to: Fri Jan  5 20:53:22 2018 (time0=1515165802)
00000000000i[PLGIN] init_dev of 'dma' plugin device by virtual method
00000000000i[DMA  ] channel 4 used by cascade
00000000000i[PLGIN] init_dev of 'pic' plugin device by virtual method
00000000000i[PLGIN] init_dev of 'pit' plugin device by virtual method
00000000000i[PLGIN] init_dev of 'floppy' plugin device by virtual method
00000000000i[DMA  ] channel 2 used by Floppy Drive
00000000000e[FDD  ] cannot determine media geometry, trying to use defaults
00000000000i[FDD  ] fd0: '/dev/loop0' ro=0, h=2,t=80,spt=18
00000000000i[PLGIN] init_dev of 'vga' plugin device by virtual method
00000000000i[MEM0 ] Register memory access handlers: 0x00000000000a0000 - 0x00000000000bffff
00000000000i[VGA  ] interval=200000
00000000000i[MEM0 ] Register memory access handlers: 0x00000000e0000000 - 0x00000000e0ffffff
00000000000i[BXVGA] VBE Bochs Display Extension Enabled
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 ] rom at 0xc0000/41472 ('/usr/share/bochs/VGABIOS-lgpl-latest')
00000000000i[PLGIN] init_dev of 'acpi' plugin device by virtual method
00000000000i[PCI  ] ACPI Controller present at device 1, function 3
00000000000i[PLGIN] init_dev of 'ioapic' plugin device by virtual method
00000000000i[IOAP ] initializing I/O APIC
00000000000i[MEM0 ] Register memory access handlers: 0x00000000fec00000 - 0x00000000fec00fff
00000000000i[PLGIN] init_dev of 'keyboard' plugin device by virtual method
00000000000i[KBD  ] will paste characters every 1000 keyboard ticks
00000000000i[PLGIN] init_dev of 'harddrv' plugin device by virtual method
00000000000i[HD   ] Using boot sequence floppy, none, none
00000000000i[HD   ] Floppy boot signature check is enabled
00000000000i[PLGIN] init_dev of 'pci_ide' plugin device by virtual method
00000000000i[PCI  ] PIIX3 PCI IDE controller present at device 1, function 1
00000000000i[PLGIN] init_dev of 'unmapped' plugin device by virtual method
00000000000i[PLGIN] init_dev of 'biosdev' plugin device by virtual method
00000000000i[PLGIN] init_dev of 'speaker' plugin device by virtual method
00000000000i[PLGIN] init_dev of 'extfpuirq' plugin device by virtual method
00000000000i[PLGIN] init_dev of 'parallel' plugin device by virtual method
00000000000i[PAR  ] parallel port 1 at 0x0378 irq 7
00000000000i[PLGIN] init_dev of 'serial' plugin device by virtual method
00000000000i[SER  ] com1 at 0x03f8 irq 4
00000000000i[PLGIN] init_dev of 'gameport' plugin device by virtual method
00000000000i[PLGIN] init_dev of 'iodebug' plugin device by virtual method
00000000000i[PLGIN] register state of 'pci' plugin device by virtual method
00000000000i[PLGIN] register state of 'pci2isa' plugin device by virtual method
00000000000i[PLGIN] register state of 'cmos' plugin device by virtual method
00000000000i[PLGIN] register state of 'dma' plugin device by virtual method
00000000000i[PLGIN] register state of 'pic' plugin device by virtual method
00000000000i[PLGIN] register state of 'pit' plugin device by virtual method
00000000000i[PLGIN] register state of 'floppy' plugin device by virtual method
00000000000i[PLGIN] register state of 'vga' plugin device by virtual method
00000000000i[PLGIN] register state of 'unmapped' plugin device by virtual method
00000000000i[PLGIN] register state of 'biosdev' plugin device by virtual method
00000000000i[PLGIN] register state of 'speaker' plugin device by virtual method
00000000000i[PLGIN] register state of 'extfpuirq' plugin device by virtual method
00000000000i[PLGIN] register state of 'parallel' plugin device by virtual method
00000000000i[PLGIN] register state of 'serial' plugin device by virtual method
00000000000i[PLGIN] register state of 'gameport' plugin device by virtual method
00000000000i[PLGIN] register state of 'iodebug' plugin device by virtual method
00000000000i[PLGIN] register state of 'acpi' plugin device by virtual method
00000000000i[PLGIN] register state of 'ioapic' plugin device by virtual method
00000000000i[PLGIN] register state of 'keyboard' plugin device by virtual method
00000000000i[PLGIN] register state of 'harddrv' plugin device by virtual method
00000000000i[PLGIN] register state of 'pci_ide' 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]: 00000002 756e6547 6c65746e 49656e69
00000000000i[CPU0 ] CPUID[0x00000001]: 00000633 00010800 00002028 1fcbfbff
00000000000i[CPU0 ] CPUID[0x00000002]: 00410601 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x80000000]: 80000008 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x80000001]: 00000000 00000000 00000101 2a100000
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[CPU0 ] CPUID[0x80000005]: 01ff01ff 01ff01ff 40020140 40020140
00000000000i[CPU0 ] CPUID[0x80000006]: 00000000 42004200 02008140 00000000
00000000000i[CPU0 ] CPUID[0x80000007]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x80000008]: 00003028 00000000 00000000 00000000
00000000000i[PLGIN] reset of 'pci' plugin device by virtual method
00000000000i[PLGIN] reset of 'pci2isa' plugin device by virtual method
00000000000i[PLGIN] reset of 'cmos' plugin device by virtual method
00000000000i[PLGIN] reset of 'dma' plugin device by virtual method
00000000000i[PLGIN] reset of 'pic' plugin device by virtual method
00000000000i[PLGIN] reset of 'pit' plugin device by virtual method
00000000000i[PLGIN] reset of 'floppy' plugin device by virtual method
00000000000i[PLGIN] reset of 'vga' plugin device by virtual method
00000000000i[PLGIN] reset of 'acpi' plugin device by virtual method
00000000000i[PLGIN] reset of 'ioapic' plugin device by virtual method
00000000000i[PLGIN] reset of 'keyboard' plugin device by virtual method
00000000000i[PLGIN] reset of 'harddrv' plugin device by virtual method
00000000000i[PLGIN] reset of 'pci_ide' plugin device by virtual method
00000000000i[PLGIN] reset of 'unmapped' plugin device by virtual method
00000000000i[PLGIN] reset of 'biosdev' plugin device by virtual method
00000000000i[PLGIN] reset of 'speaker' plugin device by virtual method
00000000000i[SPEAK] Using /dev/console for output
00000000000i[PLGIN] reset of 'extfpuirq' plugin device by virtual method
00000000000i[PLGIN] reset of 'parallel' plugin device by virtual method
00000000000i[PLGIN] reset of 'serial' plugin device by virtual method
00000000000i[PLGIN] reset of 'gameport' plugin device by virtual method
00000000000i[PLGIN] reset of 'iodebug' plugin device by virtual method
00000000000i[XGUI ] Mouse capture off
00000000000i[XGUI ] Mouse capture off
00000000000i[MEM0 ] allocate_block: block=0x0 used 0x1 of 0x20
00000004661i[BIOS ] $Revision: 11318 $ $Date: 2012-08-06 19:59:54 +0200 (Mo, 06. Aug 2012) $
00000319051i[KBD  ] reset-disable command received
00000321813i[BIOS ] Starting rombios32
00000322255i[BIOS ] Shutdown flag 0
00000322852i[BIOS ] ram_size=0x02000000
00000323280i[BIOS ] ram_end=32MB
00000363809i[BIOS ] Found 1 cpu(s)
00000377990i[BIOS ] bios_table_addr: 0x000fa438 end=0x000fcc00
00000705785i[PCI  ] 440FX PMC write to PAM register 59 (TLB Flush)
00001033717i[P2I  ] PCI IRQ routing: PIRQA# set to 0x0b
00001033741i[P2I  ] PCI IRQ routing: PIRQB# set to 0x09
00001033765i[P2I  ] PCI IRQ routing: PIRQC# set to 0x0b
00001033789i[P2I  ] PCI IRQ routing: PIRQD# set to 0x09
00001033799i[P2I  ] write: ELCR2 = 0x0a
00001034578i[BIOS ] PIIX3/PIIX4 init: elcr=00 0a
00001042258i[BIOS ] PCI: bus=0 devfn=0x00: vendor_id=0x8086 device_id=0x1237 class=0x0600
00001044537i[BIOS ] PCI: bus=0 devfn=0x08: vendor_id=0x8086 device_id=0x7000 class=0x0601
00001046655i[BIOS ] PCI: bus=0 devfn=0x09: vendor_id=0x8086 device_id=0x7010 class=0x0101
00001046884i[PIDE ] new BM-DMA address: 0xc000
00001047504i[BIOS ] region 4: 0x0000c000
00001049538i[BIOS ] PCI: bus=0 devfn=0x0b: vendor_id=0x8086 device_id=0x7113 class=0x0680
00001049768i[ACPI ] new irq line = 11
00001049782i[ACPI ] new irq line = 9
00001049809i[ACPI ] new PM base address: 0xb000
00001049823i[ACPI ] new SM base address: 0xb100
00001049851i[PCI  ] setting SMRAM control register to 0x4a
00001213945i[CPU0 ] Enter to System Management Mode
00001213945i[CPU0 ] enter_system_management_mode: temporary disable VMX while in SMM mode
00001213955i[CPU0 ] RSM: Resuming from System Management Mode
00001377976i[PCI  ] setting SMRAM control register to 0x0a
00001392878i[BIOS ] MP table addr=0x000fa510 MPC table addr=0x000fa440 size=0xc8
00001394693i[BIOS ] SMBIOS table addr=0x000fa520
00001394744i[MEM0 ] allocate_block: block=0x1f used 0x2 of 0x20
00001397672i[BIOS ] Firmware waking vector 0x1ff00cc
00001402531i[BIOS ] ACPI tables: RSDP addr=0x000fa640 ACPI DATA addr=0x01ff0000 size=0x1f22
00001402568i[PCI  ] 440FX PMC write to PAM register 59 (TLB Flush)
00001403299i[BIOS ] bios_table_cur_addr: 0x000fa664
00001530917i[VBIOS] VGABios $Id: vgabios.c,v 1.75 2011/10/15 14:07:21 vruppert Exp $
00001530988i[BXVGA] VBE known Display Interface b0c0
00001531020i[BXVGA] VBE known Display Interface b0c5
00001533945i[VBIOS] VBE Bios $Id: vbe.c,v 1.64 2011/07/19 18:25:05 vruppert Exp $
00001600003i[XGUI ] charmap update. Font Height is 16
00014040953i[BIOS ] Booting from 0000:7c00
00065146879i[     ] dbg: Quit
00065146879i[CPU0 ] CPU is in real mode (active)
00065146879i[CPU0 ] CS.mode = 16 bit
00065146879i[CPU0 ] 00065146879i[XGUI ] Mouse capture off
00065146879i[CTRL ] quit_sim called with exit code 0

这里是bochs的配置文件:

romimage: file="/usr/share/bochs/BIOS-bochs-latest"
vgaromimage: file ="/usr/share/bochs/VGABIOS-lgpl-latest"
floppya: 1_44=/dev/loop0, status=inserted
display_library: x, options="gui_debug"
log: bochsout.txt

这就是我创建和安装 FAT12 软盘的方式

dd if=/dev/zero of=myfloppy.img bs=512 count=2880
losetup /dev/loop0 myfloppy.img 
mkdosfs -F 12 /dev/loop0
mount /dev/loop0 myfloppy -t msdos -o "fat=12"
dd if=LOADER.SYS of=/dev/loop0 
cp KRNLDR.SYS myfloppy

我的引导加载程序在虚拟机中也能正常工作,下面是一张图片

最后一行 "Preparing to load operating system" 是第二阶段引导加载程序的一部分。但是在bochs中无法正常工作,可能是什么原因?
最后是第二阶段引导加载程序(如果需要):

;*********************************************
;   Stage2.asm
;       - Second Stage Bootloader
;
;   Operating Systems Development Series
;*********************************************

org 0x0                 ; offset to 0, we will set segments later

bits 16                 ; we are still in real mode

; we are loaded at linear address 0x10000

jmp main                ; jump to main

;*************************************************;
;   Prints a string
;   DS=>SI: 0 terminated string
;************************************************;

Print:
    lodsb                   ; load next byte from string from SI to AL
    or          al, al      ; Does AL=0?
    jz          PrintDone   ; Yep, null terminator found-bail out
    mov         ah, 0eh ; Nope-Print the character
    int         10h
    jmp         Print       ; Repeat until null terminator found
PrintDone:
    ret                 ; we are done, so return

;*************************************************;
;   Second Stage Loader Entry Point
;************************************************;

main:
    cli                 ; clear interrupts
    push            cs      ; Insure DS=CS
    pop         ds

    mov         si, Msg
    call            Print

    cli                 ; clear interrupts to prevent triple faults
    hlt                 ; hault the syst

;*************************************************;
;   Data Section
;************************************************;

Msg db  "Preparing to load operating system...",13,10,0

这可能是因为您正试图在 Bochs 中使用 /dev/loop0,而它仍处于打开状态并作为挂载点处于活动状态。可能在将 KRNLDR.SYS 复制到软盘后,文件 and/or 脂肪表尚未从内存刷新到设备。

我真的建议您修改引导扇区并复制文件后避免出现问题:

umount myfloppy
losetup -d /dev/loop0

这应确保磁盘映像已完全更新(同步)并释放循环设备。然后在您的 Bochs 配置文件中,您可以将 1_44=/dev/loop0 替换为 image=myfloppy.img。 Bochs 应该能够正确打开磁盘映像 myfloppy.img