hit_os_lab2 操作系统启动
创始人
2024-02-28 11:32:48

前置知识

1.1 基础概念

入理论课程的学习。 如果网易云上的课程无法查看,也可以看 Bilibili 上的 操作系统哈尔滨工业大学李治军老师。

  • L2 开始揭开钢琴的盖子
  • L3 操作系统启动

同济大学赵炯博士的《Linux 内核 0.11 完全注释(修正版 V3.0)》(以后简称《注释》)的第 6 章是非常有帮助的参考,实验中可能遇到的各种问题,几乎都能找到答案。谢煜波撰写的《操作系统引导探究》也是一份很好的参考。

1.2 概念的代码实现

Linux 0.11 文件夹中的 boot/bootsect.s、boot/setup.s 和 tools/build.c 是本实验会涉及到的源文件。

它们的功能详见《注释》的 6.2、6.3 节和 16 章。

2. 实验内容

阅读《Linux 内核完全注释》的第 6 章,对计算机和 Linux 0.11 的引导过程进行初步的了解;

  1. 按照下面的要求改写 0.11 的引导程序 bootsect.s
  2. 有兴趣同学可以做做进入保护模式前的设置程序 setup.s。
  • 改写 bootsect.s 主要完成如下功能:
  1. bootsect.s 能在屏幕上打印一段提示信息“XXX is booting…”,其中 XXX 是你给自己的操作系统起的名字,例如 LZJos、Sunix 等(可以上论坛上秀秀谁的 OS 名字最帅,也可以显示一个特色 logo,以表示自己操作系统的与众不同。)

改写 setup.s 主要完成如下功能:

  1. bootsect.s 能完成 setup.s 的载入,并跳转到 setup.s 开始地址执行。而 setup.s 向屏幕输出一行"Now we are in SETUP"。
  2. setup.s 能获取至少一个基本的硬件参数(如内存参数、显卡参数、硬盘参数等),将其存放在内存的特定地址,并输出到屏幕上。
  3. setup.s 不再加载 Linux 内核,保持上述信息显示在屏幕上即可。

2.1 实验提示

操作系统的 boot 代码有很多,并且大部分是相似的。本实验仿照 Linux-0.11/boot 目录下的 bootsect.s 和 setup.s,以剪裁它们为主线。当然,如果能完全从头编写,并实现实验所要求的功能,是再好不过了。

需要注意的是,oslab 中的汇编代码使用 as86 编译。

下面将给出一些更具体的 “提示”。这些提示并不是实验的一步一步的指导,而是罗列了一些实验中可能遇到的困难,并给予相关提示。它们肯定不会涵盖所有问题,也不保证其中的每个字都对完成实验有帮助。所以,它们更适合在你遇到问题时查阅,而不是当作指南一样地亦步亦趋。本课程所有实验的提示都是秉承这个思想编写的。

2.2 实验环境

(1)相关代码文件
Linux 0.11 文件夹中的 boot/bootsect.s、boot/setup.s 和 tools/build.c 是本实验会涉及到的源文件。它们的功能详见《注释》的 6.2、6.3 节和 16 章。

(2)引导程序的运行环境

引导程序bootsect.s 由BIOS 加载并运行, 引导程序在执行的过程中, 操作系统还不存在, 此时整台计算机的所有资源由引导程序掌控, 能使用的功能只有BIOS 中断调用,

在此过程中, 主要使用了 0X10, 0X13 这两个中断。

3. bootsect.s

3.1 修改 bootsect.s

  1. 改动, 这里需要修改的是字符串长度,即用需要输出的字符串长度替换 mov cx,#24 中的 24。要注意:除了我们设置的字符串 msg1 之外,还有三个换行 + 回车,一共是 6 个字符。比如这里 Hello OS world, my name is Chu Yun 的长度是 34,加上 6 后是 40,所以代码应该修改为 mov cx,#40。

  2. 修改启动时的字符串,将 .org 508 修改为 .org 510,是因为这里不需要 root_dev: .word ROOT_DEV,为了保证 boot_flag 一定在最后两个字节,所以要修改 .org。

完整的代码如下:

entry _start
_start:! Print some inane message
! 读入光标所在位置mov	ah,#0x03		! read cursor posxor	bh,bhint	0x10!  显示启动过程中的字符串; “Hello OS world, my name is Chu Yun”	!mov	cx,#24mov cx,#40mov	bx,#0x0007		! page 0, attribute 7 (normal)mov	bp,#msg1!mov	ax,#0x1301		! write string, move cursor!int	0x10! es:bp 是显示字符串的地址;
! 相比与原始的代码linux-0.11(原始代码中在输出之前处理了es), 这里增加对es 的处理,mov ax,#0x07c0mov es,axmov ax,#0x1301int 0x10! 设置一个无限循环
inf_loop:jmp inf_loop! 在msg1处放置字符串
msg1:
! 一对回车+ 换行.byte  13,10.ascii "Hello OS world, my name is Chu Yun"
! 两对回车 + 换行.byte  13,10,13,10.org 510
! 设置引导扇区标记, 0xAA55,  必须有该引导扇区的标记,才能引导;
boot_flag:.word 0xAA55

