操作系统实验1:引导


实验基本内容:

  1. 阅读《Linux 内核完全注释》的第 6 章,对计算机和 Linux 0.11 的引导过程进行初步的了解;
  2. 更改bootsect.s引导程序的开机显示文字,并能完成setup.s的载入
  3. 更改setup.s接管硬件程序的开机显示文字,并将基本硬件参数显示在硬盘上
  4. 有时,继承传统意味着别手蹩脚。x86 计算机为了向下兼容,导致启动过程比较复杂。请找出 x86 计算机启动过程中,被硬件强制,软件必须遵守的两个“多此一举”的步骤(多找几个也无妨),说说它们为什么多此一举,并设计更简洁的替代方案。

一.阅读linux内核完全注释:了解引导 P205

  1. 引导启动程序:boot/目录

    1. 启动引导时内核在内存中的位置和移动后的位置情况。(bootsect.s移位后引导其他扇区,setup.s:探测+os移位+临时建表进入保护模式)
    2. ROOT_DEV:根文件系统所在的默认块-设备号。交换设备号SWAP_DEV:用作虚拟存储交换空间的外部设备号
  2. bootsect.S程序
    1. 该程序作用:

      1. 首先把从磁盘第 2 个扇区开始的 4 个扇区的 setup 模块(由 setup.s 编译而成)加载到内存紧接着bootsect 后面位置处(0x90200)
      2. 然后利用BIOS 中断0x13 取磁盘参数表中当前启动引导盘的参数,接着在屏幕上显示“Loading system…”字符串。
      3. 把磁盘上 setup 模块后面的system 模块加载到内存0x10000 开始的地方。随后确定根文件系统的设备号。若没有指定,则根据所保存的引导盘的每磁道扇区数判别出盘的类型和种类(是 1.44M A 盘吗?),并保存其设备号于 root_dev (引导块的 508 地址处)中。
      4. 长跳转到setup 程序开始处(0x90200)去执行
  3. setup.S程序
    1. 该程序作用:

      1. 利用ROM BIOS 中断读取机器系统数据,并将这些数据保存到 0x90000 开始的位置(覆盖掉了 bootsect 程序所在的地方)。所取得的参数和保留的内存位置见表所示。这些参数将被内核中相关程序使用,例如字符设备驱动程序集中的console.ctty_io.c程序等。
      2. 然后setup 程序将system 模块从0x10000-0x8ffff 整块向下移动到内存绝对地址 0x00000 处(当时认为内核系统模块 system 的长度不会超过此值:512KB)。接下来加载中断描述符表寄存器(IDTR)和全局描述符表寄存器(GDTR),开启 A20 地址线,重新设置两个中断控制芯片 8259A,将硬件中断号重新设置为 0x20 - 0x2f。
      3. 设置CPU 的控制寄存器CR0(也称机器状态字),进入32 位保护模式运行,并跳转到位于 system 模块最前面部分的 head.s程序继续运行。
  4. head.s程序

二、实验

1.bootsect显示正确。es:bp 是显示字符串的地址:ES设#SETUPSEG是内存中存放setup.s开始的地方,BP表示存放#MSG2的偏移地址。

我没设es,没加inf_loop死循环。没改.org(! 表示下面语句从地址 506(0x1FA)开始,所以 root_dev 在启动扇区的第 508 开始的 2 个字节中。)! 首先读入光标位置mov ah,#0x03        xor bh,bhint 0x10! 显示字符串 “Hello OS world, my name is LZJ”
! 要显示的字符串长度mov cx,#36              !大一些没关系mov bx,#0x0007     mov bp,#msg1
! es:bp 是显示字符串的地址mov ax,#0x1301   int 0x10
  • 实验结果如图:(偷偷暗示我名字是YYF)

2.setup.s显示文字,并载入bootsect.s

