linux – 自定义操作系统的引导加载程序没有跳转到内核的麻烦

前端之家收集整理的这篇文章主要介绍了linux – 自定义操作系统的引导加载程序没有跳转到内核的麻烦前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我最近有一个想法开始开发自己的操作系统.
在阅读了我认为可以帮助我完成这项任务的不同网站上的许多文章后,我想我现在可以开始了. (顺便说一句,我使用的是Ubuntu 14.10 x64)

由于软盘是开发操作系统的最简单的存储介质,我购买了3.5英寸软盘驱动器.

我使用NASM作为汇编编译器,qemu作为模拟器.
使用dd命令,我将一个现有的和空的(就文件而言)软盘克隆到一个名为floppy.img.bak的文件中.

之后,我在x86程序集中编写了一个简单的bootloader:

bootloader.asm

  1. org 7C00h
  2. jmp 0x0000:start ;go
  3.  
  4. msg db 'Loading Kernel...',0
  5.  
  6. start:
  7. ;update the segment registers
  8. mov ax,cs
  9. mov ds,ax
  10. mov es,ax
  11.  
  12. mov si,msg
  13.  
  14. print: ;prints a string
  15. lodsb ;load next char
  16.  
  17. cmp al,0 ;if null terminator...
  18. je reset ;...jump to reset:
  19.  
  20. mov ah,0Eh ;print AL
  21. mov bx,7
  22. int 10h
  23.  
  24. jmp print ;if not null terminator,continue printing
  25.  
  26. reset: ;resets the floppy drive
  27. mov ax,0 ;
  28. mov dl,0 ;drive=0 (=A)
  29. int 13h ;
  30. jc reset ;if error resetting,reset again
  31.  
  32. read:
  33. mov ax,1000h ;ES:BX = 1000:000
  34. mov es,ax ;es is 1000h now
  35. mov bx,0 ;bx is 0 now
  36.  
  37. mov ah,2 ;load disk data into ES:BX
  38. mov al,1 ;load 1 sector
  39. mov ch,0 ;cylinder=0
  40. mov cl,2 ;sector=2
  41. mov dh,0 ;head=0
  42. mov dl,0 ;drive=0
  43. int 13h ;read!
  44.  
  45. jc read ;if error then try again
  46.  
  47.  
  48. jmp 1000h:0000;jump to the program
  49.  
  50. times 510-($-$$) db 0
  51. dw 0AA55h

到现在为止还挺好.
我的简单临时存根内核如下:

kernel.asm

  1. kstart:
  2. mov ah,9
  3. mov al,'k'
  4. mov bx,7
  5. mov cx,5
  6. int 10h
  7.  
  8. hang:
  9. jmp hang
  10.  
  11. times 510-($-$$)+2 db 0

我还有一个shell脚本来编译,编写和启动这个设置:

compile-and-run.sh

  1. cd ~/Dev/OS # cd to here
  2.  
  3. rm asm-bin/bootloader.bin # remove old compiled bootloader
  4. rm asm-bin/kernel.bin # remove old compiled kernel
  5.  
  6. nasm asm-src/bootloader.asm -f bin -o asm-bin/bootloader.bin # compile bootloader
  7. nasm asm-src/kernel.asm -f bin -o asm-bin/kernel.bin # compile kernel
  8.  
  9. rm images/floppy.img # remove old floppy image
  10. cp images/floppy.img.bak images/floppy.img # copy original floppy image to fresh one
  11.  
  12. dd if=asm-bin/bootloader.bin of=images/floppy.img bs=512 count=1 seek=0 # write bootloader to first sector
  13. dd if=asm-bin/kernel.bin of=images/floppy.img bs=512 count=1 seek=1 # write kernel to second sector
  14.  
  15. qemu-system-i386 images/floppy.img # start qemu and boot floppy.img

现在,qemu的预期输出将是(至少我理解的):

  1. Loading Kernel...
  2. kkkkk

但相反,它是:

  1. Loading Kernel...

所以,显然,跳跃有些不对劲,我只是不知道是什么.
也许你可以帮助我?我会很感激.

解决方法

bootdrive存储在dl寄存器中,但是将其覆盖为0.
默认情况下,bootdrive为80h,而不是引导加载程序代码使用的0.
如果你注释掉2行
  1. ; mov dl,0 ;drive=0 (=A)

它将按预期启动.

猜你在找的Linux相关文章