操作系统引导

开始试验之前先了解汇编语言为前提

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


  • 进入目录

cd /home/shiyanlou/oslab

  • 解压

tar -zxvf hit-oskab

  • 进入oslab/linux-0.11/boot目录

cd oslab/linux-0.11/boot

  • 进入bootsect.s粘贴以下内容
entry _start
_start:mov ah,#0x03xor bh,bhint 0x10mov cx,#36mov bx,#0x0007mov bp,#msg1mov ax,#0x07c0mov es,axmov ax,#0x1301int 0x10
inf_loop:jmp inf_loop
msg1:.byte   13,10.ascii  "Hello OS world, my name is LZJ".byte   13,10,13,10
.org 510
boot_flag:.word   0xAA55
  • 在目录执行下面两个命令编译和链接
$ as86 -0 -a -o bootsect.o bootsect.s
$ ld86 -0 -s -o bootsect bootsect.o
  • 其中 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 个字节后就可以放入引导扇区了。

  • 剔除生成的bootsect的字节数由 544修改到512
shiyanlou@3a7e1252e814:~/oslab/oslab/linux-0.11/boot$ ls -la
\u603b\u7528\u91cf 36
drwxr-xr-x  2 shiyanlou shiyanlou 4096  3\u6708 27 12:08 .
drwxr-xr-x 10 shiyanlou shiyanlou 4096  8\u6708 23  2011 ..
-rwxrwxr-x  1 shiyanlou shiyanlou  544  3\u6708 27 12:08 bootsect
-rw-rw-r--  1 shiyanlou shiyanlou  164  3\u6708 27 12:08 bootsect.o
-rw-r--r--  1 shiyanlou shiyanlou  340  3\u6708 27 12:04 bootsect.s
-rw-r--r--  1 shiyanlou shiyanlou 5938  8\u6708 28  2008 head.s
-rw-r--r--  1 shiyanlou shiyanlou 5362  8\u6708 28  2008 setup.s
shiyanlou@3a7e1252e814:~/oslab/oslab/linux-0.11/boot$ dd bs=1 if=bootsect of=Image skip=32
\u8bb0\u5f55\u4e86512+0 \u7684\u8bfb\u5165
\u8bb0\u5f55\u4e86512+0 \u7684\u5199\u51fa
512\u5b57\u8282(512 B)\u5df2\u590d\u5236\uff0c0.00162956 \u79d2\uff0c314 kB/\u79d2
shiyanlou@3a7e1252e814:~/oslab/oslab/linux-0.11/boot$ ls
bootsect  bootsect.o  bootsect.s  head.s  Image  setup.s
  • 拷贝生成的Image镜像到linux-0.11目录下
shiyanlou@3a7e1252e814:~/oslab/oslab/linux-0.11/boot$ cp -rvf Image  ../
"Image" -> "../Image"
  • 去oslavb目录下run吧执行脚本即可
shiyanlou@3a7e1252e814:~/oslab/oslab/linux-0.11/boot$ cp -rvf Image  ../
"Image" -> "../Image"

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


第二步bootsect.s 读入 setup.s

  • 进入目录
/home/shiyanlou/oslab/oslab/linux-0.11/boot
  • 修改setup.s文件的内容添加如下
_start:mov ah,#0x03xor bh,bhint 0x10mov cx,#25mov bx,#0x0007mov bp,#msg2mov ax,cs                ! 这里的cs其实就是这段代码的段地址mov es,axmov ax,#0x1301int 0x10
inf_loop:jmp inf_loop
msg2:.byte  13,10.ascii "Now we are in SETUP".byte    13,10,13,10
.org 510
boot_flag:.word 0xAA55
  • 接着需要编写bootsect.s中载入setup.s的关键代码

所有需要的功能在原版 bootsect.s 中都是存在的,我们要做的仅仅是将这些代码添加到新的 bootsect.s 中去。
除了新增代码,我们还需要去掉在 bootsect.s 添加的无限循环。

  • 新增bootsect.s的代码,去掉bootsect.s添加的无限循环
SETUOLEN=2              ! 读入的扇区数
SETUPSEG=0x07e0         ! setup代码的段地址
entry _start
_start:mov ah,#0x03        ! 设置功能号xor bh,bh           ! 将bh置0int 0x10            ! 返回行号和列号,供显示串用mov cx,#52          !要显示的字符串长度mov bx,#0x0007      ! bh=0,bl=07(正常的黑底白字)mov bp,#msg1        ! es:bp 要显示的字符串物理地址mov ax,#0x07c0      ! 将es段寄存器置为#0x07c0mov es,ax           mov ax,#0x1301      ! ah=13(设置功能号),al=01(目标字符串仅仅包含字符,属性在BL中包含,光标停在字符串结尾处)int 0x10            ! 显示字符串! 将setup模块从磁盘的第二个扇区开始读到0x7e00
load_setup:mov dx,#0x0000                  ! 磁头=0;驱动器号=0mov cx,#0x0002                  ! 磁道=0;扇区=2mov bx,#0x0200                  ! 偏移地址mov ax,#0x0200+SETUPLEN         ! 设置功能号;需要读出的扇区数量int 0x13                        ! 读磁盘扇区到内存jnc ok_load_setup               ! CF=0(读入成功)跳转到ok_load_setup  mov dx,#0x0000                  ! 如果读入失败,使用功能号ah=0x00————磁盘系统复位mov ax,#0x0000int 0x13jmp load_setup                  ! 尝试重新读入ok_load_setup:jmpi    0,SETUPSEG              ! 段间跳转指令,跳转到setup模块处(0x07e0:0000)! 字符串信息
msg1:.byte   13,10           ! 换行+回车.ascii  "Welcome to the world without assembly language".byte   13,10,13,10     ! 换行+回车! 将
.org 510! 启动盘具有有效引导扇区的标志。仅供BIOS中的程序加载引导扇区时识别使用。它必须位于引导扇区的最后两个字节中
boot_flag:.word   0xAA55
  • 在 Ubuntu 下,进入 linux-0.11 目录后,使用下面命令(注意大小写)

$ make BootImage

  • 会有报错信息这是正常现象
as86 -0 -a -o boot/bootsect.o boot/bootsect.s
ld86 -0 -s -o boot/bootsect boot/bootsect.o
as86 -0 -a -o boot/setup.o boot/setup.s
ld86 -0 -s -o boot/setup boot/setup.o
gcc -m32 -g -Wall -O2 -fomit-frame-pointer  \-o tools/build tools/build.c
tools/build.c: \u5728\u51fd\u6570\u2018main\u2019\u4e2d:
tools/build.c:118:2: \u8b66\u544a\uff1a \u63d0\u9886\u7c7b\u578b\u53cc\u5173\u7684\u6307\u9488\u5c06\u7834\u574f\u5f3a\u91cd\u53e0\u89c4\u5219 [-Wstrict-aliasing]
tools/build.c:147:2: \u8b66\u544a\uff1a \u63d0\u9886\u7c7b\u578b\u53cc\u5173\u7684\u6307\u9488\u5c06\u7834\u574f\u5f3a\u91cd\u53e0\u89c4\u5219 [-Wstrict-aliasing]
tools/build boot/bootsect boot/setup none  > Image
Root device is (3, 1)
Boot sector 512 bytes.
Setup is 512 bytes.
Unable to open 'system'
make: *** [BootImage] \u9519\u8bef 1
  • 打个小补丁进入下面文件注释掉178-190行

$ vim ./tools/build.c

  • 重新编译即可
shiyanlou@32d27690b4d9:~/oslab/oslab/linux-0.11$ make BootImage
  • 然后run一下脚本就行了

至此完成bootsect.s 读入 setup.s


第三步setup.s 获取基本硬件参数

  • 进入目录shiyanlou@32d27690b4d9:~/oslab/oslab/linux-0.11/boot/bootsect.s 添加下列参数
INITSEG  = 0x9000                   ! 参数存放位置的段地址
entry _start
_start:
! 打印 "NOW we are in SETUP"mov ah,#0x03xor bh,bhint 0x10mov cx,#25mov bx,#0x0007mov bp,#msg2mov ax,csmov es,axmov ax,#0x1301int 0x10! 获取光标位置mov ax,#INITSEGmov ds,axmov ah,#0x03xor bh,bhint 0x10                        ! 返回:dh = 行号;dl = 列号mov [0],dx                      ! 存储到内存0x9000:0处! 获取内存大小mov ah,#0x88int 0x15                        ! 返回:ax = 从0x100000(1M)处开始的扩展内存大小(KB)mov [2],ax                      ! 将扩展内存数值存放在0x90002处(1个字)! 读第一个磁盘参数表复制到0x90004处mov ax,#0x0000mov ds,axlds si,[4*0x41]                 ! 把低字(2B)置为偏移地址,高字(2B)置为段地址mov ax,#INITSEGmov es,axmov di,#0x0004mov cx,#0x10                    ! 重复16次,即传送16Brepmovsb                           ! 按字节传送! 打印前的准备mov ax,csmov es,axmov ax,#INITSEGmov ds,ax! 打印"Cursor position:"mov ah,#0x03xor bh,bhint 0x10mov cx,#18mov bx,#0x0007mov bp,#msg_cursormov ax,#0x1301int 0x10! 打印光标位置mov dx,[0]call    print_hex! 打印"Memory Size:"mov ah,#0x03xor bh,bhint 0x10mov cx,#14mov bx,#0x0007mov bp,#msg_memorymov ax,#0x1301int 0x10! 打印内存大小mov dx,[2]call    print_hex! 打印"KB"mov ah,#0x03xor bh,bhint 0x10mov cx,#2mov bx,#0x0007mov bp,#msg_kbmov ax,#0x1301int 0x10! 打印"Cyls:" mov ah,#0x03xor bh,bhint 0x10mov cx,#7mov bx,#0x0007mov bp,#msg_cylesmov ax,#0x1301int 0x10! 打印柱面数   mov dx,[4]call    print_hex! 打印"Heads:"mov ah,#0x03xor bh,bhint 0x10mov cx,#8mov bx,#0x0007mov bp,#msg_headsmov ax,#0x1301int 0x10! 打印磁头数mov dx,[6]call    print_hex! 打印"Sectors:"mov ah,#0x03xor bh,bhint 0x10mov cx,#10mov bx,#0x0007mov bp,#msg_sectorsmov ax,#0x1301int 0x10mov dx,[18]call    print_hexinf_loop:jmp inf_loop! 上面的call都转到这里
print_hex:mov    cx,#4                    ! dx(16位)可以显示4个十六进制数字
print_digit:rol    dx,#4                    ! 取 dx 的高4比特移到低4比特处mov    ax,#0xe0f                ! ah = 请求的功能值(显示单个字符),al = 半字节(4个比特)掩码and    al,dl                    ! 前4位会被置为0add    al,#0x30                 ! 给 al 数字加上十六进制 0x30cmp    al,#0x3a                 ! 比较看是否大于数字十jl     outp                     ! 是一个不大于十的数字则跳转add    al,#0x07                 ! 否则就是a~f,要多加7
outp:int    0x10                     ! 显示单个字符loop   print_digit              ! 重复4次ret                             ! 打印换行回车
print_nl:mov    ax,#0xe0d     ! CRint    0x10mov    al,#0xa     ! LFint    0x10retmsg2:.byte 13,10.ascii "NOW we are in SETUP".byte 13,10,13,10
msg_cursor:.byte 13,10.ascii "Cursor position:"
msg_memory:.byte 13,10.ascii "Memory Size:"
msg_cyles:.byte 13,10.ascii "Cyls:"
msg_heads:.byte 13,10.ascii "Heads:"
msg_sectors:.byte 13,10.ascii "Sectors:"
msg_kb:.ascii "KB".org 510
boot_flag:.word 0xAA55

Memory Size 是 0x3C00KB,算一算刚好是 15MB(扩展内存),加上 1MB 正好是 16MB。

  • 看看 Bochs 配置文件 bochs/bochsrc.bxrc:

    注意三个点要跟图片一致才可以
!……
megs: 16
!……
ata0-master: type=disk, mode=flat, cylinders=204, heads=16, spt=38
!……
  • 然后继续Make Image 编译 RUN吧

操作系统原理(哈工大-李治军老师)操作系统引导相关推荐

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

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

  2. Linux0.11操作系统(哈工大李治军老师)实验楼实验2-系统调用

    Linux0.11操作系统(哈工大李治军老师)实验楼实验2-系统调用 在 Linux 0.11 上添加两个系统调用iam()和whoami(),并编写两个简单的应用程序测试它们. 原理 1. 应用程序 ...

  3. 哈工大李治军老师操作系统笔记【10】:内核级线程实现(Learning OS Concepts By Coding Them !)

    文章目录 0 回顾 1 实现 1.1 int 0x80 fork(中断入口) 1.2 进入核心态 1.3 system_call(中断切换中间三段) 1.4 中断出口 1.3 switch_to 1. ...

  4. 操作系统(哈工大李治军老师)

    L4 操作系统接口 操作系统接口 用户通过程序(应用软件)使用计算机 程序是普通代码加上一些重要的函数 如: 操作系统提供重要函数(重要函数就是操作系统接口,接口表现为函数调用,由系统提供,因此叫系统 ...

  5. 哈工大李治军老师操作系统笔记【29】:目录与文件系统(Learning OS Concepts By Coding Them !)

    文章目录 0 回顾 1 目录与文件系统 1.1 映射 1.2 目录树 1.3 实现目录 1.4 树状目录的完整实现 2 总结 0 回顾 整个磁盘变成一棵目录树 目录树组织一堆文件 文件抽象 一个文件到 ...

  6. 哈工大李治军老师操作系统笔记【27】:从生磁盘到文件(Learning OS Concepts By Coding Them !)

    文章目录 0 回顾 1 引入文件 1.1 映射 1.2 链式结构实现文件 1.3 索引结构实现文件 2 总结 0 回顾 盘块号就是连续的扇区 得到盘块号就能进行下列操作 1 引入文件 普通用户使用生磁 ...

  7. 操作系统(哈工大李治军老师)32讲

    链接 https://www.bilibili.com/video/BV1d4411v7u7/?spm_id_from=333.788.recommend_more_video.0&vd_so ...

  8. 哈工大李治军老师操作系统笔记【13】:一个实际的schedule函数(Learning OS Concepts By Coding Them !)

    文章目录 0 回顾 1 linux0.11的schedule() 1.1 counter的作用 2 总结 0 回顾 实际的schedule是多种基本算法的融合,综合考虑各种情况,但也要求算法本身尽可能 ...

  9. 哈工大李治军老师的操作系统学习笔记

    文章目录 1 什么是操作系统 2 操作系统启动 3 操作系统接口 命令行发生了什么? 图形按钮怎么回事? 操作系统接口(系统调用) 4 操作系统调用 不应该随意访问内核 怎么不让你访问内核 不让我访问 ...

最新文章

  1. iOS 模仿微信的照片选择器
  2. C# 开发和使用中的33个技巧
  3. IHttpHandler的妙用之防盗链
  4. NuGet 发布类库,依赖项的问题
  5. Linux - XShell - alt 快捷键的设置
  6. CodeForces - 1437E Make It Increasing(确定首尾的最长不下降子序列)
  7. [汇编语言]实验:应用更灵活的寻址方式来定位内存地址
  8. 网络爬虫相关程序学习(包含jar包等)---各大网站网络爬虫
  9. 大数据之-Hadoop3.x_MapReduce_MapJoin案例需求分析---大数据之hadoop3.x工作笔记0133
  10. Linux中Docker部署Nginx
  11. Hibernate 笔记5 load和get方法的区别
  12. ssh工具的使用(全平台运行)
  13. U8采购入库单单价修复sql
  14. 基于改进区域生长算法的图像分割方法及实现
  15. 织梦dede文章列表调用标签的用法和规则
  16. 使用SqlConnection.connectionString连接数据库
  17. Leetcode | Insertion Sort List | 初出茅庐
  18. 国内RPG网游市场显现疲软 ACG细分将成增量市场
  19. NGS 数据过滤之 Trimmomatic
  20. 计算机不能启动 无法验证数字签名,Win10提示错误0xc0000428无法验证此文件的数字签名怎么办?...

热门文章

  1. EDA09--VCS 操作实践(二)
  2. 查出每个部门的工资前三的员工信息
  3. 企业微信私域流量运营应当掌握的“工具”
  4. 解决win7系统电脑右下角小喇叭有个小叉
  5. HTML5 和 CSS3 提高篇 下 2D转换 transform(移动、旋转、缩放、中心点、综合写法);动画(animation);3D转换;浏览器私有前缀;背景色线性渐变
  6. 网络管理服务器篇之FTP
  7. nodejs的 面试大全 容易 难的都有
  8. Python Tkinter详解 (一)窗体的创建
  9. 【数字IC验证快速入门】3、数字IC设计全流程介绍
  10. d3关联关系图力引导图,支持多条线,带箭头。