User Tools

Site Tools


tech:system:q_a

Tech Q&A

Q1. [OS]如何为系统的每一个进程提供一个从0开始的独立地址空间,从而使进程间的地址空间相互独立,简化了进程镜像的链接和装载过程

A1: 要实现这一点,需要有硬件的MMU支持,这个MMU必须能够借助于内存中的地址转换表实现虚拟地址到物理地址的转换。MMU使能后,CPU看到的是虚拟地址,而内存接口看到的却是物理地址。因此,OS可以通过控制地址转换表控制虚拟地址到物理地址的映射,从而能够为不同的进程建立各自的地址转换表,以将相同的虚拟地址映射为不同的物理地址,达到为每一个进程提供一个从0开始的独立地址空间的目的。这种情况下,OS需要在进程切换的时候切换MMU依赖的地址转换表。

Q2. [OS]如何实现系统调用?

A2: 对于相对简单的OS,系统调用完全可以以普通API的形式给出,用户代码通过包含系统头文件实现对系统API的引用。这种情况下,用户程序一般会和系统编译成一个整体的镜像,或者被动态地插入到系统中。 对于复杂一点的OS——这些OS通过处理器的物理支持,实现了供用户代码运行的用户态和供OS代码运行的特权态,用户态下不只不可以运行某些特权指令,也不可以访问OS使用的系统地址空间——通过API的形式实现系统调用是不可能的。好在处理器还会提供一个非特权的陷入指令,用户态下运行这个特权指令可以切入到特权态,从而实现了对OS代码、数据的访问。当然,切换后的处理代码是由OS提供的,因此,执行陷入指令并不会让恶意代码危害OS的安全。 如是,系统调用可以以陷入指令为缺口,在OS内部实现。

Q3. [CPU]什么是特权指令?

A3: 特权指令只存在于区分运行态的处理器中。对于这种处理器,某些指令可以在所有的处理器运行态下执行,某些指令却只能在特定的处理器运行态下执行,只能在特定处理器运行态下执行的指令就是特权指令。比如ARM处理器的MCR, MRC指令、x86处理器的io指令就是特权指令。

Q4. [OS]何谓共享库(或动态链接库)?共享库的“共享”仅仅体现在硬盘上,还是也能体现在内存中?

A4: 库的机制实现了对通用代码片段的重复使用,比如应用程序A和B都可以通过链接库C来使用C中的代码片段。链接的方式有两种,静态链接和动态链接。前者将应用程序代码和库代码合并在一起,然后载入内存运行;后者则首先将应用程序代码载入内存,在运行过程中才载入需要的库代码。 这里面,动态链接的形式即所谓共享库的形式。共享库的“共享”可以体现在硬盘上是毋庸置疑的——多个应用程序可以共享硬盘上的某个库,那么,如果内存中的多个应用程序进程使用同一个共享库,这个共享库需要被多次装载、每一个进程都在其地址空间中保存一个备份,还是将共享库一次装载到内存的某个区域、然后每个进程通过某种机制共享其中的代码和数据?

通过一个简单的实验,推断至少在LINUX中共享库的所谓“共享”并不能体现在内存里,似乎每一个进程都需要装载共享库的代码到自己的地址空间中。 实验过程: - 编写程序a、b及它们都会用到的共享库c。 - 编译a,b,c - 链接生成可执行程序a和b,其中a,b运行时都将陷入一个循环而无法退出。 - 运行a; - 删除共享库c,或修改共享库c,去掉其中为a和b提供的某些函数。 - 运行b;←无法找到共享库c,或无法找到需要的符号。

IBM技术论坛上有一篇简单的参考文章: http://www-128.ibm.com/developerworks/cn/linux/l-dynlink 其中提到了程序的动态链接和动态载入,认为在这种技术的帮助下,多个应用程序进程可以在内存中共享某个库的数据和代码,个人认为是不大可能的。因为如果这种共享存在的话,编写程序的时候势必还需要考虑一个全局变量为多个进程所竞争的问题,再或者,即使是共享,也仅仅允许共享某些局部数据,譬如.text段?

[added on 2008/08/15]: 如果是ELF共享库,并且链接的时候同时使能-fpic选项和-shared选项,则可以实现共享库的代码段在各个进程间的共享,但仍然需要为每一个进程建立一个数据段的拷贝。

[added on 2009/12/28]: .text在内存中的共享应该是毋庸置疑的。

Q5. [Compiler]GCC编译C代码时系统头文件的搜索路径由什么决定?

A5: 这个搜索路径是编译GCC的时候通过configure来指定的。 如./configure –prefix=xxx –includedir=xxx

Q6. [OS]LINUX Kernel的缺省配置来自何方?

A6: 这里所说的缺省配置是指运行make config/make menuconfig的时候呈现给用户的各项目的配置。当然,如果.config文件存在的话,所呈现出来的各项目的配置即当前.config中设定的配置,但如果.config不存在的话,运行运行make config/menuconfig时呈现给用户的缺省设置则由固化在各个Kconfig文件中各项目的缺省值决定。

如果运行make defconfig的话,系统则根据一个defconfig文件来生成.config。因此,可以认为defconfig文件是系统的缺省设置文件,然而从实质上讲,这个defconfig文件和configs文件夹中各那些xxx_defconfig文件没什么两样,因为如果运行make xxx_defconfig照样可以根据configs/xxx_defconfig来生成当前的.config。

Q7. [CPU]什么是Alignment Fault?

A7: 虽然,处理器很早以前就开始了由8位、16位向32位,64位的转变,但存储器的编址一直以8位的字节为单位,即一个字节占用一个存储器地址。此外,SDRAM的数据宽度也在由8位、16位向32位演进,但这并没有对处理器以8位字节对存储器编址的机制产生任何影响,唯一需要注意的是SDRAM接口会自动根据需要的数据宽度在其地址线上输出正确的地址信息。实际上,以字节为单位的物理地址被隐藏了起来,因为甚至SDRAM的数据传输也是以32位字为单位的(A0/A1往往会被SDRAM接口忽略)。 个人认为Alignment Fault的问题就是在这种情况下产生的,假如从一个非四字节对齐的地址如0x03处读取一个32位字,CPU不得不产生Alignment Fault的异常,因为SDRAM接口不知道该如何利用这个地址来读写一个32位字,即使CPU没有产生异常,其读写的实际效果很可能和0x00是相同的。假如外部存储器接口都是8位的,一个32位字通过4个外部存储器访问来实现,Alignment Fault的问题也许就不存在了。

tech/system/q_a.txt · Last modified: 2014/11/10 08:22 (external edit)