30天自制操作系统 pdf_30天自制操作系统:第三天:系统引导完成
对第二天代码进行了修改,只打印hello ,uos没一点意思。
读取磁盘上10个柱面的1-18个扇区,(目前ssd已经没有柱面这个概念了)。读出来的数据放入内存0x8200起始的地方。
启动区放在0x8000内存扇区中。为什么要放在0x8000以后的内存中的呢? 只是因为这块内存没有用而已。
为什么要将启动程序(img的0扇区)放在0x7c00处? 这是ibm规定的。
向一个空软盘保存文件时:
1.文件名会写在0x002600以后的地方。
2.文件内容会写在0x004200以后的地方。
所以若想启动位于0x004200的程序,就得让引导程序运行完成后跳转到0x8000+0x4200=0xc200处。
作者这一块写的很混乱啊,咱们整理一下为啥是0xc200地址,看下图:
bios会把磁盘0位置的内容拷贝到内存0x7c00这个位置然后跳过去执行, 也就是把A拷贝到了内存,然后执行A A会把磁盘后面的内容从内存0x8200开始拷贝 这样的话磁盘0x4200位置就会对应到内存0xC200 一个扇区512字节,十六进制表示就是0x200
程序的执行情况:
1.bios读取磁盘0扇区到0x7c00处。
2.bios跳转到0x7c00处开始执行,该处为ipl10.nas程序,该程序功能为加载磁盘[1-最后]扇区到内存的0x8200处。并跳转到0xc200处执行。
3.0xc200处为asmhead.nas程序,该程序功能为,调用显卡bios,设置画面模式,调用操作系统代码。
4.操作系统代码目前就一个功能就是让cpu睡眠,开始进入c程序。
下面根据功能修改代码:
修改ipl.nas
ipl10.nas:
; haribote-ipl; TAB=4CYLS EQU 10 ; 声明CYLS=10 ORG 0x7c00 ; 指明程序装载地址; 标准FAT12格式软盘专用的代码 Stand FAT12 format floppy code JMP entry DB 0x90 DB "HARIBOTE" ; 启动扇区名称(8字节) DW 512 ; 每个扇区(sector)大小(必须512字节) DB 1 ; 簇(cluster)大小(必须为1个扇区) DW 1 ; FAT起始位置(一般为第一个扇区) DB 2 ; FAT个数(必须为2) DW 224 ; 根目录大小(一般为224项) DW 2880 ; 该磁盘大小(必须为2880扇区1440*1024/512) DB 0xf0 ; 磁盘类型(必须为0xf0) DW 9 ; FAT的长度(必??9扇区) DW 18 ; 一个磁道(track)有几个扇区(必须为18) DW 2 ; 磁头数(必??2) DD 0 ; 不使用分区,必须是0 DD 2880 ; 重写一次磁盘大小 DB 0,0,0x29 ; 意义不明(固定) DD 0xffffffff ; (可能是)卷标号码 DB "HARIBOTEOS " ; 磁盘的名称(必须为11字?,不足填空格) DB "FAT12 " ; 磁盘格式名称(必??8字?,不足填空格) RESB 18 ; 先空出18字节; 程序主体entry: MOV AX,0 ; 初始化寄存器 MOV SS,AX MOV SP,0x7c00 MOV DS,AX; 读取磁盘 MOV AX,0x0820 MOV ES,AX MOV CH,0 ; 柱面0 MOV DH,0 ; 磁头0 MOV CL,2 ; 扇区2readloop: MOV SI,0 ; 记录失败次数寄存器retry: MOV AH,0x02 ; AH=0x02 : 读入磁盘 MOV AL,1 ; 1个扇区 MOV BX,0 MOV DL,0x00 ; A驱动器 INT 0x13 ; 调用磁盘BIOS JNC next ; 没出错则跳转到next ADD SI,1 ; 往SI加1 CMP SI,5 ; 比较SI与5 JAE error ; SI >= 5 跳转到error MOV AH,0x00 MOV DL,0x00 ; A驱动器 INT 0x13 ; 重置驱动器 JMP retrynext: MOV AX,ES ; 把内存地址后移0x200(512/16十六进制转换) ADD AX,0x0020 MOV ES,AX ; ADD ES,0x020因为没有ADD ES,只能通过AX进行 ADD CL,1 ; 往CL里面加1 CMP CL,18 ; 比较CL与18 JBE readloop ; CL <= 18 跳转到readloop MOV CL,1 ADD DH,1 CMP DH,2 JB readloop ; DH < 2 跳转到readloop MOV DH,0 ADD CH,1 CMP CH,CYLS JB readloop ; CH < CYLS 跳转到readloop; 读取完毕,跳转到haribote.sys执行! MOV [0x0ff0],CH ; 记下IPL读到哪里了 JMP 0xc200error: MOV SI,msgputloop: MOV AL,[SI] ADD SI,1 ; 给SI加1 CMP AL,0 JE fin MOV AH,0x0e ; 显示一个文字 MOV BX,15 ; 指定字符颜色 INT 0x10 ; 调用显卡BIOS JMP putloopfin: HLT ; 让CPU停止,等待指令 JMP fin ; 无限循环msg: DB 0x0a, 0x0a ; 换行两次 DB "load error" DB 0x0a ; 换行 DB 0 RESB 0x7dfe-$ ; 填写0x00直到0x001fe DB 0x55, 0xaa
我们在使用段寄存器时,以ES:BX这种方式表示地址,写成"MOV AL, [ES:BX]"它代表ES×16+BX内存地址。
2.修改asmhead.nas
; haribote-os boot asm; TAB=4;一些定义BOTPAK EQU 0x00280000 ; bootpack�̃��[�h��DSKCAC EQU 0x00100000 ; �f�B�X�N�L���b�V���̏ꏊDSKCAC0 EQU 0x00008000 ; �f�B�X�N�L���b�V���̏ꏊ�i���A�����[�h�j; 有关BOOT_INFOCYLS EQU 0x0ff0 ; 设定启动区LEDS EQU 0x0ff1VMODE EQU 0x0ff2 ; 该位置保存颜色数目的信息,颜色的位数。SCRNX EQU 0x0ff4 ; 该位置保存 分辨率的xSCRNY EQU 0x0ff6 ; 该位置保存 分辨率的yVRAM EQU 0x0ff8 ; 图像缓冲区的开始地址。 ORG 0xc200 ; 这个程序需要装载到内存的什么地方呢。; 画面设定 MOV AL,0x13 ; VGA显卡,320*320*8位彩色,调色板模式。 MOV AH,0x00 INT 0x10 ;调用显卡bios的函数,切换显示模式。 MOV BYTE [VMODE],8 ; 将画面模式信息保存到这些内存地址中。 MOV WORD [SCRNX],320 MOV WORD [SCRNY],200 MOV DWORD [VRAM],0x000a0000 ;VRAM指的时显卡内存,也就是用来显示画面的内存。这一块内存地址都对应着画面上的像素。;VRAM在0xa0000~0xaffff之间的64kb。 VRAM分布在内存分布图中的好几个不同的地方。; 用bios取得键盘上各种led灯的状态。 MOV AH,0x02 INT 0x16 ; keyboard BIOS MOV [LEDS],AL;=====================================后边的留以后再看,这块时调用bootpack.c程序的======================; 防止PIC接受所有中断; AT兼容机的规范、PIC初始化; 然后之前在CLI不做任何事就挂起; PIC在同意后初始化 MOV AL,0xff OUT 0x21,AL NOP ; ; 不断执行OUT指令 OUT 0xa1,AL CLI ;进一步中断CPU; ; 让CPU支持1M以上内存、设置A20GATE CALL waitkbdout MOV AL,0xd1 OUT 0x64,AL CALL waitkbdout MOV AL,0xdf ; enable A20 OUT 0x60,AL CALL waitkbdout; 保护模式转换[INSTRSET "i486p"] ; 说明使用486指令 LGDT [GDTR0] ;设置临时GDT MOV EAX,CR0 AND EAX,0x7fffffff ; 使用bit31(禁用分页) OR EAX,0x00000001 ; bit0到1转换(保护模式过渡) MOV CR0,EAX JMP pipelineflushpipelineflush: MOV AX,1*8 ; 写32bit的段 MOV DS,AX MOV ES,AX MOV FS,AX MOV GS,AX MOV SS,AX;bootpack传递 MOV ESI,bootpack ; 源 MOV EDI,BOTPAK ; 目标 MOV ECX,512*1024/4 CALL memcpy; 传输磁盘数据; 从引导区开始 MOV ESI,0x7c00 ; 源 MOV EDI,DSKCAC ; 目标 MOV ECX,512/4 CALL memcpy; 剩余的全部 MOV ESI,DSKCAC0+512 ; 源 MOV EDI,DSKCAC+512 ; 目标 MOV ECX,0 MOV CL,BYTE [CYLS] IMUL ECX,512*18*2/4 ; 除以4得到字节数 SUB ECX,512/4 ; IPL偏移量 CALL memcpy; 由于还需要asmhead才能完成; 完成其余的bootpack任务; bootpack启动 MOV EBX,BOTPAK MOV ECX,[EBX+16] ADD ECX,3 ; ECX += 3; SHR ECX,2 ; ECX /= 4; JZ skip ; 传输完成 MOV ESI,[EBX+20] ; 源 ADD ESI,EBX MOV EDI,[EBX+12] ; 目标 CALL memcpyskip: MOV ESP,[EBX+12] ; 堆栈的初始化 JMP DWORD 2*8:0x0000001bwaitkbdout: IN AL,0x64 AND AL,0x02 JNZ waitkbdout ; AND结果不为0跳转到waitkbdout RETmemcpy: MOV EAX,[ESI] ADD ESI,4 MOV [EDI],EAX ADD EDI,4 SUB ECX,1 JNZ memcpy ; 运算结果不为0跳转到memcpy RET; memcpy地址前缀大小 ALIGNB 16GDT0: RESB 8 ; 初始值 DW 0xffff,0x0000,0x9200,0x00cf ; 写32bit位段寄存器 DW 0xffff,0x0000,0x9a28,0x0047 ; 可执行的文件的32bit寄存器(bootpack用) DW 0GDTR0: DW 8*3-1 DD GDT0 ALIGNB 16bootpack:
3.加入bootpack.c操作系统代码
这个操作系统实现了一个最简单的功能:让cpu睡眠
void io_hlt(void);void HariMain(void){fin: io_hlt(); /* 执行naskfunc.nas里边的_io_hlt()函数。 */ goto fin;}
4.加入naskfunc.nas
加入这个文件是因为c程序不能调用HLT指令,所以使用c程序调用汇编程序,在汇编程序中用HLT让cpu睡眠。
; naskfunc; TAB=4[FORMAT "WCOFF"] ; 制作目标文件的模式 [BITS 32] ; 制作32位模式用的机器语言; 制作目标文件的信息。[FILE "naskfunc.nas"] ; 源文件名信息 GLOBAL _io_hlt ; 程序中包含的函数名;实际的函数[SECTION .text] ;目标中间中写了这些之后再写程序_io_hlt: ; void io_hlt(void); 这个函数只执行了一个HLT命令,让cpu睡眠。 HLT RET
5.运行结果
本地代码下载:https://download.csdn.net/download/u011164819/12981508
30天自制操作系统 pdf_30天自制操作系统:第三天:系统引导完成相关推荐
- 30天自制操作系统 pdf_30天自制操作系统:第四天:系统界面绘制
第四天: OUT:让cpu给设备发送电信号. IN:让cpu从设备获取电信号. 为了区别不同的设备,要使用设备号码,用port表示. pushad: 将所有的32位通用寄存器压入堆栈 pusha:将所 ...
- [笔记]深入解析Windows操作系统《三》系统机制
文章目录 前言 第三章 系统机制 3.1 陷阱分发 实验:将系统调用号映射到函数和参数 实验:查看系统服务的行为 选择"System"对象,再选择"System Call ...
- 操作系统精讲(0) | 操作系统详细简介
操作系统(英语:Operating System,缩写:OS)是一组主管并控制计算机操作.运用和运行硬件.软件资源和提供公共服务来组织用户交互的相互关联的系统软件程序,同时也是计算机系统的内核与基石. ...
- linux操作系统 第09章 操作系统接口
第9章 操作系统接口 ( 好多人看这篇博客,应该是为了 9.1.2 操作系统的接口 那段描述吧,不知道是不是你们想要的答案 ... ... ) 9.1 操作系统接口概述 9.1.1 作业与作业 ...
- 了解操作系统,什么是操作系统Operation System?
1.操作系统(Operation System,oS):是一个特殊的软件. 操作系统作为接口的示意图 1.没有安装操作系统的计算机,通常被称为裸机. 2.如果想在裸机上运行自己所编写的程序,就必须用机 ...
- 麒麟操作系统基于linux哪个版本_linux操作系统排行_桌面操作系统难在哪?国产麒麟系统应用仅为Windows十...
桌面操作系统难在哪?国产麒麟系统应用仅为Windows十万分之一 10平台上差不多有70完款应用软件,而中标麒麟桌面操作系统只有8款,只有Windows平台的十万分之一左右. 公平地说,中标麒麟是基于 ...
- 深度操作系统和鸿蒙操作系统,深度操作系统与华为鸿蒙操作系统,都是操作系统,有什么不联系和区别?...
华为推出的鸿蒙系统是基于Linux内核的,采用了微内核的架构,相比Android系统更加轻巧,可以适配PC.手机.智能穿戴设备.车载设备等,面向下一代网络的操作系统.华为的鸿蒙系统的祖先是UNIX操作 ...
- 数据服务器 操作系统,服务器如何选择操作系统
因为对windows系统比较熟悉,加上操作简单.管理方便,所以与Linux相比,得到了更多服务器客户的青睐,但是windows系统又分为多个版本,甚至每个版本又分为32位和64位,那么,我们该怎么选择 ...
- 在Windows操作系统下,由操作系统分配的内存就叫做堆
堆(Heap) 上面的工作是编译器做的,即程序员并不参与堆栈的维护.但上面已经说了,堆栈相当于在编译时期分配内存,因此一旦计算好某块内存的偏移,则这块内存就只能那么大,不能变化了(如果变化会导致其他内 ...
最新文章
- 什么?我要对AI礼貌?人机交互面临的道德漏洞
- 微信小程序数据拼接_微信小程序用户数据解密算法Java版
- NYOJ 641 摧毁网络
- Android 应用程序消息处理机制(Looper、Handler)分析
- 苹果新手机软件测试,苹果即将发布iOS 14.5正式版,测试工作已进入最后阶段
- Effective Java 英文 第二版 读书笔记 Item 14:In public classes,use accessor methods,not public fields...
- ActiveX控件打包成Cab置于网页中自动下载安装
- 快狗打车通过港交所上市聆讯
- 在linux下挂载ios镜像文件,linux下挂载iso镜像文件
- mysql workbench修改密码_更改MySQL用户密码
- 中兴java笔试_最新中兴Java语言笔试真题及答案
- win7搜索网络计算机文件,Win7查找局域网共享文件的方法
- 标准差 php,标准偏差怎么计算
- 测试小兵成长记:中庸之道
- 再来学习一下RT-Thread的软件架构 | 文末赠书5本《软件架构实践》
- 安卓获取string.xml文件里的值
- Mac快捷键大全及cheatsheet插件
- php 活动网站,网页游戏的活动管理后台和管理后台
- 你是胡萝卜,是鸡蛋,还是咖啡豆
- 数字经济的压舱石、国家安全的新维度 --《数据安全法(草案)》之解读
热门文章
- 阿里云MVP乔帮主:五大类型负载均衡的原理场景详解(文末赠书)
- Vue、element-ui的resetFields()方法重置表单无效问题及解决办法
- su 切换,提示:“密码不正确”;
- 数据中台赋能企业数字化转型的四个关键成功因素
- JavaScript验证正则表达式大全
- JAVA编程多线程面试常见知识点灵魂拷问(一)
- Windows 10 LTSB 还原默认照片查看器
- 1073. Pearls
- 斯特林数 java实现_斯特林数学习笔记
- ZZULIOJ 1095: 时间间隔(多实例测试)