操作系统原理(哈工大-李治军老师)操作系统引导
操作系统引导
开始试验之前先了解汇编语言为前提
第一步 完成 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吧
操作系统原理(哈工大-李治军老师)操作系统引导相关推荐
- Linux0.11操作系统(哈工大李治军老师)实验楼实验1-引导
Linux0.11操作系统(哈工大李治军老师)实验楼实验1-引导 实验源地址: https://www.lanqiao.cn/courses/115/learning/ 1.完成bootsect.s屏 ...
- Linux0.11操作系统(哈工大李治军老师)实验楼实验2-系统调用
Linux0.11操作系统(哈工大李治军老师)实验楼实验2-系统调用 在 Linux 0.11 上添加两个系统调用iam()和whoami(),并编写两个简单的应用程序测试它们. 原理 1. 应用程序 ...
- 哈工大李治军老师操作系统笔记【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. ...
- 操作系统(哈工大李治军老师)
L4 操作系统接口 操作系统接口 用户通过程序(应用软件)使用计算机 程序是普通代码加上一些重要的函数 如: 操作系统提供重要函数(重要函数就是操作系统接口,接口表现为函数调用,由系统提供,因此叫系统 ...
- 哈工大李治军老师操作系统笔记【29】:目录与文件系统(Learning OS Concepts By Coding Them !)
文章目录 0 回顾 1 目录与文件系统 1.1 映射 1.2 目录树 1.3 实现目录 1.4 树状目录的完整实现 2 总结 0 回顾 整个磁盘变成一棵目录树 目录树组织一堆文件 文件抽象 一个文件到 ...
- 哈工大李治军老师操作系统笔记【27】:从生磁盘到文件(Learning OS Concepts By Coding Them !)
文章目录 0 回顾 1 引入文件 1.1 映射 1.2 链式结构实现文件 1.3 索引结构实现文件 2 总结 0 回顾 盘块号就是连续的扇区 得到盘块号就能进行下列操作 1 引入文件 普通用户使用生磁 ...
- 操作系统(哈工大李治军老师)32讲
链接 https://www.bilibili.com/video/BV1d4411v7u7/?spm_id_from=333.788.recommend_more_video.0&vd_so ...
- 哈工大李治军老师操作系统笔记【13】:一个实际的schedule函数(Learning OS Concepts By Coding Them !)
文章目录 0 回顾 1 linux0.11的schedule() 1.1 counter的作用 2 总结 0 回顾 实际的schedule是多种基本算法的融合,综合考虑各种情况,但也要求算法本身尽可能 ...
- 哈工大李治军老师的操作系统学习笔记
文章目录 1 什么是操作系统 2 操作系统启动 3 操作系统接口 命令行发生了什么? 图形按钮怎么回事? 操作系统接口(系统调用) 4 操作系统调用 不应该随意访问内核 怎么不让你访问内核 不让我访问 ...
最新文章
- iOS 模仿微信的照片选择器
- C# 开发和使用中的33个技巧
- IHttpHandler的妙用之防盗链
- NuGet 发布类库,依赖项的问题
- Linux - XShell - alt 快捷键的设置
- CodeForces - 1437E Make It Increasing(确定首尾的最长不下降子序列)
- [汇编语言]实验:应用更灵活的寻址方式来定位内存地址
- 网络爬虫相关程序学习(包含jar包等)---各大网站网络爬虫
- 大数据之-Hadoop3.x_MapReduce_MapJoin案例需求分析---大数据之hadoop3.x工作笔记0133
- Linux中Docker部署Nginx
- Hibernate 笔记5 load和get方法的区别
- ssh工具的使用(全平台运行)
- U8采购入库单单价修复sql
- 基于改进区域生长算法的图像分割方法及实现
- 织梦dede文章列表调用标签的用法和规则
- 使用SqlConnection.connectionString连接数据库
- Leetcode | Insertion Sort List | 初出茅庐
- 国内RPG网游市场显现疲软 ACG细分将成增量市场
- NGS 数据过滤之 Trimmomatic
- 计算机不能启动 无法验证数字签名,Win10提示错误0xc0000428无法验证此文件的数字签名怎么办?...