操作系统还原真相阅读笔记(一)——答疑解惑

时间:2022-06-06 20:44:58

说明

1、本书真是好书
2、想到再补充

一、为什么库函数可以调用系统调用

 之前看APUE的时候看到的,exit(库函数)实现实际上还是调用了系统调用sys_exit。按照常理来说,标准C库函数应该具有可移植性,为什么就能调用UNIX系统专用的系统调用呢?C语言编译器也是通用的啊,比如说这个exit函数我在VC下编译能不能通过呢?
 这个问题其实一句话就大概解释清楚了,那就是C语言编译器提供库函数有一部分就是封装过的系统调用。这么说你可能还是有点蒙, 你还记不记得,安装编译器的时候需要选择系统,比如说GCC编译器就不能在windows下运行,VC也不能在Linux下运行。编译器根据不同的系统退出不不同的版本,因为编译器要使用系统的系统调用。

二、物理地址、线性地址、逻辑地址和虚拟地址

 之前我在学习操作系统的时候,这几个地址一直搞不清楚,相信你也有这个困扰吧。我们知道,计算机运行有两个模式, 实模式和保护模式。这几个地址我们就在这两个模式下区分。

1、实模式

 首先,不管在什么模式下,物理地址都是内存的真实地址,CPU可以根据这个地址直接访问内存,这没什么好困惑的。其次,不管在什么模式下,地址写成段地址:偏移量这样的都被称为逻辑地址,逻辑地址是程序员在程序中使用的地址。这里你可能要问了,为什么我的程序中从来没写过地址呢?因为只有汇编这类的低级语言才会在程序中直接写地址,高级语言都是编译器来做这件事。
 在实模式下,逻辑地址经过地址转换单元得到物理地址,CPU用物理地址直接访问内存。

2、保护模式

 物理地址和逻辑地址的解释,上面实模式已经说过了,下来只要介绍线性地址和虚拟地址就可以了。
 线性地址在保护模式下,指的就是逻辑地址经过地址转换单元得到的地址,如果开启了分页功能的话,线性地址又被称为虚拟地址,通过分页机制线性地址转换为物理地址。如果没有开启分页功能的话,这个线性地址就是CPU需要的物理地址。

 总结来说就是,实模式下:地址分为逻辑地址和物理地址,逻辑地址通过地址转换机制转换为物理地址。在保护模式下:如果没有开启分页,逻辑地址通过地址转换单元转换为线性地址,该线性地址=物理地址;如果开启了分页功能,线性地址再通过分页机制转换为物理地址。

 这里需要注意的是,我们说的地址转换机制的工作原理是:把段基址左移四位,然后加上偏移量。分页机制转换的原理:通过查找页表,得到该段基址对应的实际物理地址,然后加上偏移量,得到物理地址。实际上,我们可以认为我们只是对段基址进行了许许多多的操作,偏移量并没有发生变化。因此我们把偏移量称为,有效地址。

三、神奇的数字0x55和0xaa

 有一个问题,启动的的时候BIOS如何知道计算机都连接了那些外设呢?要想明白这个问题,要先明白CPU如何访问外设。
 CPU访问外设有两种方式:内存映射和IO端口映射。端口映射这种方式就是通过in/out指令操作IO端口来达到操作外设的目的。内存映射方式就是把外设的存储中的内容映射到CPU存储中来(不是很明白映射到哪里),作为存储空间的一部分,CPU只是操作这些空间就可以操作外设。
 内存映射这种方式,映射了很多外设的调用历程和初始化代码,每一个代码最后两个字节都是0x55和0xaa。启动的时候BIOS循环扫描映射的这段内存,只要发现了0x55和0xaa就说明这里有一个可运行的外设的调用例程。
 至于为什么这个“有魔力”的数字要选择称为0x55和0xaa,我我提出一个猜测,但是并没有找到任何资料佐证的猜测。0x55 的二进制形式是01010101,而0xaa的二进制形式是10101010,这两串二进制数字可能是某种意义上的检错码。
 并不只是外设的调用例程最后两个字节填充0x55和0xaa,每个引导记录最后也全部填充这两个数字。

引导程序