自定义Bootloader无法找到Kernel问题求助
Hey there, let's dig into why your bootloader can't locate your kernel. I've gone through your code and build script, and there are a few critical issues causing this problem. Let's break them down one by one with fixes:
1. Your Build Script Isn't Actually Copying the Kernel to the Floppy
This is a classic order-of-operations mistake. Right now, you're copying kernel.bin to the tmp-loop directory before mounting the floppy image to that same directory. When you mount the image, it overwrites everything in tmp-loop—so your kernel never makes it onto the floppy at all!
Fix the script like this:
#! /bin/bash cd image hdiutil create -fs MS-DOS -sectors 2880 floppy cd ../system nasm -f bin boot.asm -o boot.bin nasm -f bin kernel.asm -o kernel.bin cd .. dd conv=notrunc if=system/boot.bin of=image/floppy.dmg dev=`hdid -nomount image/floppy.dmg` sudo mkdir tmp-loop # Mount the floppy first, THEN copy the kernel into it sudo mount -t msdos ${dev} tmp-loop sudo cp system/kernel.bin tmp-loop/ # Now unmount and clean up diskutil umount tmp-loop hdiutil detach ${dev} sudo rm -rf tmp-loop hdiutil convert image/floppy.dmg -format UDTO -o image/image.iso
2. Filename Mismatch in the Bootloader
FAT12 uses the strict 8.3 filename format. When you copy kernel.bin to the FAT12 floppy, it gets stored as KERNEL BIN (two spaces between KERNEL and BIN) to fill the 8-character main name field. But your bootloader is searching for KERNEL BIN (only one space)—so it never matches the actual file entry.
Update the filename in your bootloader:
filename db 'KERNEL BIN',0 ; Two spaces here to match FAT12's 8.3 format
3. Broken lba_to_hts Subroutine
Your lba_to_hts subroutine has a stack mistake: you push ax then bx, but pop ax then bx. Since the stack is last-in-first-out, this swaps the values of ax and bx when you restore them. This corrupts your disk geometry calculations, leading to failed reads of the root directory or FAT.
Fix the pop order:
lba_to_hts: push ax push bx mov bx, ax xor dx, dx div word [SectorsPerTrack] add dl, 1 mov cl, dl mov ax, bx xor dx, dx div word [SectorsPerTrack] xor dx, dx div word [Sides] mov dh, dl mov ch, al ; Pop bx first (since we pushed it last) to restore original register values pop bx pop ax mov dl, [drive] ret
4. Redundant Stack Operations in load_file
In the .load_sector section, you have pop ax followed by push ax—this does nothing useful and could cause stack issues down the line. Just remove those two lines:
.load_sector: mov ax, word [cluster] add ax, 31 call lba_to_hts mov ax, LOAD_SEG mov es, ax mov bx, word [pointer] ; Delete these two lines—they're unnecessary ; pop ax ; push ax int 13h
5. Kernel Missing org Directive (Bonus Fix)
This isn't causing the "not found" error, but it will break your kernel's string printing once you get it loaded. Your kernel is loaded to 0x1000:0x0000 (physical address 0x10000), but you haven't set an origin directive, so the assembler will calculate string addresses incorrectly.
Add this line to your kernel:
[bits 16] ;16-bit binary format [org 0x0000] ; Matches the load offset 0x0000 in segment 0x1000 ;VECTORS os_vectors: jmp os_main
Quick Test Tip
After fixing the build script, mount the floppy image manually and check that KERNEL.BIN is actually present. You can also run QEMU with -d disk to get detailed disk debugging output—this will help you confirm if the bootloader is reading the root directory and FAT correctly.
内容的提问来源于stack exchange,提问作者Klaus Maria

