手写操作系统--主引导扇区以及内核加载器

news2024/11/27 8:21:01

在CPU上电后,会自动将cs:ip置为f000:fff0,下图就是一个计算机刚上电的模拟:

 ffff00这里开始的代码是BIOS自检,检查计算机的硬件完备性,做完这一切后将第一个扇区的内容复制到0x7c00的位置,并从0x7c00位置执行代码:

 0x7c00开始就放着我们的主引导扇区的代码。因为我的第一句代码是mov ax,0x0003,是占用3个字节,因此实际代码将会从0x7c02开始。

因此我们能接触的第一个操作系统代码就是编写这个主引导扇区。主引导扇区的功能主要是要将内核加载器加载到内存中。因此我们此次实验就模拟一个内核加载器,内核加载器的功能我们将慢慢完善。

;boot.asm

[org 0x7c00]   ;告诉编译器代码从0x7c00位置开始
xchg bx,bx
mov ax, 3           ;清空屏幕
int 0x10

; 初始化段寄存器
mov ax, 0
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7c00

mov si, booting
call print

mov edi, 0x1000; 读取的目标内存
mov ecx, 2; 起始扇区
mov bl, 4; 扇区数量

call read_disk

cmp word [0x1000], 0x55aa
jnz error

jmp 0:0x1002  ; 没问题则跳转到内核加载器

; 阻塞
jmp $

read_disk:

    ; 设置读写扇区的数量
    mov dx, 0x1f2
    mov al, bl
    out dx, al

    inc dx; 0x1f3
    mov al, cl; 起始扇区的前八位
    out dx, al

    inc dx; 0x1f4
    shr ecx, 8
    mov al, cl; 起始扇区的中八位
    out dx, al

    inc dx; 0x1f5
    shr ecx, 8
    mov al, cl; 起始扇区的高八位
    out dx, al

    inc dx; 0x1f6
    shr ecx, 8
    and cl, 0b1111; 将高四位置为 0

    mov al, 0b1110_0000;
    or al, cl
    out dx, al; 主盘 - LBA 模式

    inc dx; 0x1f7
    mov al, 0x20; 读硬盘
    out dx, al

    xor ecx, ecx; 将 ecx 清空
    mov cl, bl; 得到读写扇区的数量

    .read:
        push cx; 保存 cx
        call .waits; 等待数据准备完毕
        call .reads; 读取一个扇区
        pop cx; 恢复 cx
        loop .read

    ret

    .waits:
        mov dx, 0x1f7
        .check:
            in al, dx
            jmp $+2; nop 直接跳转到下一行
            jmp $+2
            jmp $+2
            and al, 0b1000_1000
            cmp al, 0b0000_1000
            jnz .check
        ret

    .reads:
        mov dx, 0x1f0
        mov cx, 256; 一个扇区 256 字
        .readw:
            in ax, dx
            jmp $+2;  ;类似与nop空指令 只不过时钟周期会更长
            jmp $+2
            jmp $+2
            mov [edi], ax
            add edi, 2
            loop .readw
        ret

print:
    mov ah, 0x0e
.next:
    mov al, [si]
    cmp al, 0
    jz .done
    int 0x10
    inc si
    jmp .next

.done:
    ret

booting:
    db "Loading XJC_OS", 10, 13, 0; \n\r

error:
    mov si, .msg
    call print
    hlt; 让 CPU 停止
    jmp $
    .msg db "Booting Error!!!", 10, 13, 0

; 填充 0
times 510 - ($ - $$) db 0

; 主引导扇区的最后两个字节必须是 0x55 0xaa
; dw 0xaa55
db 0x55, 0xaa

上述代码是一个完整的主引导扇区,它主要实现如下功能:

1,清空屏幕

2,在屏幕上输出一句加载内核

3,调用硬盘读写功能,将硬盘中的第二个扇区开始的内核加载器写入内存0x1000的位置

4,校检内核加载器的完备性,如果出现错误则跳转到输出错误语句

5,如果成功将控制权交给内核加载器。

这样主引导扇区的使命就完成了。接下来我们模拟实现一个小型的内核加载器

