如何从第一阶段加载第二阶段引导加载程序? [英] How to load second stage boot loader from first stage?
本文介绍了如何从第一阶段加载第二阶段引导加载程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我编写了简单的第一阶段引导程序,该命令使用BIOS中断显示"Hello world".现在是编写第二阶段的下一个显而易见的步骤,但是应该在哪里存在代码以及如何从第一阶段加载它?
I have written simple first stage bootloader which displays "Hello world" using interrupt to bios. Now as a next obvious step to write a second stage, but where code for that should exist and how to load it from first stage ?
这是第一阶段的程序
[BITS 16] ;Tells the assembler that its a 16 bit code
[ORG 0x7C00] ;Origin, tell the assembler that where the code will
;be in memory after it is been loaded
MOV SI, HelloString ;Store string pointer to SI
CALL PrintString ;Call print string procedure
JMP $ ;Infinite loop, hang it here.
PrintCharacter: ;Procedure to print character on screen
;Assume that ASCII value is in register AL
MOV AH, 0x0E ;Tell BIOS that we need to print one charater on screen.
MOV BH, 0x00 ;Page no.
MOV BL, 0x07 ;Text attribute 0x07 is lightgrey font on black background
INT 0x10 ;Call video interrupt
RET ;Return to calling procedure
PrintString: ;Procedure to print string on screen
;Assume that string starting pointer is in register SI
next_character: ;Lable to fetch next character from string
MOV AL, [SI] ;Get a byte from string and store in AL register
INC SI ;Increment SI pointer
OR AL, AL ;Check if value in AL is zero (end of string)
JZ exit_function ;If end then return
CALL PrintCharacter ;Else print the character which is in AL register
JMP next_character ;Fetch next character from string
exit_function: ;End label
RET ;Return from procedure
;Data
HelloString db 'Hello World', 0 ;HelloWorld string ending with 0
TIMES 510 - ($ - $$) db 0 ;Fill the rest of sector with 0
DW 0xAA55 ;Add boot signature at the end of bootloader
推荐答案
在x86上,您将执行以下操作(简化):
On x86 you would do the following (simplified):
- 让引导加载程序将磁盘/软盘的第n个扇区(无论您从哪里引导)加载到内存中并执行它(即加载segment/offset并执行
retf
).更好的选择是在文件系统中搜索某个文件名(例如KERNEL.BIN),但是您需要知道文件系统的类型(例如,如果从软盘映像进行测试,则是FAT12). - 然后,内核将以实模式启动.它设置代码描述符,GDT等,激活32位寻址(您应该已经听说过"A20")并最终进入保护模式.然后,您需要跳到32位代码段(内核文件必须以32位代码位于绝对位置的方式链接在一起,例如,紧靠16位实模式填充之后的偏移量512)
- 然后,32位内核程序集仅定义了
EXTERN _mykernel
(例如)并调用该符号. - 然后,您就可以开始将内核编写为C函数
mykernel
.
- Have the bootloader load the n-th sector of the disk/floppy (wherever you're booting from) into memory and execute it (i.e. load segment/offset and do
retf
). A better alternative is to search the filesystem for a certain filename (e.g. KERNEL.BIN) -- but you'd need to know the file system type (e.g. FAT12 if you're testing from a floppy image). - The kernel would then start in real mode. It sets up code descriptors, GDT, and so on, activates 32-bit addressing (you should have heard of "A20") and finally enters protected mode. Then you need a far jump to a 32-bit code segment (kernel file must be linked together in a way that the 32-bit code is at an absolute position, e.g. at offset 512, right after the 16-bit real mode stuff).
- The 32-bit kernel assembly, then, just defines
EXTERN _mykernel
(for example) and calls that symbol. - Then you can begin writing your kernel as C function
mykernel
.
好吧,这是我几年前所做的简短概述(来自Internet的大量复制和粘贴;).如果这没有帮助,那么这里有一些关于OS开发的优秀Web资源:
Okay that was a short overview of what I did a few years ago (with lots of copy&paste from the Internet ;). If that isn't helpful, here are some good web resources on OS development:
- http://www.brokenthorn.com/Resources/OSDevIndex.html
- http://wiki.osdev.org/Main_Page
- http://lowlevel.brainsware.org/wiki/index.php/Hauptseite (包含许多业余OS开发人员的Wiki,仅限德语...)
- http://www.brokenthorn.com/Resources/OSDevIndex.html
- http://wiki.osdev.org/Main_Page
- http://lowlevel.brainsware.org/wiki/index.php/Hauptseite (wiki with many hobbyist OS developers, German only...)
希望有所帮助的^^
这篇关于如何从第一阶段加载第二阶段引导加载程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文