Bootloader /内核仅在虚拟机中启动

时间:2016-07-21 10:47:50

标签: assembly kernel bootloader osdev floppy

所以,过去几周我已经研究过在程序集中编写引导加载程序和内核(x86 / x86_64),虽然我尝试了更复杂的解决方案,但在自己编写之前我决定尝试一些用户命名的代码< em> Sinned 已发布here。我的引导程序代码是:

[BITS 16]
[ORG 0x7C00]

MOV DL, 0x0 ;drive 0 = floppy 1
MOV DH, 0x0 ;head (0=base)
MOV CH, 0x0 ;track/cylinder
MOV CL, 0x02 ;sector (1=bootloader, apparently sectors starts counting at 1 instead of 0)
MOV BX, 0x1000 ;place in RAM for kernel - I suppose randomly chosen on examples
MOV ES, BX ;place BX in pointer ES
MOV BX, 0x0 ;back to zero - also has something to do with RAM position

ReadFloppy:
MOV AH, 0x02
MOV AL, 0x01
INT 0x13
JC ReadFloppy ;if it went wrong, try again

;pointers to RAM position (0x1000)
MOV AX, 0x1000
MOV DS, AX
MOV ES, AX
MOV FS, AX
MOV GS, AX
MOV SS, AX

JMP 0x1000:0x0

;assuming we get never back here again, so no further coding needed (kernel handles everything now)

TIMES 510 - ($ - $$) db 0 ;fill resting bytes with zero
DW 0xAA55 ;end of bootloader (2 bytes)

我的内核文件是:

;set print-registers
MOV AH, 0x0E ;function nr
MOV BH, 0x00 ;page
MOV BL, 0x07 ;color

MOV SI, msg ;move msg to SI-pointer
CALL PrintString ;call function to print SI (msg)

JMP $ ;hang

PrintString:
.next_char:
MOV AL, [SI] ;current character
OR AL, AL
JZ .print_done ;if current char is zero, go to end
INT 0x10 ;print character
INC SI ;increase pointer to msg (next character)
JMP .next_char
.exit_char
RET

msg db 'Hello world from the kernel!', 13, 10, 0

TIMES 512 - ($ - $$) db 0 ;fill the rest

我可以把所有东西组装好,并且当连接到软盘控制器时,单个二进制文件在VirtualBox内部启动。虽然这让我有信心在我自己的加载器和内核上工作,但我希望能够在裸机上启动它。

我尝试使用USB驱动器启动图像无济于事,我确信我正确地对USB记忆棒进行成像。我开始觉得我错过了一些非常明显的东西。我怀疑这与使用13h读取“软盘”有关,我实际上是在尝试从USB读取原始二进制文件。是这样的吗?如果是这样,我如何重写引导加载程序以从非特定磁盘而不是软盘读取?

1 个答案:

答案 0 :(得分:1)

我已经写了一些适用于此代码的General Bootloader tips。特别是我有这个提示:

  
      
  1. 当BIOS跳转到您的代码时,您不能依赖具有有效或预期值的CS,DS,ES,SS,SP寄存器。应在引导加载程序启动时正确设置它们。您只能保证从物理地址0x00007c00加载并运行引导加载程序,并且引导驱动器号加载到DL寄存器中。
  2.   

第一张软盘的启动驱动器通常为0,因此您的虚拟机可能正常工作,因为您启动了作为虚拟驱动器安装的软盘映像A :.导致您出现问题的代码位于ReadFloppy代码中。特别是这一行:

MOV DL, 0x0 ;drive 0 = floppy 1

您应该使用BIOS传递的值硬编码零。在你启动的任何系统上,除了软盘驱动器A:它可能会失败。要解决此问题,只需删除上面的行。

我建议您查看我在提供的链接中提供的其他引导加载程序提示。