您的位置:首页 > 运维架构 > Linux

关于linux内核重要文件的基本描述

2015-08-10 19:02 363 查看
linux/Makefile 文件

这个Makefile文件的主要作用是指示make程序最终使用独立编译连接成的tools/目录中的build执行程序将所有内核编译代码连接和合并成一个可运行的内核映像文件 image。具体是对 boot/中的bootsect.s、setup.s 使用 8086 汇编器进行编译,分别生成各自的执行模块。再对源代码中的其它所有程序使用 GNU 的编译器 gcc/gas 进行编译,并连接成模块 system。再用 build 工具将这三块组合成一个内核映象文件 image. 基本编译连接/组合结构如下图 1.1 所示。



System.map 文件
System.map 文件用于存放内核符号表信息。符号表是所有符号及其对应地址的一个列表。随着每次内核的编译,就会产生一个新的对应 System.map 文件。当内核运行出错时,通过 System.map 文件中的符号表解析,就可以查到一个地址值对应的变量名,或反之。

 


2.2 bootsect.s 文件
bootsect.s 代码是磁盘引导块程序,驻留在磁盘的第一个扇区中(引导扇区,0 磁道(柱面) ,0 磁头,第 1 个扇区) 。在 PC 机加电 ROM BIOS 自检后,引导扇区由 BIOS 加载到内存 0x7C00 处,然后将自己移动到内存 0x90000 处。该程序的主要作用是首先将 setup 模块(由 setup.s 编译成)从磁盘加载到内存紧接着 bootsect 的后面位置(0x90200),然后利用 BIOS 中断 0x13 取磁盘参数表中当前启动引导盘的参数,接着在屏幕上显示“Loading
system...”字符串。再者将 system 模块从磁盘上加载到内存 0x10000 开始的地方。随后确定根文件系统的设备号,若没有指定,则根据所保存的引导盘的每磁道扇区数判别出盘的类型和种类 (是 1.44M A 盘?) 并保存其设备号于 root_dev(引导块的 0x508 地址处), 最后长跳转到 setup程序的开始处(0x90200)执行 setup 程序。


2.3 setup.s 程序
setup 程序的作用主要是利用 ROM BIOS 中断读取机器系统数据,并将这些数据保存到 0x90000 开始的位置(覆盖掉了 bootsect 程序所在的地方) ,所取得的参数和保留的内存位置见下表 2.1 所示。这些参数将被内核中相关程序使用,例如 ttyio.c 程序等。 然后 setup 程序将 system 模块从 0x10000-0x8ffff(当时认为内核系统模块 system 的长度不会超过此值:512KB)整块向下移动到内存绝对地址 0x00000 处。接下来加载中断描述符表寄存器(idtr)和全局描述符表寄存器(gdtr),开启
A20 地址线,重新设置两个中断控制芯片 8259A,将硬件中断号重新设置为0x20 - 0x2f。最后设置 CPU 的控制寄存器 CR0(也称机器状态字) 从而进入 32 位保护模式运行,并跳转到位于 system 模块最前面部分的 head.s 程序继续运行 setup.s 负责从 BIOS 中获取系统数据,并将这些数据放到系统内存的适当地方。 此时 setup.s 和 system 已经由 bootsect 引导块加载到内存中.这段代码询问 bios 有关内存/磁盘/其它参数,并将这些参数放到一个 “安全的”地方:0x90000-0x901FF,也即原来
bootsect 代码块曾经在的地方,然后在被缓冲块覆盖掉之前由保护模式的 system 读取。




2.4 head.s 文件
head.s程序在被编译后, 会被连接成system模块的最前面开始部分, 这也就是为什么称其为头部(head)程序的原因。从这里开始,内核完全都是在保护模式下运行了。heads.s 汇编程序与前面的语法格式不同,它采用的是 AT&T 的汇编语言格式,并且需要使用 GNU 的 gas 和 gld 进行编译连接。因此请注意代码中付值的方向是从左到右。

 

 

