Linux 0.01 源代码目录分布

news/2024/7/20 15:43:36 标签: shell, 内存管理, 运维
目录名所属文件
boot核心引导代码
fs文件系统
include头文件
initInit 进程,系统中执行的第一个进程
kernel系统调用
lib库代码
mm内存管理
tools内核引导文件的制作工具

boot 目录

文件描述
boot.sBIOS 启动的时候加载并执行的代码
head.s32 bit 的引导代码,调用 init_main()

boot.s 文件说明

加电自检结束后,boot.s 的代码被加载到 0x7C00 处,然后 boot.s 将自身移动到物理地址的 0x90000 处,接着跳转到该处执行。

boot.s 使用 BIOS 中断在屏幕上打印 “/nLoading system.../n/n”接着读取核心镜像文件到 0x100000 处,然后关闭引导设备,保存光标位置,关闭所有中断,再将系统核心从 0x100000 复制到 0x0000 处。接着载入中断描述符表和全局描述符表。

head.s 文件说明

该文件包含了 32 位系统的初始化代码。初始化代码的物理地址为:0x00000000 ,这个地址也是系统分页目录存放的地址。因此,系统初始化完成后,系统初始化代码将被分页目录的数据替代。

head.s 的具体工作说明:

    setup_idt:建立一个 256 个入口的中断向量表,并正确设置中断向量。设置完中断向量后,打开中断。

    setup_gdt:建立一个新的 GDT,并正确设置表项。在新的 GDT 中,只有两个表项被装载,这两个表项是在 init.s 中建立的。

    setup_paging:通过 cr0 标志位设置为 0 来建立一个页表。建立的页表可以映射机器的前 8M 物理内存。

head.s 由 boot.s 调用执行,当 head.s 执行时,系统运行在 32 位保护模式下。当 head.s 执行时,中断向量表与全局描述符表都已经被正确设置,并且合适的值被装入到 CPU 的帧、栈、堆栈指针寄存器中,然后检查有没有浮点数处理单元,如果没有,就在中断向量表中设置一个软件异常处理程序,便于模式浮点数运算。因为物理地址 0x00000000 实际上是页表数据的存放地址,因此在系统启动的最后阶段,所有的启动代码都被页表数据覆盖,启动代码将执行一个 jmp 指令,跳转到页表后的第一个地址,这个地址就是 _main() 函数的入口地址,这时,系统就执行 init/main.c 中。

fs 目录

fs 包含了文件系统的所有功能:

文件名文件包含的函数
bitmap.cnew_block(),free_block(),new_inode(),free_inode()
block_dev.cblock_write(),block_read(),ll_rw_block()
buffer.cget_hash_table(),get_blk(),sys_sync(),brelse(),bread(),buffer_init()
char_dev.crw_char()
exec.cread_head(),read_ind(),read_area(),do_execve()
fcntl.csys_dup2(),sys_dup(),sys_fcntl()
file_dev.cfile_read(),file_write()
file_table.cfile_table[]
inode.csync_inodes(),bmap(),create_block(),iput(),get_empty_inode(),get_pipe_inode()
ioctl.csys_ioctl()
namei.cnamei(),open_namei(),sys_mkdir(),sys_rmdir(),sys_unlink(),sys_link()
pipe.cread_pipe(), write_pipe(), sys_pipe()
read_write.csys_lseek(),sys_read(),sys_write()
stat.csys_stat(),sys_fstat()
super.csuperblock[],do_mount(),mount_root()
truncate.ctruncate()
ttyioctl.ctty_ioctl()
open.csys_utime(),sys_access(),sys_chdir(),sys_chroot(),sys_chmod(),sys_chown(),sys_open(),sys_create(),sys_close()

 

include 目录

该目录中包含了内核头文件也包含了 libc 中的内联函数

文件名功能
a.out.h定义可执行文件方面的信息
cons.h定义内核使用的一系列函数
ctype.h定义标准 C 的类型
errno.h定义系统错误代码
fcntl.h定义文件控制的常量与函数
signal.h定义信号量与信号量处理函数
stdarg.h定义 var_start(),va_rounded_size(),va_end()
stddef.h定义 size_t,NULL,offsetof 3个宏
string.h定义标准 C 的字符串处理函数
termios.h定义 tty 使用的常量与函数
time.h 定义时间函数与常量
unistd.h 定义标准 Unix 函数与宏
utime.h 定义 utime 时间函数

