OS操作系统初始化过程
前面两篇文章已经分别讲了OS的实验环境配置及x86汇编的指令,本文则着重于讲解操作系统的初始化。
BIOS
8086可以访问1MB的内存空间,地址从0x00000
到0xFFFFF
,顶端一部分用于访问ROM和外围板卡,其他大部分则用来访问内存DRAM。
- ROM-BIOS占据着整个内存空间顶端的64KB,物理地址范围是0xF0000-0xFFFFF,里面固化了开机时要执行的指令
- 内存条DRAM占据着较低端的640KB,地址范围是0x00000-0x9FFFF
- 中间还有一部分,地址范围是0xA0000-0xEFFFF(320KB),则分给了其他外围设备,如显卡
因为8086加电或者复位时,CS=0xFFFF
,IP=0x0000
,所以,它取的第一条指令位于物理地址0xFFFF0
(也即FFFF:0000
),正好位于 ROM中,那里固化了开机时需要执行的指令。
这块ROM芯片中的内容包括很多部分,主要是进行硬件的诊断、检测和初始化。
所谓初始化,就是让硬件处于一个正常的、默认的工作状态。
最后,它还负责提供一套软件例程,让人们在不必了解硬件细节的情况下从外围设备(比如键盘)获取输入数据,或者向外围设备(比如显示器)输出数据。
设备当然是很多的,所以这块 ROM 芯片只针对那些最基本的、对于使用计算机而言最重要的设备,而它所提供的软件例程,也只包含最基本、最常规的功能。
正因为如此,这块芯片又叫基本输入输出系统(Base Input & Output System, BIOS) ROM
ROM-BIOS的容量是有限的,当它完成自己的使命后,最后所要做的,就是从辅助存储设备读取指令数据,然后转到那里开始执行。
绝大多数时候,对于 ROM-BIOS 来说,硬盘都是首选的外存储设备。
硬盘的第一个扇区是0面0道1扇区,或者说是0头0柱1扇区(512B),这个扇区称为主引导扇区bootsector。
整个加载操作系统的过程如下
- 搜索可用的存储媒介,如软盘(floppy disk)、硬盘、CD等
- 检查每个引导盘的有效性:最后一个字必须为
0x55aa
才为有效的引导盘(注意这里在汇编程序中体现为
org 7c00h
。非常重要!否则无法正确读取代码段/数据段!) - 如果有效,则第一个扇区,即主引导程序(master boot record, MBR),将会被加载入RAM地址为
0000:7C00
的地方(也就是物理地址 0x07C00,自举bootstrap),BIOS跳转到7C00
继续执行 - OS应该被加载入RAM,或者是另外一个引导程序
注:C中直接访问绝对地址
int*var=(int*)0x40001000;*var=4;
显存
概述
显存,即显示存储器(Video RAM, VRAM)。
要显示的内容都需要先写入显存,显存同样是按字节访问的存储期间。
两种基本工作模式
- 图形模式:每个像素用01控制
- 文本模式:直接用ASCII码控制显示字符的形状
由于历史的原因,所有在个人计算机上使用的显卡,在加电自检之后都会把自己初始化到80*25 的文本模式。在这种模式下,屏幕上可以显示25行,每行80个字符,每屏总共2000个字符。
所以,0xB8000-0xBFFFF
这段物理地址空间,是留给显卡的,由显卡来提供,用来显示文本。
除非显卡出了毛病,否则这段空间总是可以访问的。
如果显卡出了毛病,计算机一定不会通过加电自检过程,这就是传说中的严重错误,计算机是无法启动的,更不要说加载并执行主引导扇区的内容了。
因此要访问显存,段寄存器要先指向0xB800
,然后设置好偏移量,将对应的字符和显示属性放入该内存地址中。
80*25文本模式颜色表
屏幕上的每个字符都对应着显存中连续两个字节,前一字节是字符的ASCII码,后一字节是字符的显示属性。
字符的显示属性分为两部分,低4位定义的是前景色,高4位定义的是背景色。K=0时不闪烁,K=1时闪烁。
R | G | B | 背景色 | 前景色(I=0) | 前景色(I=1) |
---|---|---|---|---|---|
0 | 0 | 0 | 黑 | 黑 | 灰 |
0 | 0 | 1 | 蓝 | 蓝 | 浅蓝 |
0 | 1 | 0 | 绿 | 绿 | 浅绿 |
0 | 1 | 1 | 青 | 青 | 浅青 |
1 | 0 | 0 | 红 | 红 | 浅红 |
1 | 0 | 1 | 品红 | 品红 | 浅品红 |
1 | 1 | 0 | 棕 | 棕 | 黄 |
1 | 1 | 1 | 白 | 白 | 亮白 |
即连续两个字节为(ASCII)(KRGB)(IRGB),如0000 0000 0000 0101
代表黑底(背景)品红字(前景)ASCII码为0x00
的字符。
软盘
通常一个扇区尺寸是512B,可以看成是一个数据块(block)。
1440KB=1474560B,1B=8b等同于两个hex位。
1.44M的软盘一共包含2880个扇区。
采用磁头、磁道和扇区这种模式来访问硬盘的方法称为CHS模式,但不是很方便。
后来引入了逻辑块地址(Logical Block Address, LBA)的概念。
现在市场上销售的硬盘,无论是哪个厂家生产的,都支持LBA模式。
LBA模式是由硬盘控制器在硬件一级上提供支持,所以效率很高,兼容性很好。
LBA模式不考虑扇区的物理位置(磁头号、磁道号),而是把它们全部组织起来统一编号。
在这种编址方式下,原先的物理扇区被组织成逻辑扇区,且都有唯一的逻辑扇区号。
软盘有2个磁头(head)/面(side),有80个柱面(cylinder),每一个道(track)18个扇区(sector)。
柱面和磁头从0开始计数,扇区从1开始计数。
#define FLOPPY_144_SECTORS_PER_TRACK 18voidlba_2_chs(uint32_tlba,uint16_t*cyl,uint16_t*head,uint16_t*sector)
{
*cyl=lba/(2*FLOPPY_144_SECTORS_PER_TRACK);
*head=((lba%(2*FLOPPY_144_SECTORS_PER_TRACK))/FLOPPY_144_SECTORS_PER_TRACK);
*sector=((lba%(2*FLOPPY_144_SECTORS_PER_TRACK))%FLOPPY_144_SECTORS_PER_TRACK+1);
}
DOS
磁盘操作系统(Disk Operating System, DOS)主要有五部分组成
- 引导程序(BOOT):由格式化程序直接写入磁盘初始扇区
- 基本输入/输出管理程序(PC-DOS为IBMBIO.COM、MS-DOS为IO.SYS)
- 文件管理和系统功能调用程序(PC-DOS为IBMDOS.COM、MS-DOS为MSDOS.SYS)
- 命令处理程序(COMMAND.COM)
- 各种外部命令:完成各种辅助功能的可执行文件
参考资料
完整开发
- 李忠,《x86汇编语言-从实模式到保护模式》
- The little book about OS development, https://littleosbook.github.io/, https://littleosbook.github.io/book.pdf
- Writing a Simple Operating System from Scratch, https://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf
- Arjunsreedharan, https://arjunsreedharan.org/
- OS开发参考目录,https://nithinbekal.com/notes/os/
- Writing Your Own Toy Operating System: Guides & Tutorials, http://www.independent-software.com/operating-system-development.html
- Bona fide OS Developer, http://www.osdever.net/tutorials/
- CMSC 412, https://www.cs.umd.edu/~hollings/cs412/s02/
- Linux内核参考文档,https://www.kernel.org/doc/html/latest/index.html
- Linux开发,https://0xax.gitbooks.io/linux-insides/
- os-dev, https://wiki.osdev.org/Main_Page
- Linux指令,https://linux.die.net/man/
- C标准头文件(FreeBSD实现)
内核启动
- Bootloaders(Wiki), https://en.wikibooks.org/wiki/X86_Assembly/Bootloaders
- Booting an Operating System, https://www.cs.rutgers.edu/~pxk/416/notes/02-boot.html
- 内核代号101 — 动手写自己的内核,https://linux.cn/article-2926-1.html
- Linux 内核加载启动过程分析, https://woshijpf.github.io/%E5%86%85%E6%A0%B8/2017/06/26/Linux-%E5%86%85%E6%A0%B8%E5%8A%A0%E8%BD%BD%E5%90%AF%E5%8A%A8%E8%BF%87%E7%A8%8B%E5%88%86%E6%9E%90.html
- 32位引导程序,http://3zanders.co.uk/2017/10/16/writing-a-bootloader2/
- Create Your Own Kernel In C, https://www.codeproject.com/Articles/1225196/Create-Your-Own-Kernel-In-C
- Making your own Linux Shell in C, https://www.geeksforgeeks.org/making-linux-shell-c/(C内核字符串处理)
链接
- Linker Script初探 - GNU Linker Ld手冊略讀,http://wen00072.github.io/blog/2014/03/14/study-on-the-linker-script/
- 10分钟读懂linker scripts, https://blog.louie.lu/2016/11/06/10%E5%88%86%E9%90%98%E8%AE%80%E6%87%82-linker-scripts/
- ld官方文档,https://sourceware.org/binutils/docs/ld/
- Beginner’s Guide to Linkers,https://www.lurklurk.org/linkers/linkers.html
- x86_64_ldscripts, https://dev.haiku-os.org/attachment/ticket/6308/x86_64_ldscripts.txt
- Linker Scripts, http://www.scoberlin.de/content/media/http/informatik/gcc_docs/ld_3.html
工具
- Debugging and Building Operating Systems, https://www.codeproject.com/Articles/16582/Debugging-and-Building-Operating-Systems, Boches
- 16位编译器(OpenWatcom), http://www.openwatcom.org/doc.php
表单
- Scan code, http://stanislavs.org/helppc/scan_codes.html
- Interrupts (BIOS/DOS), https://jbwyatt.com/253/emu/8086_bios_and_dos_interrupts.html
其他
- 磁盘组织,https://wiki.osdev.org/Floppy_Disk_Controller
- Basic x86 interrupts, https://alex.dzyoba.com/blog/os-interrupts/
- 键盘中断,http://inglorion.net/documents/tutorials/x86ostut/keyboard/
以上是 OS操作系统初始化过程 的全部内容, 来源链接: utcz.com/a/127448.html