哈工大操作系统实验一——操作系统的引导

写在前面

哈尔滨工业大学李治军老师的《操作系统》课程实验,相关资源:

哈工大操作系统实验手册

实验资源与参考

不配环境懒人福利:实验楼

在线课程:操作系统,李治军,哈工大(网易云课堂)

参考阅读:《Linux内核完全注释》——赵炯,《操作系统原理、实现与实践》——李治军,刘宏伟

实验内容

  • 改写bootsect.s,功能:能在屏幕上打印一段提示信息“XXX is booting...”。

  • 改写setup.s,功能:

  1. bootsect.s能完成setup.s的载入,并跳转到setup.s开始地址执行。而setup.s向屏幕输出一行"Now we are in SETUP"。

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

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

改写bootsect.s

bootsect.s驻留在引导扇区(0磁道,0磁头,第1个扇区)。上电自检后,ROM BIOS把bootsect加载到0x7c00处。bootsect做4件事:

  1. 将自身移动到0x90000处并继续执行。

  2. 利用INT 0X13中断将setup模块读到0x90200处,一共读四个扇区。

  3. 显示“Loading system...”的字符串

  4. 再把setup模块后的system模块加载到内存0x10000处。

注:由于实验裁剪Linux 0.11的源代码,没有使用root_dev。

汇编看起来有点头大,大部分源码问题都能在《注释》里找到答案,几个比较重要的点:

  • 将自身加载到0x9000后,跳到go处执行:

 jmpi    go,INITSEG      ! 段间跳转, INITSEG是目的段地址, go是段内偏移地址

由于自身代码移动了位置,所以需要段间跳转:

哈工大操作系统实验一——操作系统的引导_第1张图片

 

  • 修改显示字符串 将“Loading system ..."修改为”Welcome to NewOS“

    原字符串共18个字符,加上回车和换行共24个字符,修改后字符串长16个字符。

    调用INT 0X10中断,cx寄存器内存放显示字符数,bx寄存器存放属性(可修改字符串颜色),es:bp 指向待显示字符串。

mov ah,#0x03        ! 读取光标位置
xor bh,bh   
int 0x10
     
mov cx,#22
mov bx,#0x0009      ! page 0, attribute c 
mov bp,#msg1        ! es:bp 指向待显示字符串
mov ax,#0x1301      ! write string, move cursor
int 0x10
     
!开始执行setup代码
jmpi 0,SETUPSEG
 ​
msg1:
    .byte 13,10
    .ascii "Welcome to NewOS"
    .byte 13,10,13,10

改写setup.s

setup.s主要功能:

  1. 利用中断读取机器系统数据,保存到0x90000处(覆盖了bootsect.s)

  2. 将system模块从0x10000-0x8ffff整块下移到0x00000处。

  3. 进入32位保护模式,跳转到system模块的head.s

注:实验要求setup不加载后续的system模块,故暂时不必要实现。

显示“Now we are in SETUP”

参考bootsect.s中显示字符串的代码部分,很容易修改得到:

! 显示"Now we are in SETUP"
 mov ax,cs
 mov ds,ax
 mov es,ax
 ​
 mov ah,#0x03        ! 读取光标位置
 xor bh,bh
 int 0x10
     
 mov cx,#25
 mov bx,#0x0007      ! page 0, attribute normal 
 mov bp,#msg1        ! es:bp 指向待显示 字符串
 mov ax,#0x1301      ! write string, move cursor
 int 0x10

注意,在显示前务必设置cs = es = ds,在显示时需要es定位字符串,现在是setup程序,SETUPSEG = cs = 0x9020

显示硬件参数

显示硬件参数前,先将ds寄存器重置为0x90000(INITSEG),在读取参数时使用了ds寄存器并覆盖了bootsect.s,所以重置ds,寻址硬件参数,ps:汇编中,mov ax, [0]默认为mov ax, ds:[0] 后面按照取硬件参数的顺序,复制内存中的数据打印即可,比如光标信息:

 ! 打印光标信息
 mov ax, [0]
 call print_hex
 call print_nl

ps:根据读取时,磁盘硬件参数从[0x80]开始。

改写tools/build.c

根据实验指导在build.c中添加:

 if(strcmp(argv[3],"none")==0) return 0;

 

 

 

 

你可能感兴趣的:(操作系统)