3.2 编译和运行 bootsect.s

执行下面两个命令编译和链接 bootsect.s:

$ as86 -0 -a -o bootsect.o bootsect.s
$ ld86 -0 -s -o bootsect bootsect.o

其中 -0(注意:这是数字 0,不是字母 O)表示生成 8086 的 16 位目标程序,-a 表示生成与 GNU as 和 ld 部分兼容的代码,-s 告诉链接器 ld86 去除最后生成的可执行文件中的符号信息。

如果这两个命令没有任何输出,说明编译与链接都通过了。

Ubuntu 下用 ls -l 可列出下面的信息:

~/os/oslab/linux-0.11/boot$ ls -l
总用量 72
-rwxrwxr-x 1 shiyanlou shiyanlou   544 11月 29 15:54 bootsect
-rw-rw-r-- 1 shiyanlou shiyanlou   924 11月 29 15:53 bootsect.o
-rw-r--r-- 1 shiyanlou shiyanlou  5059 8月  28  2008 bootsect_ori.s
-rw-r--r-- 1 shiyanlou shiyanlou  1799 11月 29 15:55 bootsect.s

其中 bootsect.o 是中间文件。bootsect 是编译、链接后的目标文件。

注意到; bootsect 的文件大小是 544 字节,而引导程序必须要正好占用一个磁盘扇区,即 512 个字节。

造成多了 32 个字节的原因是 ld86 产生的是 Minix 可执行文件格式,这样的可执行文件除了文本段、数据段等部分以外,还包括一个 Minix 可执行文件头部,它的结构如下:

struct exec {unsigned char a_magic[2];  //执行文件魔数unsigned char a_flags;unsigned char a_cpu;       //CPU标识号unsigned char a_hdrlen;    //头部长度,32字节或48字节unsigned char a_unused;unsigned short a_version;long a_text; long a_data; long a_bss; //代码段长度、数据段长度、堆长度long a_entry;    //执行入口地址long a_total;    //分配的内存总量long a_syms;     //符号表大小
};

算一算:6 char(6 字节)+ 1 short(2 字节) + 6 long(24 字节)= 32,正好是 32 个字节,去掉这 32 个字节后就可以放入引导扇区了(这是 tools/build.c 的用途之一)。

对于上面的 Minix 可执行文件,其 a_magic[0]=0x01,a_magic[1]=0x03,a_flags=0x10(可执行文件),a_cpu=0x04(表示 Intel i8086/8088,如果是 0x17 则表示 Sun 公司的 SPARC),所以 bootsect 文件的头几个字节应该是 01 03 10 04。

为了验证一下,Ubuntu 下用命令hexdump -C bootsect可以看到:

hexdump -C bootsect
00000000  01 03 10 04 20 00 00 00  00 02 00 00 00 00 00 00  |.... ...........|
00000010  00 00 00 00 00 00 00 00  00 82 00 00 00 00 00 00  |................|
00000020  b8 c0 07 8e d8 b8 00 90  8e c0 b9 00 01 29 f6 29  |.............).)|

3.3 修改 bootsect 文件大小

接下来干什么呢?

是的,要去掉这 32 个字节的文件头部(tools/build.c 的功能之一就是这个)!随手编个小的文件读写程序都可以去掉它。不过,

在 Ubuntu 下可以用命令:

3.4 ubuntu 中读入文件指定大小字节的数据

dd bs=1 if=bootsect of=Image skip=32
记录了512+0 的读入
记录了512+0 的写出
512字节已复制,0.00892562 s,57.4 kB/s
shiyanlou@respectinglife-Inspiron-24-5459:~/os/oslab/linux-0.11/boot$ ls
bootsect  bootsect.o  bootsect_ori.s  bootsect.s  head.o  head.s  Image  setup  setup.o  setup.s

3.5 运行引导文件 bootsect

去掉这 32 个字节后,将生成的文件拷贝到 linux-0.11 目录下,
并一定要命名为Image(注意大小写)。

~/os/oslab/linux-0.11/boot$ cp ./Image  ../Image

然后就“run”吧, 注意到这里是在当前路径下, 回退的方式运行的;

~/os/oslab/linux-0.11/boot$ ../../run

在这里插入图片描述

4. build.c 实验

5. setup.S 实验

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...