! setup.s (从bootsect.s复制而来,换掉了msg1和start,并加上了死循环)
entry _start
_start:mov ah,#0x03        xor bh,bhint 0x10mov cx,#25            mov bx,#0x0007     mov bp,#msg2mov ax,csmov es,axmov ax,#0x1301   int 0x10
inf_loop:jmp inf_loop
msg2:.byte   13,10                     .ascii  "NOW we are in SETUP".byte   13,10,13,10
boot_flag:.word   0xAA55     ! bootsect.s (仅仅改了SETUPLEN而已)
SETUPLEN=2
entry _start
_start:mov ah,#0x03        xor bh,bhint 0x10mov cx,#36            mov bx,#0x0007     mov bp,#msg1mov ax,#0x07c0mov es,axmov ax,#0x1301   int 0x10
load_setup:
! 设置驱动器和磁头(drive 0, head 0): 软盘 0 磁头mov dx,#0x0000
! 设置扇区号和磁道(sector 2, track 0): 0 磁头、0 磁道、2 扇区mov cx,#0x0002
! 设置读入的内存地址:BOOTSEG+address = 512,偏移512字节        mov bx,#0x0200
! 设置读入的扇区个数(service 2, nr of sectors),
! SETUPLEN是读入的扇区个数,Linux 0.11 设置的是 4,
! 我们不需要那么多,我们设置为 2(因此还需要添加变量 SETUPLEN=2)mov ax,#0x0200+SETUPLEN
! 应用 0x13 号 BIOS 中断读入 2 个 setup.s扇区                    int 0x13
! 读入成功,跳转到 ok_load_setup: ok - continue            jnc ok_load_setup
! 软驱、软盘有问题才会执行到这里。我们的镜像文件比它们可靠多了    mov dx,#0x0000
! 否则复位软驱 reset the diskette    mov ax,#0x0000        int 0x13
! 重新循环,再次尝试读取jmp load_setup
ok_load_setup:
! 接下来要干什么?当然是跳到 setup 执行。
! 要注意:我们没有将 bootsect 移到 0x9000,因此跳转后的段地址应该是 0x7ce0
! 即我们要设置 SETUPSEG=0x07e0jmpi    0,SETUPSEG
! 注意将上一个实验的jmp inf_loop代码删掉!!

实验结果:

3.修改setup.s

  1. 显示数字的代码要看懂。其中用到的BIOS中断为INT 0x10,功能号0x0E(显示一个字符),即AH=0x0E,AL=要显示字符的ASCII码。但AL实际是由栈bp指向的字符赋值来的,那么其实显示的是ss:bp的字符
  2. 注意与上面区别。MOV AX,#0X1301 + INT 0x10是显示es:bp下的字符串
  3. 因此本题将ss设为#0x9000,es设为setup代码段基址#0x9020。再不断改变bp显示字符串即可
  !以16进制方式打印栈顶的16位数print_hex:mov    cx,#4         ! 4个十六进制数字mov    dx,(bp)     ! 将(bp)所指的值放入dx中,如果bp是指向栈顶的话print_digit:rol    dx,#4        ! 循环以使低4比特用上 !! 取dx的高4比特移到低4比特处。mov    ax,#0xe0f     ! ah = 请求的功能值,al = 半字节(4个比特)掩码。and    al,dl         ! 取dl的低4比特值。add    al,#0x30     ! 给al数字加上十六进制0x30cmp    al,#0x3ajl    outp          !是一个不大于十的数字add    al,#0x07      !是a~f,要多加7outp: int    0x10loop    print_digit !cx--ret!setup.s关键代码
! Be Ready to Printmov  ax,#SETUPSEG    ! init es = 0x9020mov  es,ax           mov     ax,#INITSEG         ! init ss:sp.put stack at 0x90000.mov   ss,axsub        sp,sp! Print "Now we are in SETUP"mov     ah,#0x03        ! read cursor posxor        bh,bhint        0x10mov     cx,#25mov       bx,#0x0007      ! page 0, attribute 7 (normal)mov       bp,#msg2mov     ax,#0x1301      ! write string, move cursorint      0x10! Get Paramsmov     ax,#INITSEG mov     ds,axmov    ah,#0x03  xor   bh,bhint    0x10      mov   [0],dx    mov   ah,#0x88int     0x15mov     [2],axmov   ax,#0x0000mov   ds,axlds    si,[4*0x41]mov  ax,#INITSEGmov  es,axmov    di,#0x0004mov   cx,#0x10repmovsb! Be Ready to Printmov  ax,#SETUPSEG    ! init es = 0x9020mov  es,ax           ! Cursor Position mov   ah,#0x03   xor  bh,bhint    0x10mov     cx,#18mov   bx,#0x0007     mov  bp,#msg_cursormov   ax,#0x1301   int    0x10 mov        bp,#0x00call    print_hex ! Memory Sizemov  ah,#0x03      xor   bh,bhint    0x10mov     cx,#14mov   bx,#0x0007      mov     bp,#msg_memorymov   ax,#0x1301      int     0x10 mov        bp,#0x02call    print_hex (后续代码如磁盘信息或许同上)

实验结果如图:


最后补番外链接:
1.实验楼(操作系统原理与实践)
https://www.shiyanlou.com/courses/115
2.网易云课堂:哈尔滨工业大学,国家级精品课程,操作系统
https://mooc.study.163.com/course/1000002004#/info
3.推荐markdown神器,本文由此写成
https://typora.io/
(完)

