您的位置:首页 > 其它

【NROS-01】Bootloader 引导操作系统

2015-08-30 11:49 302 查看

Bootloader 定义

Bootloader 是计算机加电之后加载的第一个程序(除去 Bios),这个程序被放在二级存储(比如硬盘)的第一个扇区,用于加载复杂的操作系统到内存中。之所以不直接加载操作系统,而加载 bootloader 来加载操作系统,是因为操作系统体积庞大,无法存储在第一扇区(只有 512 字节)。

过程简述

计算机加电,进行自检等一系列操作,这些操作由硬件供应商保证,操作系统开发人员一般不需太过关心;

随后 Bios 会读取硬盘第一个扇区(sector)的数据(此处存疑),加载到 0x7c00 的物理地址;

ip
cs
寄存器被设置(
cs = 0x00, ip = 0x7c00
),并开始执行 bootloader;

Bootloader 进行一些必要的初始化(比如 enable a20 gate,保护模式等等);

在特定位置寻找操作系统(很可能是第二扇区),并根据一定的约定(比如 elf 可执行文件格式),加载操作系统;

跳转到操作系统入口处执行,进入操作系统。

实现参考

NROS bootloader Github

放置 Bootloader 到存储设备

假定 bootloader 已有,在 Linux 下硬盘被映射为文件,可以使用
dd
来将 bootloader 写入硬盘扇区。暂时先写入成为一个镜像文件,通过 qemu 虚拟机启动:

dd if=bootloader of=nros.img conv=notrunc
qemu-system-i386 -hda nros.img

不过忧心的是你目前还没有 bootloader 呢,所以我们自己写一个吧。

实现细节

要理解 bootloader 还是要理解链接与加载地址。对于程序生成的二进制代码,物理地址、线性地址,和逻辑地址这些概念都是透明的。程序只知道 (virtual) memory address(VMA) 和 load memory address(LMA),即程序看到的地址,和看到的地址真正被放置的地址。VMA 和 LMA 是 elf 格式引入的概念,对于硬件而言太高级了,难以实现。硬件只会简单的将第一扇区的 512 字节放在内存
0x7c00
的位置(相当于LMA),因此你必须安排链接器,让他把代码的地址链接到 0x7c00 的位置(参考 GNU 文档),如下:

/*
* setup.ld
*
* Linker script for the i386 setup code
*/
OUTPUT_ARCH("i386");
OUTPUT_FORMAT("binary", "binary", "binary");

SECTIONS
{
. = 0x7C00;
.text : {
*(.text);
}

. = 0x7DFE;
.signature : {
SHORT(0xAA55);
}

/DISCARD/ : {
*(.eh_frame);
*(.eh_frame_hdr);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: