《ORANGE-s-一个操作系统实现》尾声(9)

让mkfs()只执行一次

目前我们的操作系统每次启动都是“全新的”,因为每一次init_fs()都会调用mkfs()刷新硬盘,每次启动时可以保证文件系统是一样,但它也存在明细的坏处,那就是上次建立的文件到下一次启动时就不见了。下面就来改变现状:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
PRIVATE void init_fs()
{
int i;

/* f_desc_table[] */
for (i = 0; i < NR_FILE_DESC; i++)
memset(&f_desc_table[i], 0, sizeof(struct file_desc));

/* inode_table[] */
for (i = 0; i < NR_INODE; i++)
memset(&inode_table[i], 0, sizeof(struct inode));

/* super_block[] */
struct super_block * sb = super_block;
for (; sb < &super_block[NR_SUPER_BLOCK]; sb++)
sb->sb_dev = NO_DEV;

/* open the device: hard disk */
MESSAGE driver_msg;
driver_msg.type = DEV_OPEN;
driver_msg.DEVICE = MINOR(ROOT_DEV);
assert(dd_map[MAJOR(ROOT_DEV)].driver_nr != INVALID_DRIVER);
send_recv(BOTH, dd_map[MAJOR(ROOT_DEV)].driver_nr, &driver_msg);

/* read the super block of ROOT DEVICE */
RD_SECT(ROOT_DEV, 1);

sb = (struct super_block *)fsbuf;
if (sb->magic != MAGIC_V1) {
printl("{FS} mkfs\n");
mkfs(); /* make FS */
}

只需要每次先读取超级块,如果发现魔数,则认为分区已经操作系统,否则调用mkfs()。
然后在untar()上留下记号,让它不再一股脑的解压了。
运行结果如下:
mark

从硬盘引导

前面都是从软盘引导的,现在我们从硬盘引导,先看看软盘引导的过程:

  1. BIOS将引导扇区读入内存0000:7c00处
  2. 跳转到0000:7c00处开始执行引导代码
  3. 引导代码从软盘中找到loader.bin,并将其读入内存
  4. 跳转到loader.bin开始执行
  5. loader.bin从软盘中找到kernel.bin,并将其读入内存
  6. 跳转到kernel.bin开始执行,到此可认为启动过程结束
  7. 系统运行
    硬盘启动和软盘的启动的区别在于第一步,BIOS到底是读谁,由CMOS设置决定,通常可以找到一个叫做Boot Sequence的选项,从中选择首选启动设备。在第3步和第5步中,对于软盘启动,代码将在软盘中寻找loader.bin和kernel.bin,对应硬盘启动,我们需要让引导扇区代码从硬盘中寻找loader.bin和kernel.bin。
    mark

    grub

    将引导扇区安装到我们的操作系统分区的引导扇区,而不是整块硬盘的引导扇区,这样操作系统就可以和硬盘上其他操作系统和平共处了。只需要安装一个grub就可以了

    将OS安装到真实的计算机

您的支持将鼓励我继续创作!