(浓缩+精华)哈工大-操作系统-MOOC-李治军教授-实验1-操作系统的引导相关推荐

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

    写在前面 哈尔滨工业大学李治军老师的<操作系统>课程实验,相关资源: 哈工大操作系统实验手册 实验资源与参考 不配环境懒人福利:实验楼 在线课程:操作系统,李治军,哈工大(网易云课堂) 参 ...

  2. 操作系统(李治军) L9多进程图像-操作系统最重要的图像

    @[TOC]操作系统 解决一个任务即开启一个进程 PCB(process control block)进程控制块 'W'设置成阻塞态 Schedule():切换函数 pCur:当前进程 pNew:新进 ...

  3. 操作系统(李治军) L8 CPU管理的直观想法

    @[TOC]操作系统 CPU的 取指执行 给了cpu初地址自动的取值执行 给地址在内存中取出来执行 50:mov ax,[100] 51:mov bx,[101] - - 依次向下顺序执行 管理CPU ...

  4. 操作系统(李治军) L12内核级线程的实现

    只有支持了进程才可以管理CPU 图:五段论 整个过程:从用户栈->内核栈->TCB->TCB完成切换(TCB用switch_to完成TCB的切换完成内核栈的切换)->内核栈切换 ...

  5. 操作系统(李治军) L11内核级线程

    **用户级和核心级的区别:根据TCB切换一个栈还是一套栈** 进入内核要用中断 INT和IRET压栈来使寄存器的状态指令从用户栈和内核栈来回切换 ESP:系统分区 cur,next当前和下一个线程的T ...

  6. 操作系统(李治军) L10用户级线程

    进程更大,线程更小 进程切换=指令切换+资源(内存)(映射表)切换[分治思想] 线程切换:避免了进程切换代价:不需要切换资源(映射表) 这是多个线程 这是因为进程的地址是分离的,所以是线程 buffe ...

  7. 操作系统实验一到实验九合集(哈工大李治军)

    操作系统实验 作者寄语 操作系统实验的学习是一个循序渐进的过程,初次看linux-0.11中的代码,看着满屏的汇编语言,确实头疼.但通过学习赵炯博士的Linux内核0.11完全注释,结合着王爽老师的汇 ...

  8. 哈工大操作系统实验总结

    实验地址, https://www.lanqiao.cn/courses/115/learning/?id=374, 在现做实验, 好处是环境提前都配好了, 不足之处是敲代码有网络延迟, 环境无法保存 ...

  9. Linux0.11操作系统(哈工大李治军老师)实验楼实验1-引导

    Linux0.11操作系统(哈工大李治军老师)实验楼实验1-引导 实验源地址: https://www.lanqiao.cn/courses/115/learning/ 1.完成bootsect.s屏 ...

最新文章

  1. 把文档放到PNG图片中
  2. python直方图均衡化
  3. php编程实现单入口,apache配置php实现单一入口方法
  4. QT4使用HDF5 类型错误
  5. Java 用接口实现加减乘除计算器
  6. 建武28a对讲机最大距离_小米对讲机再出新品:不但价格低,还能一键写频
  7. 异步电机matlab仿真 推荐 辅导书,异步电机模型Matlab仿真
  8. 五、ELK设置用户密码登陆
  9. 厘米和磅的转换程序python_在Python中如何将磅转换成公斤
  10. CODEVS 1069 关押罪犯
  11. EOS区块链的通信模型
  12. YOLOv3目标检测算法——通俗易懂的解析
  13. SpringBoot 中定时执行注解(@Scheduled、@EnableScheduling)
  14. 接口与抽象类的区别,为什么要用接口,抽象类不香吗?
  15. 【基础入门题072】转置矩阵
  16. JUC详解 | JUC Lock
  17. 【计算机网络】HTTP协议中Get与Post的区别
  18. ERROR in Cannot find module ‘node-sass‘和Error:Node Sass version 5.0.0 is incompatible with ^4.0.0解决
  19. JAVA热部署神器,JRebel破解版,JRebel免费实用插件
  20. 1.Docker学习之基础知识

热门文章

  1. Python数据挖掘入门与实践pdf
  2. flash加载html代码
  3. Word中分隔符 分页符 分栏符 换行符 分节符的用法
  4. 数字图像处理之高斯滤波加速优化
  5. 怎么把图片修改成600x800像素图片?
  6. 码率控制中的“鸡生蛋蛋生鸡”的悖论
  7. linux上常用命令及通用软件安装
  8. 推荐一款使用java+MYSQL搭建的 客户oa管理系统源码
  9. avr flash_AVR | 掩蔽
  10. Navicat Premium 12 卸载和注册表的删除