前言

今天本来的任务看书和把之前写的FragileOS整理一下,但是到现在还在摸鱼,书也只看一点。后来整理了一下写这个系列的思路,原本的目的是对操作系统原理性的学习和对之前写的一个玩具型操作系统的回顾,就是想对操作系统的知识的轮廓能有一个了解,现在想来想减少对之前写的系统的回顾,毕竟也只有2000多行,但是还是要有对整个思路的展现。然后增加对Linux 0.12源码的一些学习。所以离标题可能比较远了一点,但是就这样吧

什么是操作系统

原本这一节是写计算机系统和操作系统概述的,但是写到一半觉得太水就删了。就总结几句,后面用到什么就补什么。计算机系统的概述应该属于计算机组成原理的内容,这俩部分也是《操作系统:精髓和设计原理》的第一二章。但是觉得如果对于想学习操作系统内部的代码的话,换成汇编的内容会更好。

进入正题,操作系统是什么

对于计算机来说最根本的运行方式,就是取指执行

对于在屏幕上输出Hello,World!的过程,首先CPU拿到内存中的指令,这些指令是通知CPU把存在某个内存中的'H''E''L'等移动到显存位置,这样在屏幕上就可以看到这些字符了。这就是计算机最原始的运行方式

而操作系统就是对硬件层面的抽象,让我们不用在直面硬件,如果想要再次在屏幕输出字符,只要直接调用操作系统的write(windows下的好像是这个名),C语言中的printf下就是一个系统调用

当然操作系统绝对是比想象中的庞大的多,操作系统还对内存、终端、磁盘、网络和文件等等进行管理,光windows 2000应该就有3000多万行的代码了。当然有简陋的内存、进程管理和文件系统的玩具型内核,只要几千行代码就可以完成了。

操作系统的启动

对于X86架构的计算机,开机时一共做这几件事

  • 开机时的CS = 0xFFFF, IP = 0x0000

    这时候的CPU处理实模式,也就是寻址的方式是CS:IP (实模式和保护模式属于CPU的工作模式,其中比较大的区别就是寻址的方式)

  • 寻址0xFFFF0

  • 检查硬件设备,像键盘显示器之类的

  • 将磁盘0磁道0扇区读入0x7c00处

    会从这里读入512字节,也就是传说中的引导程序,这里放着计算机执行的第一段代码

  • 设置cs = 0x7c00 ip = 0x0000

FragileOS/boot

这个是我之前写的FragileOS的boot,采用的是Intel汇编格式

主要的逻辑就是:

  • 先加载到0x7c00位置
  • 进行初始化操作
  • 调用CPU提供的中断来读取数据
  • 读取完毕后直接跳到内核的起始位置,也就是引导结束了

(部分代码)

org  0x7c00;                                ;加载到内存0x7c00处

LoadAddr EQU  08000h                        ;内核的内存地址
BufferAddr EQU 7E0h ;读取扇区的时候进行的缓存 BaseOfStack EQU 07c00h entry:
mov ax, 0 ;进行寄存器的初始化操作
mov ss, ax
mov ds, ax mov ax, BufferAddr
mov es, ax ;ES:BX 数据存储缓冲区,指示扇区加载后放置的地址 mov ax, 0
mov ss, ax
mov sp, BaseOfStack
mov di, ax
mov si, ax mov BX, 0 ;ES:BX 数据存储缓冲区
mov CH, 1 ;CH 用来存储柱面号
mov DH, 0 ;DH 用来存储磁头号
mov CL, 0 ;CL 用来存储扇区号 read_floppy: ;每次都把扇区写入缓存地址07E00处
cmp byte [load_count], 0 ;比较load_count地址处的值,如果=0就跳转到begin_load
je begin_load mov bx, 0
inc CL
mov AH, 0x02 ;AH = 02 表示要做的是读盘操作
mov AL, 1 ;AL 表示要练习读取几个扇区
mov DL, 0 ;驱动器编号,一般我们只有一个软盘驱动器,所以写死 int 0x13 ;调用BIOS中断实现磁盘读取功能
jc fin

Linux 0.12/boot

Linux 0.12的boot自然比上面的复杂的多,Linux采用的boot的汇编是as86格式的,其余的汇编采用的都是AT&T

Linux 0.12下的boot一共有三个文件:

  • bootsect
  • head
  • setup

