HIT oslab之实验2 操作系统的引导(bootsect.s + setup.s)
零、实验1 实验环境搭建
1.参考教程
2.遇到的问题
(1)dokg: 错误:另外一个进程已经为 dpkg fronted lock 加锁
解决办法:重启,解释
3.补充:查看ubuntu 位数 uname -a
一、实验2的内容
1.实现bootsect.s的屏幕输出功能;
2.bootsect.s读入setup.s;
3.setup.s获取并显示基本硬件参数;
教程:操作系统原理与实践
二、实现bootsect.s的屏幕输出功能
1.代码(和教程有点不同,在2.说明里解释了;按照教程来)
mov ah, #0x03
xor bh, bh
int 0x10mov ax, #0x1301
mov bx, #0x0007
mov cx, #32
mov bp, #msg1
int 0x10inf_loop:jmp inf_loopmsg1:.byte 13,10.ascii "Forrest's OS is Loading...".byte 13,10,13,10.org 508root_dev:.word ROOT_DEVboot_flag:.word 0xAA55
在原有linux-0.11的bootsect.s代码进行修改
2.解析
!首先读光标位置
!BIOS中断0x10 功能号ah = 0x03, 读光标的位置
!input : bh = 页号
! output : dh = 行号(0x00顶端);dl = 列号(0x00最右端)mov ah, #0x03
xor bh, bh
int 0x10!输出字符串 "Forrest's OS is Loading..."
!BIOS中断0x10 功能号ah = 0x13,显示字符串
!input : al = 放置光标的方式及规定属性。0x01表示使用bl中的属性值,光标停在字符串结尾处。
!bh = 显示页面号,bl = 字符属性。
!cx = 显示的字符串字符数,这里是26+6=32,即msg1所占的字符。
! es:bp指向需显示的字符串起始位置处mov ax, #0x1301
mov bx, #0x0007
mov cx, #32
mov bp, #msg1 !es存的是#INITSEG, 0x9000
int 0x10!设置一个无限循环(纯粹为了多看一万眼字符串显示)
inf_loop:jmp inf_loop!msg1处放置字符串
msg1:
!换行+回车.byte 13,10
!字符串.ascii "Forrest's OS is Loading..."
!两对换行+回车.byte 13,10,13,10.org 508 !设定起始偏移地址!原有代码就有
root_dev:.word ROOT_DEV!这样boot_flag的2个魔数在最后2个字节
!boot_flag引导扇区标记,0xAA55
boot_flag:.word 0xAA55
说明:
①教程中,把es设定为#0x07c0,虽然最终结果没出错,但实际上逻辑是有问题的,因为在屏幕显示字符串之前,bootsect所在内存位置发生了移动,而linus已经将es设定成了#INITSEG,所以以下截图的内容可以去掉:
②教程下述做法会报错
注意:看了后面的教程才反应过来,原来是重新写bootsect.s,我以为是在原版基础上进行修改…
实际上不需要修改linus的这块代码。
疑问点:
为什么页号为0?
补充: “回车”,告诉打字机把打印头定位在左边界;另一个叫做 “换行”,告诉打字机把纸向下移一行。
3.编译 + 做Image文件
将完成屏幕显示的代码在开发环境中编译,并将编译后的目标文件做成 Image 文件。
这部分的解释见教程。
(1)编译
as86 -0 -a -o bootsect.o bootsect.s
(2)链接
ld86 -0 -s -o bootsect bootsect.o
(3)生成Image文件
dd bs=1 if=bootsect of=Image skip=32
linux的dd命令,以bootsect为输入,以每次1byte的速度写到文件Image中,并跳过开头的32byte才开始写入
(4)拷贝到linux-0.11目录下
. ./父级目录
4.bootsect引导后的系统启动情况
三、bootsect.s读入setup.s
此处起,按照教程来,而不是在原有代码上修改。
1.编写setup.s的代码
entry _start
_start:mov ah, #0x03xor bh, bhint 0x10mov cx, #25mov bx, #0x0007mov ax, csmov es, ax !修改es的值为csmov ax, #0x1301mov bp, #msg2int 0x10inf_loop:jmp inf_loopmsg2:.byte 13,10.ascii "Now we are in SETUP".byte 13,10,13,10.org 510
boot_flag:.word 0xAA55
2.编写 bootsect.s 中载入 setup.s的代码
BOOTSEG=0x07c0 !左移4位后就是0x7c00,占512B,所以偏移512B(0x0200)后得0x7e00;
SETUPSEG=0x07e0
SETUPLEN=2 !linus写的是4,教程是2
entry _start
_start:
!屏幕输出功能mov ah,#0x03xor bh,bhint 0x10mov bx,#0x0007mov cx,#32mov bp,#msg1mov ax,#BOOTSEGmov es,axmov ax,#0x1301int 0x10!加载setup
load_setup:mov dx,#0x0000mov cx,#0x0002 !扇区不是从0开始的,而是从1开始的,1是bootsect所在的扇区,setup从扇区2开始mov bx,#0x200 !es:bx 指向将要存放的内存地址mov ax,#0x0200+SETUPLEN !读2个扇区到内存int 0x13jnc ok_load_setup !成功就跳转到ok_load_setup执行mov dx,#0x0000mov ax,#0x0000 !复位软盘int 0x13jmp load_setup!跳转到setup执行
ok_load_setup:jmpi 0,SETUPSEG !段间跳转指令 cs = SETUPSEG,ip = 0!inf_loop:
! jmp inf_loopmsg1:.byte 13,10.ascii "Forrest's OS is Loading...".byte 13,10,13,10.org 510boot_flag:.word 0xAA55
3.make BootImage
有 Error!这是因为 make 根据 Makefile 的指引执行了 tools/build.c,它是为生成整个内核的镜像文件而设计的,没考虑我们只需要 bootsect.s 和 setup.s 的情况。它在向我们要 “系统” (system)的核心代码。为完成实验,接下来给它打个小补丁。
4.修改build.c
build.c 从命令行参数得到 bootsect、setup 和 system 内核的文件名,将三者做简单的整理后一起写入 Image。
上文因缺乏system的代码,所以报错
改造build.c的思路就忽略所有与system有关的工作:
四、setup.s获取并显示基本硬件参数
1.代码(含关键注释)
INITSEG = 0x9000
entry _start
_start:
!屏幕输出功能mov ah, #0x03xor bh, bhint 0x10mov cx, #25mov bx, #0x0007mov ax, csmov es, ax !修改es的值为csmov ax, #0x1301mov bp, #msg2int 0x10!将硬件参数取出来放在内存0x90000处mov ax,#INITSEGmov ds,ax !数据段的基地址0x9000!读光标位置xor bh,bhmov ah,#0x03int 0x10mov [0],dx !dh=行号,dl=列号!读扩展内存大小,超过1M则为扩展mov ah,#0x88int 0x15mov [2],ax!读第1个磁盘参数表,共16个字节大小;其首地址在int 0x41的中断向量位置!中断向量表的起始地址是0x000, 共1KB大小,并且每个表项占4B!所以第1个磁盘参数表的首地址的地址:0x41*4=0x104, 此处4B由段地址和偏移地址组成mov ax,#0x0000mov ds,ax !中断向量表的起始地址lds si,[4*0x41] !先存入的是偏移地址,取出存到si中 !取出的4个字节,高位存入ds,低位存入simov ax,#INITSEGmov es,axmov di,#0x0004 !光标和内存共占4B; 不是mov di,#0x0080 !目标地址 : 0x9000:0x0080 mov cx,#16repmovsb !按字节传送!打印前的准备mov ax,csmov es,ax !setup所在的代码段 mov ax,#INITSEGmov ds,ax !数据段,指向参数所在的地方!读光标位置,显示提示语,并把数值入栈mov ah,#0x03xor bh,bhint 0x10mov cx,#18 !16+2mov bx,#0x0007mov bp,#msg_cursor !"Cursor position:" es:bpmov ax,#0x1301int 0x10mov dx,[0] !存好的光标位置读出存到dx中,那没必要再读光标了吧;显示字符串需要放置光标,所以要读call print_hex !打印光标位置!显示内存大小mov ah,#0x03xor bh,bhint 0x10mov cx,#14 !12+2mov bx,#0x0007mov bp,#msg_memory !"Memory Size:"mov ax,#0x1301int 0x10mov dx,[2]call print_hex !补上KBmov ah,#0x03xor bh,bhint 0x10mov cx,#2mov bx,#0x0007mov bp,#msg_kbmov ax,#0x1301int 0x10!柱面,cylinder Cylesmov ah,#0x03xor bh,bhint 0x10mov cx,#8mov bx,#0x0007mov bp,#msg_cylesmov ax,#0x1301int 0x10mov dx,[4]call print_hex!磁头 Headsmov ah,#0x03xor bh,bhint 0x10mov cx,#8mov bx,#0x0007mov bp,#msg_headsmov ax,#0x1301int 0x10mov dx,[6]call print_hex!扇区 sectorsmov ah,#0x03xor bh,bhint 0x10mov cx,#10mov bx,#0x0007mov bp,#msg_sectorsmov ax,#0x1301int 0x10mov dx,[18] !应该是18,而不是12吧call print_hexinf_loop:jmp inf_loop!显示硬件参数(16位形式)
print_hex:!以4位16进制数进行显示mov cx,#4!mov dx,(bp) !bp指向栈顶,将其指向的指存入dx?什么栈顶? bp指向的不是msg2吗?不用管栈print_digit:!使从高位到低位显示4位16进制数rol dx,#4!ah=0x0e,显示一个字符;al=要显示的字符的ascii码;BIOS中断为int 0x10mov ax,#0x0e0f !此时的al未半字节的掩码and al,dl !取dl的低4位存入al中add al,#0x30cmp al,#0x3a !如果是数字,范围是0x30~0x39,即小于0x3ajl outp !al小于#0x3a跳转,即数字则跳转add al,#0x07 !字母则加上0x07,a~f的范围0x41~0x46outp:int 0x10loop print_digit !每次执行 loop 指令,cx 减 1,然后判断 cx 是否等于 0。 这里即执行4次ret!打印回车换行
print_nl:!CR 回车mov ax,#0x0e0dint 0x10!LF 换行mov ax,#0x0e0aint 0x10retmsg2:.byte 13,10.ascii "Now we are in SETUP".byte 13,10,13,10msg_cursor:.byte 13,10.ascii "Cursor position:"msg_memory:.byte 13,10.ascii "Memory Size:"msg_cyles:.byte 13,10.ascii "Cyles:"msg_heads:.byte 13,10.ascii "Heads:"msg_sectors:.byte 13,10.ascii "Sectors:"msg_kb:.ascii "KB".org 510
boot_flag:.word 0xAA55
2.调试
在oslab目录下 ./dbg-asm
3.结果
0x00CC = 12 * 16 + 12 = 204
疑惑点:保存光标的位置时,光标应该在SETUP的末尾,为什么是1600这个位置?0x16是行号,0x00是列号不太合理啊。(补充:这里想错了,光标应该在Now下2行的最左边,因为有2对回车和换行啊,这也就能解释列号是0x00了)
HIT oslab之实验2 操作系统的引导(bootsect.s + setup.s)相关推荐
- 实验1:操作系统的引导
实验1:操作系统的引导 实验的准备工作操作 解压源码用tar -zxvf hit-oslab-linux-20110823.tar.gz 可以使用-C来指定解压路径,tar -zxvf hit-osl ...
- 实验2 操作系统的引导
操作系统的引导 实验目的 熟悉hit-oslab实验环境: 建立对操作系统引导过程的深入认识: 掌握操作系统的基本开发过程: 能对操作系统代码进行简单的控制,揭开操作系统的神秘面纱. 实验内容 此次实 ...
- 哈工大操作系统实验一——操作系统的引导
写在前面 哈尔滨工业大学李治军老师的<操作系统>课程实验,相关资源: 哈工大操作系统实验手册 实验资源与参考 不配环境懒人福利:实验楼 在线课程:操作系统,李治军,哈工大(网易云课堂) 参 ...
- 哈工大-操作系统的引导
操作系统的引导 1. 课程说明 本实验是 操作系统之基础 - 网易云课堂 课程的配套实验,推荐大家进行实验之前先学习相关课程: L2 开始揭开钢琴的盖子 L3 操作系统启动 Tips:点击上方文字中的 ...
- 2021-08-05hit-oslab1操作系统的引导
一.背景知识 1.引导启动程序分为三个部分(bootsect.s / setup.s / head.s) 2.80x86结构的CPU在开机启动后,位于0xFFF0处的ROM-BIOS带电自检,检测和诊 ...
- Liunx操作系统的引导过程(系统操作引导过程,模拟MBR,GRUB故障,root密码遗忘解决,优化启动过程 ,运行级别的分类)
文章目录 Liunx操作系统的引导过程 引导过程 Blos自检 MBR 引导 grub引导菜单(Boot Loader) 内核启动 启动init进程,依据inittab文件设定运行级别 系统初始化进程 ...
- 在Linux系统下初始化COM组件,Linux操作系统的引导和初始化.doc
Linux操作系统的引导和初始化 系统引导和初始化概述 相关代码(引导扇区的程序及其辅助程序,以x86体系为例): \linux-2.4.22\arch\i386\boot\bootsect.S:Li ...
- 九江学院计算机主任黄冬久,陈春生副校长到实验中间调研引导工作
3月13日上午,陈春生副校长来到实验中间调研引导工作.实验中间主任方向明.副主任黄冬久.分析测试中间主任詹寿发以及各职能科室副科级以上干部参加了调研座谈会. 座谈会上,方向明主任先介绍了实验中间重要职 ...
- 计算机病毒引导实验,《计算机病毒》实验一:引导型病毒实验
<计算机病毒与防护技术>课程必做实验的实验报告,内涵完整程序代码.实验一:引导型病毒实验. 实验报告 题目:引导型病毒实验 姓名:王宇航 学号:09283020 实验环境:VMWare W ...
最新文章
- 打造属于自己的underscore系列(五)- 偏函数和函数柯里化
- springboot 添加允许跨域_springboot设置cors跨域请求的两种方式
- It is possible that this issue is resolved by uninstalling an existi
- 导出为Excel例子 java
- C/C++ SQLite 之基础篇
- html5游戏开发-零基础开发RPG游戏-开源讲座(四)
- isupper_Python字符串isupper()
- Redis源码分析系列三:initServerConfig下半部分
- 【MATLAB统计分析与应用100例】案例010:matlab调用normrnd函数生成正态分布随机数
- 手机识别图片文字的方法
- wps使用切片器,解决切片器灰色问题
- IPy模块。。ip范围求交集。。
- 【方向盘】程序人生 | 春风得意马蹄疾,一日看尽长安花
- 【Milvus的以图搜图】
- 1024_scsdn_徽章获取日_日常工作记录_百度图片爬取小程序
- 计算机网络TCP的全称,tcp/ip全称是什么
- win10任务栏图标两个以上不显示缩略图且不显示桌面预览解决方案
- c语言中n的阶乘的流程图,n的阶乘流程图(计算机n的阶乘流程图)
- Android开发之获取通话记录
- php 开源程序_国内PHP开源建站程序一览