如何从第一阶段加载第二阶段引导加载程序? [英] How to load second stage boot loader from first stage?

查看:122
本文介绍了如何从第一阶段加载第二阶段引导加载程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了简单的第一阶段引导程序,该命令使用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 (wiki with many hobbyist OS developers, German only...)

希望有所帮助的^^

这篇关于如何从第一阶段加载第二阶段引导加载程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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