(代码太长不全部贴了,有需要的可以私信我)

bootsect

bootsect的主要作用就是把自己移动到0x90000处执行,然后再加载setup模块 (也就是setup.s)到bootsect的后面,再把system模块加载到0x10000处,这个也就是内核的主要部分

bootsect的开头是一些常量的定义

SETUPLEN = 4				  ! nr of setup-sectors
BOOTSEG = 0x07c0 ! original address of boot-sector
INITSEG = 0x9000 ! we move boot here - out of the way
SETUPSEG = 0x9020 ! setup starts here
SYSSEG = 0x1000 ! system loaded at 0x10000 (65536).
ENDSEG = SYSSEG + SYSSIZE ! where to stop loading
  • _start先设置好目的地址和源地址

    ds:si和es:di

  • 然后执行rep指令

    rep指令是重复的意思,它以cx寄存器的值为判断,如果cx的值为0就停止

  • movw指令

    开始从[si]处移动cx个字到[di]处,这里也就是一共移动了256个字,512字节

  • 最后跳转到0x9000开始执行

_start:
mov ax,#BOOTSEG
mov ds,ax
mov ax,#INITSEG
mov es,ax
mov cx,#256
sub si,si
sub di,di
rep
movw
jmpi go,INITSEG
  • 现在的这些代码都是在0x90000后的
  • 先重新设置段寄存器和栈指针
go:	mov	ax,cs
mov ds,ax
mov es,ax
! put stack at 0x9ff00.
mov ss,ax
mov sp,#0xFF00 ! arbitrary value >>512
  • 这一部分和我之前的一样,就是调用中断来读取磁盘内容,只是Linux读取的是在第二扇区的setup模块

  • 如果失败就重新设置驱动器然后跳回重新读取

  • 成功就跳到ok_load_setup

  • ok_load_setup是设置根文件系统设备的,并且读入SYSTEM模块 (内核的主要部分)到0x10000处,结尾是跳到SETUP模块

load_setup:
mov dx,#0x0000 ! drive 0, head 0
mov cx,#0x0002 ! sector 2, track 0
mov bx,#0x0200 ! address = 512, in INITSEG
mov ax,#0x0200+SETUPLEN ! service 2, nr of sectors
int 0x13 ! read it
jnc ok_load_setup ! ok - continue
mov dx,#0x0000
mov ax,#0x0000 ! reset the diskette
int 0x13
j load_setup

小结

一个简单的boot引导程序,顾名思义就是把做一些引导工作的,进行一些初始化设置再读入真正的内核部分,进入OS。

其实Linux 0.12一个完整的boot应该还包括setup.s用来完成OS启动前最后的设置 (进入保护模式等),head.s则是进入之后的设置。但是因为这两部分包含了一些其它重要概念,所以打算再下一篇写。

我是如何学习写一个操作系统(二):操作系统的启动之Bootloader的更多相关文章

  1. 自制 os 极简教程1:写一个操作系统有多难

    为什么叫极简教程呢?听我慢慢说 不知道正在阅读本文的你,是否是因为想自己动手写一个操作系统.我觉得可能每个程序员都有个操作系统梦,或许是想亲自动手写出来一个,或许是想彻底吃透操作系统的知识.不论是为了 ...

  2. spring boot开发,jar包一个一个来启动太麻烦了,写一个bat文件一键启动

    spring boot开发,jar包一个一个来启动太麻烦了,写一个bat文件一键启动 @echo offcd D:\workProject\bushustart cmd /c "title ...

  3. Linux内核学习--写一个c程序,并在内核中编译,运行

    20140506 今天开始学习伟大的开源代表作:Linux内核.之前的工作流于几个简单命令的应用,因着对Android操作系统的情愫,“忍不住”跟随陈利君老师的步伐,开启OS内核之旅.学习路径之一是直 ...

  4. Android学习--写一个发送短信的apk,注意布局文件的处理过程!!!

    刚开始写Android程序如图发现使用了findViewById方法之后输出的话居然是null(空指针错误),也就是说这个方法没有成功.网上说这样写是在activity_main .xml去找这个ID ...

  5. Qt 利用XML文档,写一个程序集合 二

    接上一篇文章https://www.cnblogs.com/DreamDog/p/9213915.html XML文档的读写 一个根节点,下面每一个子节点代表一个子程序,内容为子程序名字,图标路径,e ...

  6. 一个人写的操作系统 - Sparrow OS

    一个人写的操作系统 - Sparrow OS 自己写一个操作系统,这是在过去的几年里我一直为之努力的目标,现在终于完成了. 缘起 自己动手写操作系统的动机最初来自于学习Linux遇到的困难. 我是一个 ...

  7. 一起学习造轮子(二):从零开始写一个Redux

    本文是一起学习造轮子系列的第二篇,本篇我们将从零开始写一个小巧完整的Redux,本系列文章将会选取一些前端比较经典的轮子进行源码分析,并且从零开始逐步实现,本系列将会学习Promises/A+,Red ...

  8. React学习及实例开发(二)——用Ant Design写一个简单页面

    本文基于React v16.4.1 初学react,有理解不对的地方,欢迎批评指正^_^ 一.引入Ant Design 1.安装antd yarn add antd 2.引入 react-app-re ...

  9. WCF入门教程(四)通过Host代码方式来承载服务 一个WCF使用TCP协议进行通协的例子 jquery ajax调用WCF,采用System.ServiceModel.WebHttpBinding System.ServiceModel.WSHttpBinding协议 学习WCF笔记之二 无废话WCF入门教程一[什么是WCF]

    WCF入门教程(四)通过Host代码方式来承载服务 Posted on 2014-05-15 13:03 停留的风 阅读(7681) 评论(0) 编辑 收藏 WCF入门教程(四)通过Host代码方式来 ...

