Bootloader可在仿真器中运行,但不能在实际硬件上运行 [英] Bootloader works in emulators but not on real hardware

查看:95
本文介绍了Bootloader可在仿真器中运行,但不能在实际硬件上运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用汇编语言编写引导加载程序,它在qemu,bochs和virtualbox上似乎工作正常.但是,它并没有在真正的硬件上加载内核.

I am writing a bootloader in assembly and it seems to work fine on qemu, bochs and virtualbox. However, it is not loading the kernel on real hardware (it seems).

引导加载程序通过向视频内存写入字符(用于调试)开始,然后从驱动器读取扇区2,然后跳转到内核.然后内核将一些字符写入视频内存.

The bootloader starts off by writing a character to the video memory (for debugging), it then reads sector 2 off the drive and far jumps to the kernel. The kernel is then writing some characters to video memory.

在真实的机器上,我从屏幕上的引导加载程序中看到了该字符,并且该字符挂起了(插入记号闪烁).

On a real machine, I see the character from the bootloader on the screen, and there it hangs (blinking caret).

我试图将DS,ES,SI设置为零,并且我还在设置堆栈段.

I have tried to set DS, ES, SI to zero, and I am also setting up a stack segment.

我正在使用bios int 13函数2从驱动器上读取扇区2.我有点怀疑它与驱动器编号有关.我都尝试使用启动时传递给引导加载程序的驱动器号(在dl中),并将其手动设置为0x0、0x80和0x81.

I am reading sector 2 off of the drive using bios int 13 function 2. I kind of suspect that it has something to do with the drive number. I have both tried to use the drive number passed to the bootloader on startup (in dl), and setting it manually to 0x0, 0x80 and 0x81.

我注意到的一件奇怪的事情是,我用来近跳的标签神奇地获得了正确的地址.使用objdump可以看到例如:jmp 0x2,而使用gdb和qemu时则显示:jmp 0x7c02. CS和所有其他段寄存器均为零.无论我在链接中使用-Ttext 0x0还是-Ttext 0x7c00,引导加载程序都可以在所有仿真器上正常工作.当我与-Ttext 0x7c00链接时,objdump会说jmp 0x7c02.

One strange thing I noticed is that the labels I use to near jump, magically gets the correct address. Using objdump I see for example: jmp 0x2, while using gdb and qemu, it says: jmp 0x7c02. CS and all the other segment registers are zero. Whether I use -Ttext 0x0 or -Ttext 0x7c00 in the linking, the bootloader works fine on all the emulators. objdump says jmp 0x7c02 when I link with -Ttext 0x7c00.

编辑,引导程序如下:

.code16
.text
movw $0xb800, %ax
movw %ax, %ds
movw $0x0741, (0x0)

xorw %ax, %ax
movw %ax, %ds
movw %ax, %si
movw %ax, %es

movw  $0x8000, %ax
movw  %ax, %ss
movw  $0, %sp

movb $2, %ah
movb $1, %al
movw $0x02, %cx
movb $0x00, %dh

movw $0x5000, %bx
movw %bx, %es
movw $0x0, %bx
int $0x13

ljmpw $0x5000, $0x0000

编辑,第二阶段:

.code16
.text
    movw $0xb800, %ax
    movw %ax, %ds
    movw $0x0742, (0x2)

forever:
    jmp forever

推荐答案

如果您的硬件对USB驱动器使用软盘仿真,则可能没有适当的

If your hardware is using floppy disk emulation for the USB drive it may be possible that without a proper BIOS Parameter Block (BPB) in your MBR that it is failing to boot properly. Many BIOSes will attempt to detect a BPB at the start of the bootloader and may even update the values with proper drive geometry after the bootloader is loaded into memory. It is possible your bootloader was not being detected as a proper bootable drive or it was but the BIOS overwrote some of your code with drive geometry information before executing it.

以下内容添加了一个BPB,它看起来像是2.88MB的软盘.

The following adds a BPB that happens to look like a 2.88MB floppy.

.global _start
.code16
.text

_start:
    jmp     main
    .space 3 - (.-_start)

    /* Configuration for a 2.88MB floppy using FAT 12 */
    OEMname:            .ascii      "MYBOOT  "
    bytesPerSector:     .word       512
    sectPerCluster:     .byte       1
    reservedSectors:    .word       1
    numFAT:             .byte       2
    numRootDirEntries:  .word       240
    numSectors:         .word       5760
    mediaType:          .byte       0xf0
    numFATsectors:      .word       9
    sectorsPerTrack:    .word       36
    numHeads:           .word       2
    numHiddenSectors:   .long       0
    numSectorsHuge:     .long       0
    driveNum:           .byte       0
    reserved:           .byte       0x00
    signature:          .byte       0x29
    volumeID:           .long       0x54428E71
    volumeLabel:        .ascii      "NO NAME    "
    fileSysType:        .ascii      "FAT12   "

main:
    movw $0xb800, %ax
    movw %ax, %ds
    movw $0x0741, (0x0)

    xorw %ax, %ax
    movw %ax, %ds
    movw %ax, %si
    movw %ax, %es

    movw  $0x8000, %ax
    movw  %ax, %ss
    movw  $0, %sp

    movb $2, %ah
    movb $1, %al
    movw $0x02, %cx
    movb $0x00, %dh

    movw $0x5000, %bx
    movw %bx, %es
    movw $0x0, %bx
    int $0x13

    ljmpw $0x5000, $0x0000

.space 510-(.-_start)
.word 0xaa55

这篇关于Bootloader可在仿真器中运行,但不能在实际硬件上运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