init 目录

在 init 目录下只有一个文件,main.c 。main.c 实现了系统的初始化功能,代码使用 ANSI C 写的,由 boot.s 调用。 main.c 根据机器 CMOS 的值来初始化系统时钟,然后启动 tty 设备,启动系统陷阱,启动进程调度器,启动文件系统,启动硬盘中断处理程序。接下来,内核开启中断,切换到用户模式下执行,最后,调用 init() 函数,进入进程调度循环。init() 函数会调用 setuup() 函数,setup() 函数会检查硬盘分区表,并装载磁盘分区。接下来,init() 函数 fork() 另外一个进程建立一个会话,然后使用 execve() 建立一个登录 shell 进程,这个 shell 进程的 HOME 被设置为 /usr/root 。在 main 不能执行函数调用,直到 调用 fork() 为止。

main() 实现的功能

函数名功能
time_init() 读取 CMOS 数据,初始化系统时钟
tty_init() 初始化 tty 子系统
trap_init() 初始化出错处理陷阱,如:除零
sched_init() 初始化进程调度器
buffer_init() 初始化系统块设备缓冲区
hd_init() 初始化硬盘中断处理程序
main() 后续部分 开中断
  切换到用户模式
  fork() 一个子进程进行 init()
  进入进程调度循环

init() 函数是 main.c 中的一个静态函数,在 main() 的最后被调用,init() 函数的功能如下:

函数名功能
setup()读取硬盘参数表
init() 的后续部分fork 一个子进程进行 update;为终端创建常用的 stdin 、stdout、stderr 文件句柄
 显示一条信息指示缓冲区的总量和可用缓冲区的数量
 fork 一个子进程执行文件 /bin/sh,执行参数为 argv[0]=”-”,HOME=/home/root,等待子进程退出,然后打印退出代码
 sync(),同步  I/O 操作
_exit(0)退出系统

 

kernel 目录

kernel 目录包含了内核的重要功能,如:fork()、控制台处理等等。kernel 下文件与功能列表:

文件名文件功能
asm.s硬件中断处理的汇编程序,如:缺页异常中断
console.c简单虚拟终端输出函数
exit.cexit 与 waitpid 系统功能
fork.cfork 系统功能
hd.c硬盘中断处理程序,完成硬盘 I/O
keyboard.c键盘中断处理程序
mktime.c在核心中使用简单版本的 mktime 功能
panic.c简单的核心 panic 功能,处理核心出错情况,一般打印出错信息
printk.c在核心中使用 printf 功能,用于使用时保护 FS 寄存器
rs_io.cRS-232 中断处理程序
sys.c实现一些系统调用
system_call.c系统调用接口
traps.c 陷阱处理程序:打印进程的信息,然后结束进程
tty_io.c 串口和终端 I/O 的 tty 接口
vsprintf.c 核心版本的 vsprintf

 

lib 目录

lib 目录包含了系统提供的调用接口:

文件名文件功能
_exit.c_exit(),调用系统功能 sys_exit() 的接口
close.cclose(),调用系统 sys_close() 的接口
ctype.c_ctype[] 数组, 中函数使用的查询表
dup.cdup(),调用系统 sys_dup() 的接口
errno.cerrno 变量
execve.cexecve(),调用系统 sys_execve() 的接口
open.copen(),调用系统 sys_open() 的接口
setsid.csetsid(),调用系统 sys_setsid() 的接口
string.cl实现 声明的函数
wait.cwait() ,调用系统 sys_waitpid() 的接口
write.cwrite() ,调用系统interface to sys_write() 的接口

 

mm 目录

mm 目录中包含了系统内存管理的实现文件:

文件名文件功能
page.s缺页异常的处理函数
memory.c分页存储管理功能的函数,包括:get_free_page(),free_page(),free_page_tables(),copy_page_tables(),put_page(),un_wp_page(),do_wp_page(),write_verify(),do_no_page(),calc_mem()

 

tools 目录

tools 目录只包含一个文件:build.c 。这个文件主要用于将链接器生成的三个独立核心组成部分拼接成一个完整的可引导的核心镜像文件。

关于 tty:

tty 是 Teletype 的缩写

终端是一种字符型设备,它有多种类型,通常使用tty来简称各种类型的终端设备。tty 是Teletype 的缩写。Teletype 是最早出现的一种终端设备,很象电传打字机(或者说就是),是由 Teletype 公司生产的。设备名放在特殊文件目录 /dev/ 下,终端特殊设备文件一般有以下几种:

1.串行端口终端(/dev/ttySn)

    串行端口终端(Serial Port Terminal)是使用计算机串行端口连接的终端设备。计算机把每个串行端口都看作是一个字符设备。有段时间这些串行端口设备通常被称为终端设备,因为那时它的最大用途就是用来连接终端。这些串行端口所对应的设备名称是/dev/tts/0(或/dev/ttyS0)、/dev/tts/1(或/dev/ttyS1)等,设备号分别是(4,0)、(4,1)等,分别对应于DOS系统下的COM1、COM2等。若要向一个端口发送数据,可以在命令行上把标准输出重定向到这些特殊文件名上即可。例如,在命令行提示符下键入:echo test > /dev/ttyS1会把单词”test”发送到连接在ttyS1(COM2)端口的设备上。

   当然,这不是固定的。标识设备最为重要的是主设备号和次设备号组成的二元组,然后是基于此的设备驱动程序。EP9301的这块开发板采用了/dev/ttyAM0来代替/dev/ttyS0,/dev/ttyAM1来代替/dev/ttyS1。我还没有学习开发驱动程序,下个学期要熟悉一下,以加深理解。

2.伪终端(/dev/pty/)

    伪终端(Pseudo Terminal)是成对的逻辑终端设备,例如/dev/ptyp3和/dev/ttyp3(或着在设备文件系统中分别是/dev/pty/m3和/dev/pty/s3)。它们与实际物理设备并不直接相关。如果一个程序把ttyp3看作是一个串行端口设备,则它对该端口的读/写操作会反映在该逻辑终端设备对的另一个上面(ttyp3)。而ttyp3则是另一个程序用于读写操作的逻辑设备。这样,两个程序就可以通过这种逻辑设备进行互相交流,而其中一个使用ttyp3的程序则认为自己正在与一个串行端口进行通信。这很象是逻辑设备对之间的管道操作。

    对于ttyp3(s3),任何设计成使用一个串行端口设备的程序都可以使用该逻辑设备。但对于使用ptyp3的程序,则需要专门设计来使用ptyp3(m3)逻辑设备。例如,如果某人在网上使用telnet程序连接到你的计算机上,则telnet程序就可能会开始连接到设备ptyp2(m2)上(一个伪终端端口上)。此时一个getty程序就应该运行在对应的ttyp2(s2)端口上。当telnet从远端获取了一个字符时,该字符就会通过m2、s2传递给getty程序,而getty程序就会通过s2、m2和telnet程序往网络上返回”login:”字符串信息。这样,登录程序与telnet程序就通过“伪终端”进行通信。通过使用适当的软件,就可以把两个甚至多个伪终端设备连接到同一个物理串行端口上。

在使用设备文件系统(device filesystem)之前,为了得到大量的伪终端设备特殊文件,HP-UX、AIX等使用了比较复杂的文件名命名方式。

关于伪终端的编程也是很复杂的一块,要掌握不是一朝一夕就能办到的。先大体了解一下就是了。

3.控制终端(/dev/tty)

  如果当前进程有控制终端(Controlling Terminal)的话,那么/dev/tty就是当前进程的控制终端的设备特殊文件。可以使用命令”ps –ax”来查看进程与哪个控制终端相连。对于你登录的shell,/dev/tty就是你使用的终端,设备号是(5,0)。使用命令”tty”可以查看它具体对应哪个实际终端设备。/dev/tty有些类似于到实际所使用终端设备的一个联接。