;loader.asm

[org 0x1000]   ;程序将从0x1000开始执行

dw 0x55aa

mov si,loading
call print1

jmp $

print1:
    mov ah, 0x0e
.next:
    mov al, [si]
    cmp al, 0
    jz .done
    int 0x10
    inc si
    jmp .next
.done:
    ret

loading:
    db "os loading success!!!", 10, 13, 0; \n\r

这个内核加载器并没有实现很多功能,只是模拟主引导扇区是否成功加载内核加载器。如果成功加载将会在屏幕上输出一句“os loading success!!!”。我们编译这个asm看看二进制文件的样子:

 这是编译完的内核加载器的二进制文本,我们去验证一下是否加载到0x1000的内存位置:

屏幕输出了内核加载器的内容,并且确实加载进来了,因此实验成功。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/722186.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第五章 逻辑回归

第五章 逻辑回归 Logistic回归的⼀般过程 收集数据:采⽤任意⽅法收集数据。准备数据:由于需要进⾏距离计算,因此要求数据类型为数值型。另外,结构化数据格式则最佳。分析数据:采⽤任意⽅法对数据进⾏分析。训练算法&…

Golang每日一练(leetDay0118) 扁平化嵌套列表迭代器、整数拆分

目录 341. 扁平化嵌套列表迭代器 Flatten Nested List Iterator 🌟🌟 343. 整数拆分 Integer Break 🌟🌟 🌟 每日一练刷题专栏 🌟 Rust每日一练 专栏 Golang每日一练 专栏 Python每日一练 专栏 C/…

vscode工作区实现机制

工作区是编辑器的重要部分,它承载着编辑器和本地文件的连接,对文件增、删、改、查。下面我会介绍vscode工作区的创建。同样我们知道vscode软件打开的时候没有默认工作区,这里我对它进行了改造,软件启动时指向默认工作区。 工作区目…

提高腾讯QQ(电脑版)语音通话、视频聊天和远程协助的稳定性的方法

一、背景说明 腾讯QQ默认使用的通讯协议是UDP。但是各大运营商将UDP的优先级设置为最低,导致UDP数据包经常被丢弃。导致腾讯QQ在语音通话、视频聊天和远程协助的时候,会出现连接不上、卡顿和断线,非常不稳定。我们可以手动将通讯协议调整为TC…

用Python实现自动化交易:从趋势到收益

在现代金融市场中,自动化交易已经成为越来越流行的一种方式。相比于传统的手工交易方式,自动化交易更加高效、精准、快速且免除了人为因素的影响。而Python作为一种高级编程语言,凭借其简单易学、灵活性强的优势逐渐成为自动化交易中最受欢迎…

Ubuntu下Go语言TCP广播服务器实现

最近在学习Go语言网络编程,突然想到很久以前的用C语言写过的TCP广播聊天程序,然后就用Go尝试写了一遍,在此做个记录。 目录 1.广播结构 2.实现效果 3.源码 4.Go语言学习参考网站 1.广播结构 2.实现效果 服务器: 客户端1&…

小程序 web-view h5页面背景音乐自动播放

/*** 年度账单-登录首页*/ import React,{useEffect} from react import swiper/swiper-bundle.min.css import styles from ./styles.less import bgm from ./bgm2.mp3 // 主体 const annualAccountLoginIndex (props) > {const goAnnualAccount ()>{const {location: …

Java Web Tomcat 23.7.5

Tomcat 1, Tomcat 1.1 简介 1.1.1 什么是Web服务器 Web服务器是一个应用程序(软件),对HTTP协议的操作进行封装,使得程序员不必直接对协议进行操作,让Web开发更加便捷。主要功能是"提供网上信息浏览服务"…

[Python系列] Python虚拟环境Virtualenv

1. 什么是Virtualenv Python virtualenv 是一个用于创建和管理虚拟环境的工具。它可以帮助开发者在不同的项目中使用不同的 Python 版本和包,而不会相互干扰。使用 virtualenv,可以轻松地创建一个独立的 Python 环境,在其中安装所需的包和版本…

【网络】思科网络vlan配置+单臂路由

文章目录 前言一、vlan(虚拟局域网)二、配置vlan配置交换机0配置交换机1(和交换机0相同)配置计算机:测试联通性 三、单臂路由配置R0配置交换机1测试配置: 前言 VLAN(Virtual Local Area Networ…

力扣 491. 递增子序列

题目来源:https://leetcode.cn/problems/non-decreasing-subsequences/description/ 回溯三部曲(来源代码随想录): 递归函数参数:求子序列,很明显一个元素不能重复使用,所以需要startIndex&…

2023年 vue使用腾讯地图搜索、关键字输入提示、地点显示

先看结果 vue 在public文件下的index.html文件中引入&#xff1a; <script src"//map.qq.com/api/js?v2.exp&key你自己的key"></script><script src"https://map.qq.com/api/gljs?v1.exp&librariesservice&key你自己的key"&…

【保姆级教程】PyCharm通过SSH远程连接ModelArts

文章目录 一、创建Notebook二、配置SSH三、配置远程Python解释器四、成果展示 一、创建Notebook 首先&#xff0c;找到云资源下面的 ModelArts&#xff0c;然后点击并进入 ModelArts控制台。 在ModelArts控制台中&#xff0c;点击开发环境下的 Notebook 。然后点击创建&#x…

记录一次Nginx日志偶现499的排查

背景 查看到nginx日志在整点整分的时候频繁出现 499&#xff0c;因为配置了存活检查和就绪检查&#xff0c;担心业务会出现大面积重建导致现网故障&#xff0c;所以对出现499的原因进行排查&#xff0c;记录下排查思路&#xff0c;方便以后查看。 业务链路&#xff1a; 负载均…

B/S版手术麻醉系统源码,基于php、mysql和vue2开发

手术麻醉系统是一套以数字形式与医院信息系统&#xff08;如HIS、EMR、LIS、PACS等&#xff09;和医疗设备等软、硬件集成并获取围手术期相关信息的计算机系统&#xff0c;其核心是对围手术期患者信息自动采集、储存、分析并呈现。该系统通过整合围手术期中病人信息、人员信息、…

Packet Tracer – 研究 NAT 操作

Packet Tracer – 研究 NAT 操作 目标 第 1 部分&#xff1a;通过内联网研究 NAT 操作 第 2 部分&#xff1a;研究互联网中的 NAT 操作 第 3 部分&#xff1a;执行进一步研究 拓扑图 场景 帧通过网络时&#xff0c;MAC 地址可能更改。 当数据包由配置了 NAT 的设备转发时&…

转录组和蛋白组如何关联分析?先从绘制九象限图开始

转录组和蛋白组如何关联分析&#xff1f;先从绘制九象限图开始 五种常用蛋白质组学定量分析方法对比 - 知乎 (zhihu.com) 九象限图在多组学关联分析中非常重要&#xff0c;例如我们可以用九象限图展示“转录组蛋白组”、“转录组翻译组”等关联分析中不同基因的差异表达情况。…

DotNet VOL.Core框架学习使用笔记(二)(持续更新)

2023-7-5 生成代码的列表界面&#xff0c;在数据行里增加一个操作列 查看按钮&#xff0c;打开编辑框&#xff0c;然后让编辑框成为一个只读的查看界面。 页面对应的js文件中增加如下 this.columns.push 函数内容。 按钮的点击事件 重点代码 this.edit(row); 这就是框架里编…

构建工具——webpack、vite

文章目录 构建工具Webpack使用步骤配置文件&#xff08;webpack.config.js&#xff09;插件&#xff08;plugin&#xff09; ViteVite 也是前端的构建工具使用命令构建配置文件&#xff1a;vite.config.js 构建工具 当我们习惯了在 node 中编写代码的方式后&#xff0c;在回到…

page-break-after: always打印时强制分页

page-break-before 元素在指定元素前添加分页符。 <div stylepage-break-after: always;></div> <p stylepage-break-after: always;></p>https://www.runoob.com/cssref/pr-print-pagebb.html