这段程序实际上处于内存绝对地址 0 处开始的地方。这个程序的功能比较单一。首先是加载各个数据段寄存器,重新设置中断描述符表,共 256 项,并使各个表项均指向一个只报错误的哑中断程序。然后重新设置全局描述符表。接着使用物理地址 0 与 1M 开始处的内容相比较的方法,检测 A20 地址线是否真的开启(如果没有开启,则在访问高于 1Mb 物理内存地址时 CPU 实际只会访问(IP MOD 1Mb)地址处的内容) ,如果检测下来发现没有开启则进入死循环。然后测试 PC 机是否含有数学协处理器芯片,并在控制寄存器CR0
中置相应的标志位。接着设置分页处理机制,将页目录表放在绝对物理地址 0 开始处,紧随后面放置4个页表 (可寻址16MB内存) , 并分别设置它们的表项。 最后利用返回指令将预先放置在堆栈中/init/main.c程序的地址弹出,去运行 main()程序。

2.5 main.c文件

 系统在执行完 boot/目录中的 head.s 程序后就将执行权交给了 main.c。该程序虽然不长,但却包括了内核初始化的所有工作。

2.6 asm.s 文件

asm.s 汇编程序中包括大部分 CPU 探测到的异常故障处理的底层次代码,也包括数学协处理器(FPU)的异常处理。该程序与 kernel/traps.c 程序有着密切的关系。该程序的主要处理方式是在中断处理程序中调用相应的 C 函数程序,显示出错位置和出错号,然后退出中断。

 中断信号通常可以分为两类:硬件中断和软件中断(异常)。每个中断是由 0-255 之间的一个数字来标识。 中断 int0--int31(0x00--0x1f)每个的功能是由 Intel 固定设定或保留用的, 属于软件中断, 但 Intel称之为异常。是由 CPU 执行指令时探测到异常时引起的。通常分为故障(Fault)和陷阱(traps)。中断int32--int255 (0x20-0xff)可以由用户自己设定。Linux 中则将 int32-int47(0x20-0x2f)对应于 8259A中断控制芯片发出的硬件中断请求信号
IRQ0-IRQ15;并将程序编程发出的系统调用(system_call)中断设置为 int128(0x80)。

2.7 system_call.s

本程序主要实现系统调用(system_call)中断 int 0x80 的入口处理过程以及信号检测处理,同时给出了两个系统功能的底层接口, 分别是 sys_execve 和 sys_fork。 还列出了处理过程类似的协处理器出错(int 16)、设备不存在(int7)、时钟中断(int32)、硬盘中断(int46)、软盘中断(int38)的中断处理程序。

 对于软中断(system_call、coprocessor_error、device_not_available),处理过程基本上是首先为调用相应 C 函数处理程序作准备,将一些参数压入堆栈,然后调用 C 函数进行相应功能的处理,处理返回后再去检测当前任务的信号位图,对值最小的一个信号进行处理并复位位图中的该信号。

对于硬件中断请求信号 IRQ 发来的中断,其处理过程首先是向中断控制芯片 8259A 发送结束硬件中断控制字指令 EOI,然后调用相应的 C 函数处理程序。对于时钟中断也要对当前任务的信号位图进行检测处理。

2.8 traps.c 程序
 对之前的system_call.s中的各个以do_开头的函数对应名称中断处理程序调用c函数的实现(有个重要的函数void die(**));


2.9 mktime.c 文件
该该程序只有一个函数 mktime(),仅供内核使用。计算从 1970 年 1 月 1 日 0 时起到开机当日经过的秒数,作为开机时间

3.0 sched.c 文件
sched.c 是内核中有关任务调度函数的程序。'sched.c'是主要的内核文件。其中包括有关调度的基本函数(sleep_on、wakeup、schedule 等)以及 一些简单的系统调用函数(比如 getpid(),仅从当前任务中获取一个字段)。

3.1 signal.c文件


本程序给出了设置和获取进程信号阻塞码(屏蔽码)函数,singal()和 sigaction()系统调用以及在系统调用中断处理程序中处理信号的函数 do_signal()。signal()和 sigaction()的功能比较类似,都是改变信号原处理句柄。但 signal()会返回原信号处理句柄,并且在新句柄被调用一次后句柄就会恢复到默认值。而 sigaction()则可以进行更自由的设置。 

 do_signal()的处理原理是系统调用中断处理程序中真正的信号处理程序。 该函数的主要作用是将信号的处理句柄插入到用户程序堆栈中。这样,在本系统调用结束返回后就会立刻执行信号句柄程序,然后继续执行用户的程序。

