
Linux内核源代码情景分析
文章平均质量分 86
jltxgcy
热爱Android,热爱开源。
展开
-
Linux内核页面换入换出
0x00内存页面分类与换入换出规则 内存页面分为用户页面和内核页面。 用户页面有以下几种: 1、普通的用户空间页面,包括进程的代码段、数据段、堆栈段、以及动态分配的存储堆。 2、通过系统调用mmap()映射到用户空间的已打开文件的内容。 这些页面既涉及分配、使用和回收,也涉及页面的换出/换入。 内核页面有以下几种: 1、kmalloc分配用作某些临时性的数原创 2017-07-08 11:51:40 · 4199 阅读 · 0 评论 -
Linux内核源代码情景分析-mmap后,文件与虚拟区间建立映射
一、文件映射的页面换入 在mmap后,mmap参考Linux内核源代码情景分析-系统调用mmap(),当这个区间的一个页面首次受到访问时,会由于见面无映射而发生缺页异常,相应的异常处理程序do_no_page()。static inline int handle_pte_fault(struct mm_struct *mm, struct vm_area_struct * vma, uns原创 2015-04-22 20:22:13 · 1807 阅读 · 0 评论 -
Linux内核源代码情景分析-共享内存
一、库函数shmget()--共享内存区的创建与寻找asmlinkage long sys_shmget (key_t key, size_t size, int shmflg){ struct shmid_kernel *shp; int err, id = 0; down(&shm_ids.sem); if (key == IPC_PRIVATE) { err = newseg原创 2015-04-22 20:16:36 · 2844 阅读 · 0 评论 -
Linux内核源代码情景分析-文件的打开
打开文件的系统调用是open(),在内核中通过sys_open()实现,假设filename是"/usr/local/hello.c",且假设这个文件已经存在,代码如下:asmlinkage long sys_open(const char * filename, int flags, int mode){ char * tmp; int fd, error;#if BITS_PER_L原创 2015-04-03 10:56:42 · 1448 阅读 · 0 评论 -
Linux内核源代码情景分析-虚拟文件系统
我们先来看两张图: 第一张是VFS与具体文件系统的关系示意图: 第二张是Linux文件系统的层次结构: 特殊文件:用来实现”管道“的文件,特别是"命名管道"的FIFO文件,还有Unix域的socket,也都属于特殊文件;还有在/proc目录下的一系列文件。 磁盘文件:就是存在硬盘上的文件。 设备文件:sudo mount -t ext2 /dev/sdb1 /mnt/原创 2015-04-10 09:44:08 · 1991 阅读 · 0 评论 -
Linux内核源代码情景分析-进程间通信-命名管道
建立命名管道,mknod mypipe p。命名管道存在硬盘上,而管道不是。 通过open打开这个命名管道,在内核中通过sys_open()实现,filename是"***/mypipe "。 相关部分,请参考Linux内核源代码情景分析-文件的打开。 sys_open进入filp_open,然后在open_namei中调用一个函数path_walk(),根据文件的路径名在文件系原创 2015-04-10 08:44:14 · 1449 阅读 · 0 评论 -
Linux内核源代码情景分析-进程间通信-管道
一、我们先来介绍一下init_pipe_fs。static DECLARE_FSTYPE(pipe_fs_type, "pipefs", pipefs_read_super, FS_NOMOUNT|FS_SINGLE);static int __init init_pipe_fs(void){ int err = register_filesystem(&pipe_fs_type); if原创 2015-04-10 08:39:16 · 1769 阅读 · 0 评论 -
Linux内核源代码情景分析-文件的写
write对应的系统调用是sys_write,代码如下:asmlinkage ssize_t sys_write(unsigned int fd, const char * buf, size_t count){ ssize_t ret; struct file * file; ret = -EBADF; file = fget(fd); if (file) { if (file原创 2015-04-03 19:05:44 · 1656 阅读 · 0 评论 -
Linux内核源代码情景分析-从路径名到目标节点
先看外包装,__user_walk,假设name为/usr/local/hello.cint __user_walk(const char *name, unsigned flags, struct nameidata *nd){ char *tmp; int err; tmp = getname(name);//在系统空间分配一个页面,并从用户空间把文件名复制到这个页面 err =原创 2015-04-02 19:43:31 · 1949 阅读 · 0 评论 -
Linux内核源代码情景分析-特殊文件系统/proc
由于proc文件系统并不物理地存在于任何设备上,它的安装过程是特殊的。对proc文件系统不能直接通过mount()来安装,而要先由系统内核在内核初始化时自动地通过一个函数kern_mount()安装一次,然后再由处理系统初始化的进程通过mount()安装,实际上是"重安装"。 一、在内核初始化时调用init_proc_fs(),代码如下:static DECLARE_FSTYPE(proc_原创 2015-04-07 18:39:21 · 3069 阅读 · 0 评论 -
Linux内核源代码情景分析-特殊文件系统/proc-对/proc/self/cwd的访问
继上篇文章Linux内核源代码情景分析-特殊文件系统/proc,我们对/proc/loadavg访问后,这篇文章是对/proc/self/cwd的访问。int __user_walk(const char *name, unsigned flags, struct nameidata *nd){ char *tmp; int err; tmp = getname(name);//在系统空原创 2015-04-08 09:49:48 · 2718 阅读 · 0 评论 -
Linux进程与线程及其他知识点拾遗
0x00进程与线程的区别 进程和线程都是由父进程创建出来了,区别在于是否共享页表和页目录表。 进程是通过系统调用fork来创建的。使用全新的页表和页目录表,实行copy_on_write策略。asmlinkage int sys_fork(struct pt_regs regs) { return do_fork(SIGCHLD, regs.esp, ®s, 0)原创 2017-07-08 17:06:52 · 1105 阅读 · 1 评论 -
Linux内核源代码情景分析-fork()
父进程fork出子进程: fork经过系统调用,来到了sys_fork,详细过程请参考Linux内核源代码情景分析-系统调用。asmlinkage int sys_fork(struct pt_regs regs){ return do_fork(SIGCHLD, regs.esp, ®s, 0);}int do_fork(unsigned long clone_flags, u原创 2015-03-20 08:21:55 · 2165 阅读 · 0 评论 -
Linux内核源代码情景分析-insmod
看本文前,先看着篇文章,Linux字符设备驱动。 insmod,大体上所做的事,有这么一些: 1、打开待安装模块并将其读入到用户空间。所谓“模块”就是经过编译但未经连接的.o文件。 2、模块中必定有一些在模块内部无法落实的符号(函数名或变量名),对这些符号的引用必须连接到内核中的相应符号。为此目的,需要通过系统调用query_module向内核询问这些符号在内核中的地址。如果内核原创 2015-05-07 08:23:27 · 2363 阅读 · 0 评论 -
Linux内核源代码情景分析-系统初始化
我们跳过boot,setup,直接来到head代码,内核映像的起点是stext,也是_stext,引导和解压缩以后的整个映像放在内存从0x100000即1MB开始的区间。CPU执行内核映像的入口startup_32就在内核映像开头的地方,因此其物理地址也是0x100000。 然而,在正常运行时整个内核映像都应该在系统空间中,系统空间的虚拟地址与物理地址间有个固定的位移,这就是0xC00000原创 2015-05-20 09:04:52 · 1939 阅读 · 0 评论 -
Linux内核源代码情景分析-系统调用mknod
普通文件可以用open或者create创建,FIFO文件可以用pipe创建,mknod主要用于设备文件的创建。 在内核中,mknod是由sys_mknod实现的,代码如下:asmlinkage long sys_mknod(const char * filename, int mode, dev_t dev) //比如filename为/tmp/server_socket,dev是设备号{原创 2015-05-05 20:25:03 · 2786 阅读 · 0 评论 -
Linux内核源代码情景分析-设备文件系统devfs
我们以前多次讲过到,以主设备号/次设备号为基础的设备文件管理方式是有根本性的缺点的。这种从Unix早期原创 2015-05-09 16:02:00 · 2204 阅读 · 0 评论 -
Linux内核源代码情景分析-系统调用select以及异步输入/输出
一、系统调用select,把原来当前进程的单睡眠等待状态变成了现在的多睡眠等待状态。具体请看代码,select在内核中的实现为sys_select,代码如下:asmlinkage longsys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval *tvp)//inp,outp,exp是关于已打开文件的位图,t原创 2015-05-08 08:40:28 · 2064 阅读 · 0 评论 -
Linux内核源代码情景分析-信号
一、我们先来看下信号的所设计的数据结构:struct task_struct { int sigpending; int exit_code, exit_signal; /* Protects signal and blocked */ struct signal_struct *sig; sigset_t blocked; struct sigpending pending;原创 2015-04-21 09:22:26 · 3120 阅读 · 0 评论 -
Linux内核源代码情景分析-execve()
子进程开始执行execve: execve("/bin/echo", args, NULL}); 系统调用execve内核入口是sys_execve,代码如下:asmlinkage int sys_execve(struct pt_regs regs){ int error; char * filename; filename = getname((char *) regs.原创 2015-03-20 19:25:52 · 4496 阅读 · 0 评论 -
Linux内核源代码情景分析-访问权限与文件安全性
在Linux内核源代码情景分析-从路径名到目标节点,一文中path_walk代码中,err = permission(inode, MAY_EXEC)当前进程是否可以访问这个节点,代码如下:int permission(struct inode * inode,int mask){ if (inode->i_op && inode->i_op->permission) { int retv原创 2015-04-02 19:46:43 · 2114 阅读 · 1 评论 -
Linux内核源代码情景分析-文件系统安装后的访问
在Linux内核源代码情景分析-文件系统的安装,一文中,已经调用sudo mount -t ext2 /dev/sdb1 /mnt/sdb,在/mnt/sdb节点上挂载了文件系统,那么我们接下来访问/mnt/sdb/hello.c节点。我们来看一下path_walk的执行有什么不同?int path_walk(const char * name, struct nameidata *nd){原创 2015-04-02 20:33:22 · 1460 阅读 · 0 评论 -
Linux内核源代码情景分析-系统调用brk()
首先看下进程地址空间示意图: 我们简单的说,从低地址到高地址,代码区和数据区,空洞,堆栈区。 在Linux内核源代码情景分析-内存管理之用户堆栈的扩展,我们申请了从堆栈区往下,数据区上面的页面。 在Linux内核源代码情景分析-内存管理之用户页面的换入,我们申请了用于换入/换出的页面。 在本文中,我们申请的是从数据区往上,堆栈区下面的页面。 我们通过一个实例来分析,b原创 2015-03-09 08:33:51 · 7531 阅读 · 0 评论 -
Linux内核源代码情景分析-内存管理
用户空间的页面有下面几种: 1、普通的用户空间页面,包括进程的代码段、数据段、堆栈段、以及动态分配的“存储堆”。 2、通过系统调用mmap()映射到用户空间的已打开文件的内容。 3、进程间的共享内存区。 这些页面的的周转有两方面的意思。 1、页面的分配,使用,回收。如进程压栈时新申请的页面,这类页面不进行盘区交换,不使用时释放得以回收。 这部分通过一个场景来解释原创 2015-03-01 09:48:54 · 1365 阅读 · 0 评论 -
Linux内核源代码情景分析-外部设备存储空间的地址映射
随着计算机技术的发展,人们发现单纯的I/O映射方式是不能满足要求的。此种方式只适合于早期的计算机技术,那时候一个外设通常都只有几个寄存器,通过这几个寄存器就可以完成对外设的所有操作了。而现在的情况却不大一样。例如,在PC机上可以插上一块图像卡,带有2MB的存储器,甚至还可能带有一块ROM,里面装有可执行代码。所以要将外设卡上的存储器映射到内存空间,实际上是虚拟空间的手段。在Linux内核中,这样的原创 2015-03-06 09:04:25 · 1572 阅读 · 0 评论 -
Linux内核源代码情景分析-内存管理之slab-分配与释放
首先说缓存区的数据结构:struct kmem_cache_s {/* 1) each alloc & free */ /* full, partial first, then free */ struct list_head slabs;//指向所有的slab块链表,前面是完全块,然后是非完全块,最后是空闲块 struct list_head *firstnotfull;//指向第一个非原创 2015-03-04 19:32:08 · 2370 阅读 · 1 评论 -
Linux内核源代码情景分析-内存管理之slab-回收
在上一篇文章Linux内核源代码情景分析-内存管理之slab-分配与释放,最后形成了如下图的结构: 图 1 我们看到空闲slab块占用的若干页面,不会自己释放;我们是通过kmem_ca原创 2015-03-04 19:31:59 · 1543 阅读 · 0 评论 -
Linux内核源代码情景分析-内存管理之恢复映射
refill_inactive_scan和swap_out,把活跃的页面变成不活跃脏的页面。挑选的原则是最近没有被访问,且age小于0。 page_launder,把不活跃脏的页面变成不活跃干净的页面。 不活跃脏的页面,有如下特点: 使用计数为1; page->list链入mapping->dirty_pages/clean_pages; page->next_has原创 2015-03-04 09:10:35 · 1113 阅读 · 0 评论 -
Linux内核源代码情景分析-内存管理之用户堆栈的扩展
在下面几种情况下会发生,页面出错异常(也叫缺页中断): 1、相应的页面目录项或者页面表项为空,也就是该线性地址与物理地址的映射关系尚未建立,或者已经撤销。本文讨论的就是这种情况。 2、相应的物理页面不在内存中。 3、指令中规定的访问方式与页面的权限不符,例如企图写一个“只读”的页面。 首先看下进程地址空间示意图:原创 2015-03-01 12:10:36 · 1659 阅读 · 0 评论 -
Linux内核源代码情景分析-内存管理之用户页面的换入
在下面几种情况下会发生,页面出错异常(也叫缺页中断): 1、相应的页面目录项或者页面表项为空,也就是该线性地址与物理地址的映射关系尚未建立,或者已经撤销。 2、相应的物理页面不在内存中。 本文讨论的就是这种情况。 3、指令中规定的访问方式与页面的权限不符,例如企图写一个“只读”的页面。 假设已经建立好了映射,但是页表项最后一位P为0,表示页面不在内存中;整个页表项如下图,原创 2015-03-01 17:06:13 · 2603 阅读 · 0 评论 -
Linux内核源代码情景分析-内存管理之用户页面的定期换出
我们已经看到在分配ni原创 2015-03-02 18:01:43 · 2682 阅读 · 0 评论 -
Linux内核源代码情景分析-系统调用mmap()
一个进程可以系统调用mmap(),将一个已打开文件的内容映射到它的用户空间,其用户界面为: mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)。 参数fd代表着一个已打开文件,offset为文件中的起点,而start为映射到用户空间中的起始地址,length则为长度。还有两个参数prot原创 2015-03-09 09:13:36 · 4975 阅读 · 2 评论 -
Linux内核源代码情景分析-exit()
执行完/bin/echo之后,会调动do_exit,销毁子进程: 我们还是先从系统调用exit()说起,先来看exit()的实现,进入到内核态执行sys_exit。asmlinkage long sys_exit(int error_code){ do_exit((error_code&0xff) 8);}NORET_TYPE void do_exit(long code){ st原创 2015-03-21 10:37:58 · 2588 阅读 · 0 评论 -
Linux内核源代码情景分析-文件系统的安装
执行sudo mount -t ext2 /dev/sdb1 /mnt/sdb,将文件系统挂在到/mnt/sdb上。系统调用mount,映射到内核层执行的是sys_mount。假设/dev/sdb1和/mnt/sdb都位于ext2文件系统中。asmlinkage long sys_mount(char * dev_name, char * dir_name, char * type, u原创 2015-04-02 19:44:50 · 2566 阅读 · 0 评论 -
Linux内核源代码情景分析-系统调用
一、系统调用初始化void __init trap_init(void){ ...... set_system_gate(SYSCALL_VECTOR,&system_call);//0x80 ......} 对0x80中断向量,设置了系统调用的总入口system_call。static void __init set_system_gate(unsigned in原创 2015-03-13 18:46:35 · 2085 阅读 · 0 评论 -
Linux内核源代码情景分析-nanosleep()和pause()
我们介绍nanosleep()和pause()两个系统调用。 系统调用nanosleep()在内核中的实现为sys_nanosleep(),代码如下:asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp)//第一个指针rqtp指向给定所需睡眠时间的数据结构;第二个指针rmtp,指向返回剩余时间的数原创 2015-03-22 12:54:45 · 2992 阅读 · 0 评论 -
Linux内核源代码情景分析-中断下半部(软中断)
Tasklet机制是一种较为特殊的软中断。Tasklet一词的原意是“小片任务”的意思,这里是指一小段可执行的代码,且通常以函数的形式出现。软中断向量HI_SOFTIRQ和TASKLET_SOFTIRQ均是用tasklet机制来实现的。 从某种程度上讲,tasklet机制是Linux内核对BH机制的一种扩展。在2.4内核引入了softirq机制后,原有的BH机制正是通过tasklet机制原创 2015-03-13 08:25:47 · 1297 阅读 · 0 评论 -
Linux内核源代码情景分析-强制性调度
Linux内核中进程的强制性调度,也就是非自愿的、被动的、剥夺式的调度,主要是由时间引起的。前面讲过这种调度发生在中断,异常,系统调用从系统空间返回用户空间的前夕,也就是在ret_with_reschedule可以看出,此时是否真的调用schedule(),最终还要取决于当前进程task_struct结构中的need_resched是否为1(非0),因此,问题就结为当前进程的need_resche原创 2015-03-21 17:40:19 · 1342 阅读 · 0 评论 -
Linux内核源代码情景分析-异常
一、异常初始化 中断向量表的IDT的初始化void __init trap_init(void){#ifdef CONFIG_EISA if (isa_readl(0x0FFFD9) == 'E'+('I'<<8)+('S'<<16)+('A'<<24)) EISA_bus = 1;#endif set_trap_gate(0,÷_error); set_trap_gate原创 2015-03-13 09:31:55 · 1274 阅读 · 0 评论 -
Linux内核源代码情景分析-中断上半部
一、中断初始化 1、中断向量表IDT的初始化void __init init_IRQ(void){ int i;#ifndef CONFIG_X86_VISWS_APIC init_ISA_irqs();#else init_VISWS_APIC_irqs();#endif /* * Cover the whole vector space, no vector can原创 2015-03-13 08:25:26 · 1890 阅读 · 0 评论