实验一操作系统的引导 下载本文

内容发布更新时间 : 2024/5/9 18:23:34星期一 下面是文章的全部内容请认真阅读。

实验目的<编辑>

? ? ? ?

熟悉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、Sunix等(可以上论坛上秀秀谁的OS名字最帅,也可以显示一个特色logo,以表示自己操作系统的与众不同。) 改写setup.s主要完成如下功能: 1. 2. 3.

bootsect.s能完成setup.s的载入,并跳转到setup.s开始地址执行。而setup.s向屏幕输出一行\。

setup.s能获取至少一个基本的硬件参数(如内存参数、显卡参数、硬盘参数等),将其存放在内存的特定地址,并输出到屏幕上。

setup.s不再加载Linux内核,保持上述信息显示在屏幕上即可。

实验报告<编辑>

在实验报告中回答如下问题: 1.

有时,继承传统意味着别手蹩脚。x86计算机为了向下兼容,导致启动过程比较复杂。请找出x86计算机启动过程中,被硬件强制,软件必须遵守的两个“多此一举”的步骤(多找几个也无妨),说说它们为什么多此一举,并设计更简洁的替代方案。

评分标准<编辑>

? ? ? ? ? ? ? bootsect显示正确,1020% bootsect正确读入setup,10% setup显示正确,10% setup获取硬件参数正确,5% setup正确显示硬件参数,5% tools/build.c修改正确,1020% 实验报告,5060% 实验提示<编辑>

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

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

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

Linux 0.11相关代码详解

boot/bootsect.s、boot/setup.s和tools/build.c是本实验会涉及到的源文件。它们的功能详见《注释》的6.2、6.3节和16章。

如果使用Windows下的环境,那么要注意Windows环境里提供的build.c是一个经过修改过的版本。Linus Torvalds的原版是将0.11内核的最终目标代码输出到标准输出,由make程序将数据重定向到Image文件,这在Linux、Unix和Minix等系统下都是非常有效的。但Windows本身的缺陷(也许是特色)决定了在Windows下不能这么做,所以flyfish修改了build.c,将输出直接写入到Image(flyfish是写入到Boot.img文件,我们为了两个环境的一致,也为了最

大化地与原始版本保持统一,将其改为Image)文件中。同时为了适应Windows的一些特殊情况,他还做了其它一些小修改。

引导程序的运行环境

引导程序由BIOS加载并运行。它活动时,操作系统还不存在,整台计算机的所有资源都由它掌控,而能利用的功能只有BIOS中断调用。

完成bootsect.s的屏幕输出功能

首先来看完成屏幕显示的关键代码如下:

! 首先读入光标位置 mov ah,#0x03 xor bh,bh int 0x10

! 显示字符串“LZJos is running...” mov cx,#25 mov bx,#0x0007 mov bp,#msg1 mov ax,#0x1301 int 0x10

inf_loop: jmp inf_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

! 必须有它,才能引导

接下来,将完成屏幕显示的代码在开发环境中编译,并使用linux-0.11/tools/build.c将编译后的目标文件做成Image文件。

编译和运行

Ubuntu上先从终端进入~/oslab/linux-0.11/boot/目录。Windows上则先双击快捷方式“MinGW32.bat”,将打开一个命令行窗口,当前目录是oslab,用cd命令进入linux-0.11\\boot。无论那种系统,都执行下面两个命令编译和链接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可列出下面的信息:

-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是编译、链接后的目标文件。

需要留意的文件是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”可以看到:

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 8e c0 b4 03 30 ff cd 10 b9 17 00 |.........0......|

00000030 bb 07 00 bd 3f 00 b8 01 13 cd 10 b8 00 90 8e c0 |....?...........|

00000040 ba 00 00 b9 02 00 bb 00 02 b8 04 02 cd 13 73 0a |..............s.|

00000050 ba 00 00 b8 00 00 cd 13 eb e1 ea 00 00 20 90 0d |............. ..|

00000060 0a 53 75 6e 69 78 20 69 73 20 72 75 6e 6e 69 6e |.Sunix is runnin|

00000070 67 21 0d 0a 0d 0a 00 00 00 00 00 00 00 00 00 00 |g!..............|

00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| *

00000210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa