-纳兰容若纳兰性德
实验目的
<
编辑
>
?
?
?
?
熟悉
hit-oslab
实验环境;
建立对操作系统引导过程的深入认识;
掌握操作系统的基本开发过程;
能对操作系统代码进行简单的控制,揭开操作系统的神秘面纱。
实验内容
<
编辑
>
此次实验的基本内容是:
1.
2.
3.
阅读《
Linux
内核完全注释》的第
6
章,对计算机和
Linux 0.11
的引导过程进行初步
的了解;
按照下面的要求改写
0.11
的引导程序
bootsect.s
有兴趣同学可以做做进入保护模式前的设置程
序
setup.s
。
改写
bootsect.s
主要完成如下功能:
1.
bootsect.s
能在屏幕上打印一段提示信息
“XXX is booting...”
,其中
XXX
是你给自己
的操作系统起的名字,例如
LZJos
、
Suni x
等(可以上论坛上秀秀谁的
OS
名字最帅,
也可以显示一个特色
logo
,以表示自己操作系统的与众不同。)
改写
setup.s
主要完成如下功能:
1.
2.
3.
bootsect.s
能 完成
setup.s
的载入,并跳转到
setup.s
< p>开始地址执行。而setup.s
向屏
幕输出一行<
/p>
。
setup.s
p>
能获取至少一个基本的硬件参数(如内存参数、显卡参数、硬盘参数等),
将
其存放在内存的特定地址,并输出到屏幕上。
set
up.s
不再加载
Linux
内核,保持上述信息显示在屏幕上即 可。
实验报告
<
编辑
>
在实验报告中回答如下问题:
1.
有时,
继承传统意味着别手蹩脚。
x86
计算机为了向下兼容,
导致启动过程比较复杂。
< p>请找出
x86
计算机启动过程中,
被硬件强制, p>
软件必须遵守的两个
“
多此一举
”
的步 骤
(多
找几个也无妨),说说它们为什么多此一举,并设计更简洁的替代
方案。
评分标准
<
编辑
>
?
?
?
?
?
?
?
bootsect
显示正确,
1020%
bootsect
正确读入
setup
,
10%
setup
显示正确,
10%
setup
获取硬件参数正确,
5%
setup
正确显示硬件参数,
5%
tools/build.c
修改正确,
1020%
实验报告,
5060%
实验
提示
<
编辑
>
操作系统的
boot
代码有很多,并且大部分是相似的。本实验仿照 p>
Linux-0.11/boot
目录下的
bootsect
.s
和
setup.s
,以剪裁它们为主线。当然,如果能完全从 头编写,
并实现实验所要求的功
能,是再好不过了。
< /p>
同济大学赵炯博士的《
Linux
内核
0. 11
完全注释(修正版
V3.0
)》(以后简称《注释》)的第< /p>
6
章是非常有帮助的参考,实验中可能遇到的各种问题,几乎都能找到答案 。可以在
“
资料和文
件
下载
”
中下载到该书的电子版。同目录中,校友谢煜波撰写的《操作系统引导探究》也是一份
很好的参考。
需要注意的是,
osl ab
中的汇编代码使用
as86
编译,语法和汇编课上所授稍有不 同。
下面将给出一些更具体的
“
提示< /p>
”
。这些提示并不是实验的一步一步的指导,而是罗列了一些实
验中可能遇到的困难,并给予相关提示。它们肯定不会涵盖所有问题,也不保证其中的每个字
都对完成实验有帮助。所以,它们更适合在你遇到问题时查阅,而不是当作指南一样地亦步亦
趋。本书所有实验的提示都是秉承这个思想编写的。
Linux 0.11
相关代码详解
< br>boot/bootsect.s
、
boot/setup.s
< p>和tools/build.c
是本实验会涉及到的源文件。
它们的功能详见
《注
释》的
6.2
、 p>
6.3
节和
16
章。
如果使用
Windows
下的环境,
那么要注意
Windows
环境里提供的
build.c
是一个经过修 改过的
版本。
Linus Torvalds
的原版是将
0.11
内核的最终目标代码输出到标准输出,
由
make
程序将数
据重定向到
Image
文件,这在
Linux
、
Unix
和
Minix
等系统下都是非常有效的。但
Windows
本身的缺陷(也许是特色)决定了在
Windows
下不能这么做,所以
flyfish
修改了
build.c
,将
输出直接写入到
Image
(
flyfish
是写入到
文件,我们为了两个环境的一致,也为了最
大化地与原始版本保持统一,将其改为
Image
)文件中。同时为了适应 p>
Windows
的一些特殊情
况,他还做了其它一些小修改。
引导程序的运行环境
引导程
序由
BIOS
加载并运行。它活动时,操作系统还不存在,整台计算机的所有资源 都由它掌
控,而能利用的功能只有
BIOS
中断调用 p>
。
完成
bootsect.s
的屏幕输出功能
首先来看完成屏幕显示的关键代码如下:
!
首先读入光标位置
mov
a
h,#0x03
xor
b
h,bh
int
0
x10
!
显示字符串
“LZJos is running...”
mov
c
x,#25
mov
b
x,#0x0007
mov
b
p,#msg1
mov
a
x,#0x1301
int
0
x10
inf_loop:
jmp
i
nf_loop
!
要显示的字符串长度
! page 0, attribute 7 (normal)
! write string, move cursor
!
后面都不是正经代码了,得往回跳呀
! msg1
处放置字符串
msg1:
.byte
13,10
!
换行
+
回车
.ascii
.byte 13,10,13,10
!
设置引导扇区标记
0xAA55
.org 510
!
两对换行
+
回车
boot_flag:
.word 0xAA55
!
必须有它,才能引导
< /p>
接下来,
将完成屏幕显示的代码在开发环境中编译,
并使用
linux-0.11/tools/build.c
将编译后的
目标文件做成
Image
文件。
编译和运行
Ubuntu
上先 从终端进入
~/oslab/linux-0.11/boot/
目录。
Windows
上则先双击快捷方式
“”
,将打开 一个命令行窗口,当前目录是
oslab
,用
cd
命令进入
linux-0.11boot
。
无论那种系统
,都执行下面两个命令编译和链接
bootsect.s
:
as86 -0 -a -o bootsect.o bootsect.s
ld86 -0 -s -o bootsect bootsect.o
其中
-0
(
注意
:
这 是数字
0
,
不是字母
O
)
表示生成
8086
的
16
位目标程序, p>
-a
表示生成与
GNU
as
和
ld
部分兼容的代码,
-s
告诉链接器
ld86
去除最后生成的可执行文件中的符号信息。
如果这两个命令没有任何输出,
说明编译与链接都通过了。
Ubuntu p>
下用
ls -l
可列出下面的信息:
-rw--x--x 1 root root 544 Jul
25 15:07 bootsect
-rw------ 1
root root 257 Jul 25 15:07 bootsect.o
-rw------ 1 root root 686 Jul
25 14:28 bootsect.s
Windows
下用
dir
可列出下面的信息:
2008-07-28 20:14 544
bootsect
2008-07-28 20:14
924 bootsect.o
2008-07-26 20:13
5,059 bootsect.s
其中
bootsect.o
是中间文件。
bootsect
是编译、链接后的目标文件。
< p>
需要留意的文件是
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
< p>的用途之一)。
对于上面的
Minix
< p>可执行文件,其a_magic[0]=0x01
,
a_ma gic[1]=0x03
,
a_flags=0x10
(可
执行文件)
,
a_cpu=0x04
(表示 p>
Intel i8086/8088
,
如果是
0x17
则表示
Sun
公司的
SPARC
)
,
所以
bootsect
文件的头几个字 节应该是
01 03 10 04
。
为了验证一下,
Ubuntu
下用命令
“hexdump
-
C bootsect”
可以看到:
01 03 10 04 20 00 00 00 00 02 00 00
00 00 00 00
|.... ...........|
00 00 00 00 00 00 00 00 00 82 00 00
00 00 00 00
|................|
b8 c0 07 8e d8 8e c0 b4 03 30 ff cd
10 b9 17 00
|.........0......|
bb 07 00 bd 3f 00 b8 01 13 cd 10 b8
00 90 8e c0
|....?...........|
ba 00 00 b9 02 00 bb 00 02 b8 04 02
cd 13 73 0a
|..............s.|
ba 00 00 b8 00 00 cd 13 eb e1 ea 00
00 20 90 0d
|............. ..|
0a 53 75 6e 69 78 20 69 73 20 72 75
6e 6e 69 6e |.Sunix
is runnin|
67 21 0d 0a 0d 0a 00 00 00 00 00 00
00 00 00 00
|g!..............|
00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00
|................|
*
00 00 00 00 00 00 00 00
00 00 00 00 00 00 55 aa
|..............U.|
< br>Windows
下用
UltraEdit
把该文件打开,果 然如此。
图
1
用
UltraEdit
打开文件
bootsect
接下来干什么呢?是的,
要去掉这
32
个字节的文件头部
(
tools/build.c
的功能之一就是这个)
!
随手编个小的文件读写程序都可以去掉它。不过
,懒且聪明的人会在
Ubuntu
下用命令:
$$ dd bs=1 if=bootsect of=Image skip=32
生成的
Image
就是去掉文件头的
bo otsect
。
Windows
下可以 用
UltraEdit
直接删除(选中这
32
个字 节,然后按
Ctrl+X
)。
去掉这<
/p>
32
个字节后,将生成的文件拷贝到
linux-0.11
目录下,并一定要命名为
“Image”
(注意
大
小写)。然后就
“run”
吧!
图
2 bootsect
引导后的系统启动情况
bootsect.s
读入
setup.s
< p>首先编写一个
setup.s
,
该
s etup.s
可以就直接拷贝前面的
bootsect.s
(可能 还需要简单的调整)
,
然后将其中的显示的信息改为:
“ Now we are in SETUP”
。
接下来
需要编写
bootsect.s
中载入
setup.s
< p>的关键代码。原版bootsect.s
中下面的代码就是做这
个的。
load_setup:
mov
d
x,#0x0000
软盘
0
磁头
mov
c
x,#0x0002
!
设置扇区号和磁道
(sector 2, track
!
设置驱动器和磁头
(drive 0, head 0):
0):0
磁头、
0
< p>磁道、2
扇区
-初中音乐教学总结
-招工简章范本
-五年级上册英语期末试卷
-大学副班长工作总结
-休闲食品广告语
-奥林匹克的新格言
-三八放假吗
-罗辑课
-
上一篇:成 语 接 龙
下一篇:高考满分作文【感动篇】