《LINUX内核完全注释0.11》学习笔记(草稿)

 

一、相关概念

1:GNU计划的产物,emacs、gcc、gdb、bash shell、make等软件的开发为linux的开发铺平了道路,linux后来实际上也成为GNU计划的一部分。

2:POSIX标准是根据UNIX的实践提出的操作系统的标准接口,目的是提高应用程序的可移植性,使其可以在多种支持POSIX接口标准的操作系统上运行。

 

二、用户态和内核态:通过CPL寄存器区分,==0,内核态,==1,用户态

    一般地,进程首先在用户态运行,通过系统调用int 0x80中断或者被外部硬件中断后进入内核态运行,此时CPU自动将CPL设置为0,系统调用用于完成特定的功能后又返回用户态继续执行,如果该系统调用需要等待外设完成数据处理,不能立即返回的话,它将调用sleep()将该进程阻塞并运行调度程序使其他进程有机会运行,直至外设完成指定操作中断CPU,则CPU在中断处理程序中将该进程置为就绪,使其在下一次调度中有机会运行,不过进程在用户态运行时使用的是用户堆栈,而在内核态运行时使用的是内核堆栈,内核堆栈位于task_struct的同一页(4k)。

    无论进程处于用户态或内核态,都可能被中断执行,如果中断不是定时中断,不允许调动程序的话,则中断返回后将继续执行该进程。调度程序要么是可能被阻塞的系统调用自行调用,要么是在定时中断处理中调用,不可能在别的地方被调用。但是,为了保证内核态运行的程序不被打断,任何在内核态运行的代码,包括中断处理程序和系统调用,此时定时中断处理程序将不调用调度程序。

 

三、内核是一个整块的代码,其中有个main函数,是系统启动后自动执行的,用于初始化系统并创建0号进程,内核用途主要有系统初始化、硬件模块的中断处理、构造0号进程运行和提供系统调用,除了系统调用外,其余代码都在开机后依次主动运行的,而系统调用是提供给0号进程创建的子进程在运行过程中随时调用的。

      总之,内核代码是被加载程序加载到内存的高地址部分,内核的地址空间可以被映射到任一进程的代码段中,是系统中所有进程的共享的代码,它们都可以通过系统调用的方式去使用内核代码。

Linux内核源代码的结构,包括一个makefile文件和14个子目录,makefile文件用于编译连接各个模块构建image,14个子目录分别如下:

/boot:系统引导的汇编程序,位于系统引导区,用于调用main函数

/fs:分为高速缓冲区管理、底层文件操作函数,高层文件读写函数、字符和块设备的读写函数,实现了文件操作的系统调用

/inlcude:主目录下有13个头文件、include/asm目录下是4个和CPU体系结构有关的数据结构的定义、inclue/linux是内核专用头文件、 include/sys系统专用数据结构定义。

/init:main.c函数定义

/kernel:包括进程控制相关的系统调用、进程调度程序、信号处理、设备驱动、设备中断处理和字符串输出程序等公用模块

/kernel/blk_drv:块设备驱动和对于的外设硬件中断处理

/kernel/chr_drv:字符设备驱动和对于的外设硬件中断处理

/lib:内核库函数,为内核main()提供运行的支持库,属于基本C库libc的补充。

/mm:内存管理的2个文件,内存初始化分配回收和缺页中断

总之,head+main+kernel+mm+fs+lib链接成system,之后与boot和setup在一次链接成完整的image,这一过程在内核源码目录下的makefile文件控制下完成。

 

四、中断机制是内核的关键之一,首先它实现了系统调用;其次时钟中断10ms(一个嘀嗒,一般每个进程每次被分配15个嘀嗒,150ms)定时中断,用于实现分时系统,时钟中断处理程序首先通过CPL判断当前进程运行在用户态还是核心态,然后将与之对应的时间片减1,如果结果为0且进程运行在用户态,则运行调度程序重新调度,但是如果运行在核心态则直接退出而不运行调度程序,因为核心态是不可抢占的。如果系统中所有处于就绪的进程的时间片都用完,则调度程序会根据各个进程的优先级重新计算它们的时间片,如果系统中没有其他进程可运行,则运行0号进程。

 

五、内核的运行过程是从main函数开始的,在该函数完成硬件初始化之后,通过手工拼凑的方式将其设置为0号进程,之后,系统中所有的进程都是该进程fork出来的子进程,子进程复制父进程的一切,然后根据自身的一些情况进行适当的修改,比如将运行时间设置为15个嘀嗒和修改返回值,进程在内核通过PID区分,中被分配task struct,内核堆栈,用户内存中的数据代码段和堆栈段,不过Linux实行的是COW机制,写入操作时才执行真正的分配。task struct用于保持进程的状态和其运行的上下文,用于进程的被切换和被中断。

     当进程调用sleep()之类的函数时,将自愿地将其自身置于TASK_INTERRUPTABLE状态,但是当其等待的事件通过中断发生,或接收到信号之后,都能被唤醒,还有一个僵尸状态,是指进程已经运行接收,但是父进程并没有调用wait去获取其的状态,故其的task_struct将一直保持。

   进程运行结束一般通过调用exit(),该系统调用首先释放该进程分配的内存、文件等资源,然后将init进程作为其所有子进程的父进程,接下来将自身置为僵尸状态并向父进程发生sigcld信号,让处于wait状态的父进程将其task_struct释放,最后调用schedule()重新调度。

 

六、整个内存被固定地分为三个部分,分别为内核段、块设备数据缓冲区和用户段,虚拟内存管理的目的是实现小内存运行大程序,手段是写一个缺页中断程序。

 

七、信号处理:

某个进程可以通过raise、kill之类的系统调用给另一个进程发送特定的信号;在接收信号的进程中可以设置是否屏蔽特定的信号,如果不屏蔽则处理特定的信号,处理的方法可以是系统默认,忽略或用户自定义;有好几个内核模块都将设计到信号处理。

    调度程序schedule()在调度之前对当前系统中的所有进程task_struct中的alarm信号判断,如alarm时间到,则置SIGALARM信号;检查所有可睡眠打断进程有无未屏蔽信号位被置位。有则唤醒(状态改为就绪)该进程。

    任何一个中断处理程序(时钟中断和系统调用中断处理)都会在结束之前调用do_signal,该函数实现了将信号处理函数的地址压入用户堆栈中,使得中断返回后,该进程在首次得到运行时会首先运行信号处理程序,由于系统至少10ms就要执行一次时钟中断,所以当前进程能很快的处理信号,实时性也很强,因此信号总是可以及时地得到"触发"。

 

八、文件系统

 

如上图所示,一个完整的文件系统一般对应着一个分区,而一个文件系统则由5个部分组成,分别为

引导区:加电运行的第一段代码

超级块:用于描述该文件系统的相关参数,例如逻辑块的块数以及起始位置

i节点位图:描述文件系统中i节点的使用情况

逻辑块位图:描述文件系统中所有逻辑块的使用情况

i节点:系统中所有的i节点,i节点用于记录各个文件的所有属性及其所在数据块的块号,用于索引文件中的数据

 

 

 

数据区:一系列数据块组成,用于存放普通文件或目录文件的实际数据。

说明:i节点使得文件的属性和内容分开,容易实现文件的共享,即一个i节点可以被多个目录项所共享,删除一个目录项只是解除对i节点的一次引用,只有当i节点的应用计数为0,才真正执行删除操作。目录项中的链接也称为硬链接,与之对应的符号链接则是一个文本文件,文件的内容是其链接文件的路径名,可以实现跨越文件系统。

      文件操作的核心是对磁盘缓冲区的管理,一般地,系统调用读写的数据都是来自缓冲区,如果缓冲区中没有,则调用驱动程序读写硬盘。磁盘缓冲区根据磁盘数据块的大小被划分成若干块,系统调用读写之前需要申请到空闲块才能读写,所以申请过程也可能被阻塞。申请完成后,调用驱动程序读磁盘,同时自身睡眠。

九、块设备驱动程序

如图所示,三者之间通过中断实现联系,由上节的文件系统可知,块设备驱动程序完成了缓冲区和设备之间的数据传输。具体来说,块设备驱动程序读写时按照电梯算法的要求,先将读写请求构造成一个请求项,然后让请求项组成电梯算法队列,如果此时队列空,则调用该请求对应的读写函数将数据从缓冲区写到设备控制器并命令设置控制器读写到磁盘,同时自己被睡眠,当数据读写完成后,会发生中断通知CPU,CPU执行中断处理程序,首先判读是否还有扇区需要传输,有则继续,否则将释放缓冲区以及唤醒相关进程,并检查请求队列中是否有等待请求,有则执行该请求的读写函数,直至所有请求为空。

十、字符设备驱动程序

     tty是指键盘和显示器,字符驱动程序包括键盘、显示器和串口的驱动程序及其相关的中断处理程序,用于终端设备和进程之间的数据传输并对传输的数据做一定的格式修改,如图所示:

每个终端都对应这一个数据结构,用于描述其的熟悉,定义数据缓冲区和写函数,如图:

读数据的过程,是中断处理程序实现的,直接将读到的数据写入到读队列;而写数据的过程,是通过该数据结构中的写函数一个一个字符的将写队列中的数据写到显示器上或者通过串口发送出去,写显示器是先写到写缓冲区,知道写完或者缓冲区满,才真正执行输出操作;而写串口则是一次写一个字符,写完一个中断一次,直至全部写完。

参考资料:

http://blog.mcuol.com/User/lvembededsys/Article/4855_1.htm

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值