![](https://img-blog.csdnimg.cn/20201014180756913.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Linux
文章平均质量分 73
vanquishedzxl
这个作者很懒,什么都没留下…
展开
-
http://blog.csdn.net/joshua_yu/article/details/631915
一、fork入门知识 一个进程,包括代码、数据和分配给进程的资源。fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。 一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进转载 2013-10-31 22:14:36 · 667 阅读 · 0 评论 -
Linux kernel 分析之十五:kbuild系统-make menuconfig
理解了make bzImage的过程,理解了整个kbuild的结构和运行机制,make menuconfig的过程就很容易理解了。先看/usr/src/linux/Makefile。可以找到:452 %config: scripts_basic outputmakefile FORCE453 $(Q)$(MAKE) $(build)=scripts/kconfig $@%c原创 2015-07-22 22:51:31 · 1060 阅读 · 0 评论 -
Linux kernel 分析之九:fork()系统调用
不仅进入系统调用时要伪装现场,fork系统调用时返回时也需要伪装现场。因为是“无中生有”。例如在fork创建新进程时,系统要保证新进程与旧进程一样,从相同的代码开始执行。比如:#include#includeint main(){ pid_t pid; if((pid=fork())>0) {原创 2015-07-22 21:28:00 · 1389 阅读 · 0 评论 -
Linux kernel 分析之十二:kbuild系统-内核模块的编译
段错误么?这里涉及到PIII中用sysenter来代替系统调用的int 0x80的问题。大概就是内核允许一部分代码给用户态进程访问。例如:cat /proc/$pid/maps可以看到:ffffe000-fffff000 ---p 00000000 00:00 0 [vdso]ldd 一个应用程序也可以看到:linux-gate.so.1 => (0xffffe00原创 2015-07-22 22:39:11 · 1609 阅读 · 0 评论 -
Linux kernel 分析之十一:信号通信
信号是进程之间通信的一种方式。它包括3部分操作:1.设置信号处理函数。系统调用signal。内核调用sys_signal(),设置当前进程对某信号的处理函数。2.发送信号.系统调用kill。内核调用sys_kill()。向目标进程发送信号。3.接收并处理信号。目标进程调用do_signal()处理信号。从用户态的角度看,目标进程在执行用户态的代码时突然“中断”,转而去执行对应的信号处理原创 2015-07-22 22:33:42 · 2928 阅读 · 0 评论 -
Linux kernel 分析之十七:设计模式-用C来实现继承和模板
多态实现了,封装呢?基本上,C的结构体是不设防的,谁都可以访问。从这一点来看,C很难实现封装。尽管C中有static关键字,可以保证函数和变量的作用仅限于本文件,尽管内核可以通过控制导出符号表(EXPORT_SYMBOL)来控制提供给下层模块的函数和变量,但这些与C++中的封装相去甚远。好在内核的原则是“相信内核不会自己伤害自己”。所以就不苛求啦。那么继承呢?这个也基本上很难。不过我们可以通过原创 2015-07-22 23:00:20 · 1886 阅读 · 0 评论 -
Linux kernel 分析之十四:kbuild系统-make bzImage的过程
从以上例子中可以看到,内核的编译系统kbuild是个很庞大的系统。但是,它所使用的make和我们平时用的make是一模一样的。kbuild只是通过预定义一些变量(obj-m,obj-y等等)和目标(bzImage ,menuconfig等等),使内核的编译和扩展变得十分方便。我们不妨yy一下kbuild的一些功能:1.考虑到Linux能够方便地移植到各个硬件平台,kbuild也必须很容易添加对原创 2015-07-22 22:49:11 · 1034 阅读 · 0 评论 -
Linux kernel 分析之十八:设计模式-文件系统与抽象工厂
抽象工厂的典型应用是在gui设计中。为了在运行时方便地替换不同风格的gui设计,我们需要在上层把每种不同风格的gui的实现细节隐藏起来。我们不再显式地调用gui中的某个组件的构造函数,因为这样暴露了组件的实现。相反,我们为每一个风格提供一个“工厂”来生产该风格的“产品”。抽象工厂可以看作是面向对象设计中常用的多态思想的扩展。普通的多态只是针对一个“产品”,如shape抽象类。而抽象工厂是针对一原创 2015-07-23 22:01:38 · 1068 阅读 · 0 评论 -
Linux kernel 分析之十九:阅读源代码技巧-变量命名规则
在阅读源代码的时候,经常会发现在跟踪函数调用时跟踪不下去了,如result = dir->i_op->lookup(parent_inode, child_dentry, nd);这类似于C++中的多态。inode_operations中的lookup函数指针具体指向哪个函数,不是在编译时确定的,而是在运行期确定的。具体地说,就是在从磁盘上读入inode时才对对应inode的inode_ope原创 2015-07-23 22:08:21 · 4048 阅读 · 0 评论 -
Linux kernel 分析之二十:内存管理-内核中的页表映射总结
从线性地址到物理地址的转换,实际上是一种映射。所有进程的3~4G的线性地址实际上是映射到相同的物理地址的。这一点不多说了。为了方便起见,3~4G的线性地址与对应的物理地址基本上是呈线性关系的。即线性地址=物理地址+3G。但是如果把这1G的线性地址都简单地处理为对应物理地址+3G,就会有新的问题产生。例如,如果物理地址大于4G,那么内核就没法访问这些地址了。所以,内核必须要从这1G的线性空间中预原创 2015-07-23 22:12:07 · 3173 阅读 · 1 评论 -
Linux kernel 分析之二十一:定时器-巧妙的定时器算法
内核中经常要用到各种定时器。比如nanosleep()系统调用,让当前进程睡眠一段时间,再把它唤醒。即在expires时刻(以时钟滴答为单位),自动调用wake_up_process。最直接的思路是定义一个定时器,里面有function(函数指针),data(函数参数),expires(调用时刻)。然后排成一个链表。每次时钟中断发生时,扫描整个链表,发现有触发的定时器,就调用function(da原创 2015-07-23 22:16:15 · 1398 阅读 · 0 评论 -
Linux kernel 分析之十三:kbuild系统-编译到内核和编译成模块的区别
代码编译到内核和编译成模块在代码中有什么区别呢?从模块的代码中看是一样的。入口函数都是module_init(fun),但是代码中的条件编译会使宏module_init()在编译到内核和编译成模块的情况下替换成不同的代码。include/linux/init.h中可知#ifndef MODULE...#define module_init(x) __initcall(x);...原创 2015-07-22 22:44:15 · 1068 阅读 · 0 评论 -
Linux kernel 分析之十六:文件系统-用C来实现面向对象
电脑用户跟文件系统打交道是非常频繁的。不过文件系统在结构上应该属于哪一层呢?它和设备驱动的关系如何?不同的系统有不同的理解。Linux把文件系统放在设备驱动之上,访问普通文件时,系统先执行文件系统的代码,把文件指针的偏移量映射为块设备的偏移量,然后调用驱动程序的代码。另一方面,Linux把设备也看作是一种特殊的文件。这有助于简化接口,对程序员来说是很方便的。 我们可以把接口的观点原创 2015-07-22 22:55:55 · 1188 阅读 · 0 评论 -
Linux kernel 分析之二:main函数执行启动过程
内核是从哪里开始执行的呢?几乎任何一本Linux内核源代码分析的书都会给出详细的答案。不过,我试图从一个不同的角度(一个初学者的角度)来叙述,而不是一上来就给出答案。从熟悉的事物入手,慢慢接近陌生的事物,这是比较常见的思路。既然都是二进制代码,那么不妨从最简单的用户态C程序,hello world开始。说不定能找到共同点。恰好我是一个喜欢寻根究底的人。也许,理解了hello world程序的启动过原创 2015-07-21 21:30:47 · 3676 阅读 · 0 评论 -
Linux kernel 分析之三:加电BIOS启动
Linux内核为什么不是从main函数开始执行? 事实上,Linux内核源代码里有许多main()函数,但仔细一看。他们都是运行在用户态的。其实,从上一节中可以看到,main()函数只是一个符号而已。很多书上提到start_kernel()。它类似于main()。但正如调用main()的是_start()。在start_kernel之前仍然有很多代码。所以内核的真正入口并不是start_原创 2015-07-21 21:39:47 · 1145 阅读 · 0 评论 -
Linux kernel 分析之一:内核镜像
跌跌撞撞的在软件开发行业这么久了,各种语言也都见识过了各种平台也都差不多见识了一下,但都了解不够深入,唯独对Linux内核知之甚少,想想今天开始学习还来得及,所以Just do it....原创 2015-07-19 22:00:26 · 4974 阅读 · 0 评论 -
Linux kernel 分析之四:setup辅助程序
我们发现,在起点与终点之间,还有几个中转站。最近的一站叫作MBR。BIOS,带你到MBR后,说:“对不起,只能送你到这里了。” 那其它几个中转站是什么呢?我们知道,在x86上,保护模式有两种,32位页式寻址的保护模式和32位段式寻址的保护模式。显然,32位页式寻址的保护模式要求系统中已经构造好页表。从16位实地址模式直接到32位页式寻址的保护模式是很有难度的,因为你要在16位实地址模式下原创 2015-07-21 21:56:55 · 1302 阅读 · 0 评论 -
Linux kernel 分析之六:内核启动-开启页面映射
在setup的帮助下,我们顺利地从16位实地址模式过渡到32位段式寻址的保护模式。又在arch/i386/boot/compressed/head.S的帮助下实现了内核的自解压,并且从arch/i386/kernel/head.S中的startup_32开始。现在在线性地址0x100000(1M)处开始就是我们的解压后的内核了。而startup_32()的地址恰好是0x100000。由于还没有开启原创 2015-07-21 22:16:32 · 991 阅读 · 0 评论 -
Linux kernel 分析之五:内核启动-内核解压缩
这得从vmliux.bin的产生过程说起。从内核的生成过程来看内核的链接主要有三步:第一步是把内核的源代码编译成.o文件,然后链接,这一步,链接的是arch/i386/kernel/head.S,生成的是vmlinux。注意的是这里的所有变量地址都是32位页寻址方式的保护模式下的虚拟地址。通常在3G以上。/* * linux/arch/i386/kernel/head.S --原创 2015-07-21 22:05:37 · 3628 阅读 · 0 评论 -
Linux kernel 分析之七:内核启动-链接脚本
一般来说,用户是不需要关心section的具体位置的。在用户态,内核会解析elf可执行文件的各个section,然后把它映射到虚拟地址空间。然而,在内核启动时,一切得从 零开始。很多在用户态下应用程序不需要操心的东西,例如映射section的任务不得不由内核自己来完成。上一篇感悟揭示了内核如何建立页表,并且把自身的一部分映射到虚拟地址。内核还要负责对BSS段(所有在代码中未定义的全局变量)的初原创 2015-07-21 22:20:18 · 2428 阅读 · 0 评论 -
Linux kernel 分析之八:系统调用参数
内核支配了整个计算机的硬件资源,好像一位独裁者,高高在上。他有时候必须像法官一样公正,有时候则必须像狐狸一样狡猾。伪装现场就是他的拿手好戏。系统调用是很特别的函数,因为它里面实现了用户态到内核态的转换。应用程序要创建新进程,不可能在用户态直接调用sys_fork()。这就需要内核为sys_fork()伪装一下调用现场。比如fork()系统调用,它有一个简洁得不能再简洁的接口。不过它在内核中原创 2015-07-21 22:23:32 · 850 阅读 · 0 评论 -
Linux kernel 分析之十:内核线程
众所周知,内核中创建一个内核线程是通过kernel_thread实现的。声明如下: int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); 我们知道,用户态创建线程调用clone(),如果要在内核态创建线程,首先想到的是在内核态调用clone()。这是可以的。比如在init内核线程原创 2015-07-22 21:36:08 · 1753 阅读 · 0 评论 -
Linux kernel 分析之二十二:内存管理-page fault处理流程
page fault是Linux内存管理中比较关键的部分。理解了page fault的处理流程,有助于对Linux内核的内存管理机制的全面理解。因为要考虑到各种异常情况,并且为了使内核健壮高效,所以page fault的处理流程是比较复杂的。我把这个繁琐的处理流程放在最后。在page fault处理函数中使用了很多lazy algorithm。它的核心思想是,由于磁盘IO非常耗时,所以把这些操作尽原创 2015-07-23 22:20:08 · 11421 阅读 · 3 评论