3.2 exit.c文件

负责释放指定的进程,同时释放他所拥有的资源,以及遇见特殊情况的处理办法;系统调用 waitpid()。挂起当前进程,直到 pid 指定的子进程退出(终止)或者收到要求终止

3.3 fork.c 程序

fork()系统调用用于创建子进程。Linux 中所有进程都是进程 0(任务 0)的子进程; 'fork.c'中含有系统调用'fork'的辅助子程序(参见 system_call.s),以及一些其它函数

('verify_area')。一旦你了解了 fork,就会发现它是非常简单的,但内存管理却有些难度.参见'mm/mm.c'中的'copy_page_tables()'。

3.4 sys.c文件

sys.c 程序主要包含有各个系统调用功能的实现函数。 其中, 若返回值为-ENOSYS, 则表示本版的 linux还没有实现该功能,可以参考目前的代码来了解它们的实现方法。

3.5 vsprintf.c文件

由于该文件也属于库函数,所以从 1.2 版内核开始就直接使用库中的函数了。也即删除了该文件。

3.6 printk.c文件

当处于内核模式时,我们不能使用 printf,因为寄存器 fs 指向其它不感兴趣的地方;自己编制一个 printf 并在使用前保存 fs,一切就解决了。也既是printk的实现源码

3.7 panic.c程序

当内核程序出错时,则调用函数 panic(),显示错误信息并使系统进入死循环;在内核程序的许多地方,若出现严重出错时就要调用到该函数。在很多情况下,调用 panic()函数是一种简明的处理方法。这样做很好地遵循了 UNIX“尽量简明”的原则。该函数在整个内核中使用(包括在 头文件*.h, 内存管理程序 mm 和文件系统 fs 中;用以指出主要的出错问题

3.8 blk.h 文件

这是有关硬盘块设备参数的头文件,因为只用于块设备,所以与块设备代码放在同一个目录下;块设备头文件。定义请求数据结构、块设备数据结构和宏函数等信息

3.9 hd.c文件

本程序是底层硬盘中断辅助程序。主要用于扫描请求列表,使用中断在函数之间跳转。 由于所有的函数都是在中断里调用的,所以这些函数不可以睡眠。请特别注意。 由 Drew Eckhardt 修改,利用 CMOS 信息检测硬盘数

4.0 ll_rw_blk.c 文件

该程序处理块设备的所有读/写操作

4.1 ramdisk.c文件

定义虚拟盘读写操作(EXT2?);包含虚拟盘初始化函数

4.2 serial.c文件

该程序用于实现 rs232 的输入输出功能 void rs_write(struct tty_struct *queue); void rs_init(void);以及与传输 IO 有关系的所有中断处理程序

4.3 rs_io.s 文件

该汇编程序实现 rs232 串行通信中断处理程序

4.4 tty_io.c 文件

'tty_io.c'给 tty 一种非相关的感觉,是控制台还是串行通道。该程序同样 实现了回显、规范(熟)模式等。(这个汇编文件相当的复杂)

4.5 tty_ioctl.c 文件

对于tty_io的具体实现以及各类处理串行通道的函数(?)

4.6 keyboard.S 文件

该键盘驱动汇编程序主要包括键盘中断处理程序。在英文惯用法中,make 表示键被按下;break 表示键被松开(放开)。 对于 AT 键盘的扫描码,当键按下时,则对应键的扫描码被送出,但当键松开时,将会发送两个字节,第一个是 0xf0,第 2 个还是按下时的扫描码。为了向下的兼容性,设计人员将 AT 键盘发出的扫描码转换成了老式 PC/XT 标准键盘的扫描码。因此这里仅对 PC/XT 的扫描码进行处理即可。

4.7 console.c 文件

该模块实现控制台输入输出功能

 

 

 

 

 

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: