linux内核源码分析 linux内核bfs源码
- 开发语言
- 2023-08-13
- 71
很多朋友对于linux内核源码分析和linux内核bfs源码不太懂,今天就由小编来为大家分享,希望可以帮助到大家,下面一起来看看吧!如何修改linux内核源码并调试将修...
很多朋友对于linux内核源码分析和linux内核bfs源码不太懂,今天就由小编来为大家分享,希望可以帮助到大家,下面一起来看看吧!
如何修改linux内核源码并调试
将修改的代码添加进内核树,然后修改makefile和config文件,从新编译。
Linux内核是如何创建线程的,它与windows有哪些不同
谢邀。
其实Linux创建进程,就是创建进程运行所需的内存空间,填充描述进程的task_struct结构体,以及加载进程的程序而已。
Linux内核并无专门创建线程的机制我们之前提到,Linux并不特殊对待线程,在Linux看来,线程不过就是一种特殊的进程而已。那么,Linux是如何创建线程的呢?
线程机制是大多数现代编程语言都会提供的机制,该机制允许在同一进程的共享内存地址空间运行一组“特殊的进程(即线程)”。这些线程不仅共享同一段内存空间,还可以共享已经打开的文件,统计量等其他资源。线程机制支持程序并发运行,在多处理器核心的系统上,该并发机制能够实现多条线程同时运行。
Linux管理线程的方式不同于其他一些经典操作系统,Linux并没有线程的概念,它把线程当作进程的一个子集来管理。因此,Linux内核并未为线程提供额外调度算法,也没有提供额外的数据结构用于描述和存储线程。
就像进程一样,Linux使用task_struct结构体描述和记录线程,每个线程都有唯一属于自己的task_struct结构。从这个角度来看,线程就是一个普通的进程,只不过线程可能和其他进程共享一些资源而已。
以Windows为代表的一些操作系统提供了专门用于创建线程的机制,在这些系统中,线程常常被称作“轻量级进程”,因为相对于进程而言,线程耗费的资源较少,能够较为迅速的创建和投入运行。
但是对于Linux而言,线程不过是进程之间共享资源的一种手段罢了。那么是不是Linux中的线程比Windows中的线程更加“重量级”呢?也不是,因为Linux中的进程本身就很轻量级,Linux创建进程所需时间,并不比Windows创建线程所需时间多多少。
从C语言代码层面来看,假设某个进程包含4个线程,以Windows为代表的一些操作系统一般会有一个包含指向4个不同线程的指针的进程描述符,负责描述地址空间、打开的文件等共享资源,而线程本身再去描述自己独占的资源。
与之对应的,Linux的做法就高雅许多,它仅需为这4个线程创建4个task_struct结构体,然后在task_struct中指定它们共享的资源就可以了。
创建线程看了我最近几篇文章的读者应该已经明白,Linux内核中的线程其实就是进程,因此线程的创建与进程的创建过程是类似的,从C语言源代码层面看,基本上也是通过fork()函数和exec()函数族实现的。只不过在调用clone()函数时需要传递一个参数用于描述共享资源,例如:
上面这行C语言代码和调用fork()函数的结果差不多,只不过输入的几个参数标志位说明了子进程与父进程共享一些资源:地址空间、文件系统、打开的文件、信号处理程序。
对比一下,fork()基本上就相当于clone(SIGCHLD,0),这也是fork()函数创建的子进程之后不再与父进程共享资源的原因。
关于clone()函数的参数标志位,可以在Linux中输入man命令查看。
Linux内核线程就像用户空间的C语言程序开发一样,Linux内核也经常需要在后台处理数据,这时就需要借助内核线程了。Linux的内核线程一般不会独立的地址空间,它们只在内核空间运行,不会切换到用户空间。不过调度是和普通进程一样的,可以被调度和抢占。
Linux创建内核线程由kthread_create()函数实现,它的C语言源代码如下,请看:
可见,kthread_create()函数的C语言代码并不长,而且也可以看出,Linux内核线程是通过kthread_create_info结构体描述的,它的定义C语言代码如下,可见,内核线程的描述和存储也是包含task_struct结构体的:
kthread_create()函数创建名为namefmt的线程,不过线程被创建后是处于不可运行状态的,我们可以通过wake_up_process()函数唤醒它。当然,也可以通过kthread_run()方法实现这一过程,相关的C语言代码如下,请看:
其实就是将kthread_create()函数和wake_up_process()函数组合到一起而已。Linux的内核线程被启动后,会一直运行到调用do_exit()退出。我们也可以调用kthread_stop()函数提前结束它,相关的C语言代码如下,请看:
kthread_stop()函数接收的参数为kthread_create()函数创建的结构体的task_struct成员。从C语言代码可以看出,kthread_stop()其实也是会调用wake_up_process()函数唤醒线程的,它在唤醒线程后,会等待线程函数退出,并不会调用threadfn()函数。
这里需要注意,如果创建的线程函数threadfn()调用了do_exit()函数,最好就不要再调用kthread_stop()函数了。
kthread_stop()函数等待线程退出是通过wait_for_completion()函数实现的,相关的C语言代码如下,请看:
稍稍跟踪一下C语言代码,发现其实这一等待过程是由do_wait_for_common()函数实现的,它的C语言代码如下,请看:
还是比较清晰的,这里就不再赘述了。至此,我们就了解了Linux内核是如何创建线程并投入运行,以及如何结束内核线程的了。
小结本节主要讨论了Linux内核中的线程的创建,应该能够看出,其实核心还是围绕对task_struct结构的管理,这与管理进程并无过多区别。因此,说Linux中的线程只是一种特殊的进程,一点也不为过。
从C语言代码分析,linux内核中“队列”是如何设计实现的
内核代码很简单的
需要多久才能看完linux内核源码
linux0.11的内核源码,结合下面这本书,我花了大概一个寒假(1个半月),看了一遍。
然而,现在的内核已经膨胀的不成样子了,以还不算最新的linux-4.9.229为例:
整个内核源码一共约801M:
驱动代码占了大概一半,大约407M:
体系相关的代码大约164M:
网路子系统相关的代码29M:
文件系统相关的代码38M:
linux内核核心代码大约7.7M:
但是就这7.7M,其实你要完全看完看懂也不容易。linux内核代码涉及c语言、硬件组成原理、操作系统、数据结构和算法等,这些基础知道你都具备了吗?如果没有具备,即使看完linux内核源码,你也看不懂liux内核的精髓。
linux内核源码大而全,一个人,即使再聪明、再有精力,也不可能完全看完、看懂所有的linux内核源码。你得选择一个主线进行深入研究,这些主线可以是:
linux内核启动过程研究linux驱动架构的学习和研究linux网络子系统的研究linux内存管理机制的研究linux调度器的学习和研究linux进程管理的学习和研究linux虚拟机制(kvm)的学习和研究linux内核实时化技术的研究沿着某一个主线,深入进去,在研究清楚这个主线的同时,向其他的主线扩展、渗透和学习。由点到线、由线到面、由面到体,层层深入、不断精进,是学习linux内核源码的一个有效的方法。
关注”技术简说“,带你由浅入深学习linux内核源码。linux内核开发100讲免费教程,每周二、周四晚上9点更新视频,每周一、周三晚9点更新文章,敬请收看。进我主页点”视频“栏目即可观看。
本人想学Linux内核,望高手有经验的人士推荐点书
《内核源代码情景分析》,毛德操,胡希明著,这本书讲的比较深,公认的经典。
我感觉比较浅些的《linux内核源代码》陈莉君写的那本,当然还有别的。
看内核以前应该有些操作系统的知识,x86硬件也要有一定的了解,最好再有些Linux应用程序的了解,这样看起来更容易些,个人感觉。
关于linux内核原理的入门书籍有哪些值得推荐的
谢小编邀。
@云瑄软件回答的已经很全面了,他推荐的几本书都是内核入门经典中的经典。
我再推荐几本接触过好书:
《linux设备驱动程序》JonathanCorbet著,讲内核设备驱动开发,对内核抽象层次,设备原理讲的很细,还介绍了不少内核开发调试的技巧。
《linux内核设计的艺术》中科院新设计团队著,这本书褒贬不一,但是书中对于一些内核的算法数据结构讲的很详细,对内核bootloader也讲了很多,对我帮助不少。
另外强烈推荐先过一遍《深入理解计算机系统》,这本书深入浅出,可以说是基本功中的基本功了。
最后的最后,如果想自己开发内核,推荐一个网站:osdev.org,这个网站几乎可以找到所有内核开发的资料。
共勉。
好了,文章到此结束,希望可以帮助到大家。
本文链接:http://xinin56.com/kaifa/9115.html