4.控制台终端(/dev/ttyn, /dev/console)

  在UNIX系统中,计算机显示器通常被称为控制台终端(Console)。它仿真了类型为Linux的一种终端(TERM=Linux),并且有一些设备特殊文件与之相关联:tty0、tty1、tty2等。当你在控制台上登录时,使用的是tty1。使用Alt+[F1—F6]组合键时,我们就可以切换到tty2、tty3等上面去。tty1 –tty6等称为虚拟终端,而tty0则是当前所使用虚拟终端的一个别名,系统所产生的信息会发送到该终端上。因此不管当前正在使用哪个虚拟终端,系统信息都会发送到控制台终端上。

可以登录到不同的虚拟终端上去,因而可以让系统同时有几个不同的会话期存在。只有系统或超级用户root可以向/dev/tty0进行写操作。

5.其它类型

还针对很多不同的字符设备存在有很多其它种类的终端设备特殊文件。例如针对ISDN设备的/dev/ttyIn终端设备等。这里不再赘述。

转载于:https://www.cnblogs.com/Proteas/archive/2010/10/18/2335686.html


http://www.niftyadmin.cn/n/694981.html

相关文章

灵活使用ARM汇编的WEAK关键字

////TITLE:// 灵活使用ARM汇编的WEAK关键字//AUTHOR:// norains//DATE:// Tuesday 20-October-2010//Environment:// KEIL MDK 4.0// ARM汇编中的WEAK关键字是一个很有意思的功能,如果能够灵活使用,能减轻不少繁琐。一般来说,这…

Unix I/O总结 - shangdahao - 博客园

Unix I/O总结 - shangdahao - 博客园Unix I/O总结输入是从I/O设备拷贝数据到主存,输出是从主存拷贝数据到I/O设备。一个文件就是一个字节序列。所有的I/O设备,如网络、磁盘、和终端,都被模型化为文件,而所有的输入和输出都被当做想…

Android Intent对象使用和Activity间数据的传递

在应用中&#xff0c;可能会在当跳转到另外一个Activity的时候需要传递数据过去&#xff0c;这时就可能用Bundle对象&#xff1b; 在MainActivity中&#xff0c;有一个导航至BActivity的Intent&#xff0c; Intent intent new Intent(Context context, Class<?> class)…

《Jsp2.0技术手册》读书笔记补充-web.xml详解及listener,filter,servlet加载顺序

已经复习完了jsp中后台重要部分&#xff1a;servlet,filter和listener。那么它们之间的加载顺序是怎样的&#xff1f;web.xml其他元素怎么配置呢&#xff1f;由于找到了一篇很好的文章&#xff0c;故转贴如下&#xff1a; 一、 1、启动一个WEB项目的时候&#xff0c;WEB容器会…

iOS网络编程实践--NSStream实现TCP Socket iPhone客户端

客户端我们使用iPhone应用程序&#xff0c;画面比较简单。点击发送按钮&#xff0c;给服务器发送一些字符串过去。点击接收按钮就会从服务器读取一些字符串&#xff0c;并且显示在画面上。 有关客户端应用的UI部分不再介绍了&#xff0c;我们直接看代码部分&#xff0c;Socket客…

JavaScript面向对象的简单介绍

JavaScript是一门OOP&#xff0c;而有些人说&#xff0c;JavaScript是基于对象的。1) 如何创建对象&#xff1a;1. 使用constructor&#xff0c;例如&#xff1a;var obj new Object() // var 可以省略var obj new Date() 2. 使用对象字面值(object literals)&#xff0c;例如…

百度重置页面自动跳转脚本

大家都知道的原因&#xff0c;百度现在不允许其它搜索引擎直接进入的它旗下的所有站点&#xff0c;在痛苦的被增加了很多点击后写了这个自动跳转的脚本。 原来不只搜索引擎&#xff0c;其它网站的链接也被搞了&#xff0c;nnd&#xff0c;诅咒百度。 使用方法&#xff1a;用xxx…

光脚丫学LINQ(009):选择各个源元素的子集

视频演示&#xff1a;http://u.115.com/file/f2d7193f3a 选择源序列中的各个元素的子集有两种主要方法&#xff1a;1、若要只选择源元素的一个成员&#xff0c;请使用点运算。在下面的示例中&#xff0c;假定 Customer 对象包含几个公共属性&#xff0c;其中包括名为 City 的字…