随机推荐

  1. 洛谷P2285 【[HNOI2004]打鼹鼠】

    每次打鼹鼠的机器人总是从某一次打鼹鼠的地方走过来的 对鼹鼠出现时间从小到大排序 f[i]表示到第i个鼹鼠(打第i个)最多能打多少个鼹鼠 f[i]=max(f[j]+1)f[i]=max(f[j]+1) ...

  2. python,看看有没有你需要的列表元祖和range知识!

    列表--list 列表:列表是python的基础数据类型之一,存储多种数据类型 可变 支持索引 可切片 方便取值 li = ['alex',123,Ture,(1,2,3,'wusir'),[1,2, ...

  3. 个人永久性免费-Excel催化剂功能第23波-非同一般地批量拆分工作表

    工作薄的合并,许多Excel插件已有提供,Excel催化剂也提供了最佳的解决方案,另外还有工作薄的拆分和工作表的拆分,同样也是各大插件必备功能. 至于工作薄拆分,那是伪需求,Excel催化剂永远只会带 ...

  4. spring applicationContext.xml文件移到resources目录下

    SpringMVC的框架默认目录结构 修改后的目录结构及web.xml 同时在pom里的配置:将resources目录打包到web-inf/classes目录下<resources>   ...

  5. Java集合 HashSet的原理及常用方法

    目录 一. HashSet概述 二. HashSet构造 三. add方法 四. remove方法 五. 遍历 六. 合计合计 先看一下LinkedHashSet 在看一下TreeSet 七. 总结 ...

  6. 算法与数据结构基础 - 广度优先搜索(BFS)

    BFS基础 广度优先搜索(Breadth First Search)用于按离始节点距离.由近到远渐次访问图的节点,可视化BFS 通常使用队列(queue)结构模拟BFS过程,关于queue见:算法与数 ...

  7. rem的基准字体大小的设置

    1.移动端 UI 给的设计稿通常是640px.720px.750px的宽度,但是我们要做适配,兼容不同的终端,rem布局是比较常用的一种方式,比较关键的是确定根节点的字体大小. 这里以640px为例, ...

  8. TCP传输协议如何进行拥塞控制?

    拥塞控制 拥塞现象是指到达通信子网中某一部分的分组数量过多,使得该部分网络来不及处理,以致引起这部分乃至整个网络性能下降的现象,严重时甚至会导致网络通信业务陷入停顿,即出现死锁现象.这种现象跟公路网中 ...

  9. Something wrong with EnCase v8 index search results

    My friend told me that she installed EnCase v8.05 on her workstation which OS version is Win 10. She ...

  10. PHP后门***详解

    说起php后门***我就心有愉季啊前不久一个站就因不小心给人注入了然后写入了小***这样结果大家知道的我就不说了下面我来给大家收集了各种php后门***做法大家可参考. php后门***对大家来说一点 ...