随笔分类 -  kernel

一些自己对内核的理解,没有笔记和翻译。
摘要:1、数据的存储 虽然从Ext2到Ext4,找数据的方式发生了变化,但是,磁盘的布局还是非常相似的。其实这个东西也不需要变化,因为现在也没什么特别巧妙的方式,而且磁盘的吞吐量、效率的瓶颈也不在这里。当然,这里排除那些根据自身文件特点设计的数据库,毕竟还是为了支持通用文件。磁盘布局如下: Boot在第一个块,放的应该是引导程序,超级块就放在了第二个块上,如果不是可以在mount的时候通过参数sb来设置。对于经常要访问(比较重要)的内容可以在每个块组中都存储(当然这是比较浪费空间的,所有有的只选择在部分),在不同的块组中访问这些内容的时候磁头移动的距离就小了。如果开启了sparse block功.. 阅读全文
posted @ 2011-10-28 10:41 GG大婶 阅读(3171) 评论(0) 推荐(1)
摘要:1、ext2_add_link的执行过程,函数的定义如下:int ext2_add_link (struct dentry *dentry, struct inode *inode){ struct inode *dir = dentry->d_parent->d_inode;//父节点的inode const char *name = dentry->d_name.name;//目录名 int namelen = dentry->d_name.len;//名字长度 unsigned chunk_size = ext2_chunk_size(dir);//块大小 ... 阅读全文
posted @ 2011-10-09 09:18 GG大婶 阅读(936) 评论(0) 推荐(0)
摘要:昨天晚上想了下slab中是没有bitmap的,那slab怎么知道哪些object是可用的?今天来看了一下感觉很有意思,slab把空闲的object放到了一个链表上。那为什么没有list_head?因为这个链表是用数组实现的。大概的结构如下:---------------------------个人理解,欢迎拍砖。 阅读全文
posted @ 2011-09-27 11:10 GG大婶 阅读(256) 评论(0) 推荐(0)
摘要:因为看内核的时候感觉红黑树挺有意思的,所以利用周末的时间来实现一下玩玩。红黑树的操作主要是插入和删除,而删除的时候需要考虑的情况更多一些。具体的操作就不在这里罗嗦了,百度文库里面有一个比较有好的文章,已经说的很明白了。 在看具体的操作的时候有的人可能感觉有些情况是没有考虑到的(如果没有这种感觉的人很有可能根本没有仔细地想)。但是那些“遗漏”的情况如果存在的话,操作之前的红黑树将违反那几个规则。 写代码的时候很多次因为少考虑情况而导致错误,细节比较多,刚开始rb_node中没有指向父节点的指针,写的快吐血,然后还是加上了。代码具体的含义可以结合文章和注释来看(还是很好理解的)。下面的代码中可能. 阅读全文
posted @ 2011-09-25 19:56 GG大婶 阅读(3615) 评论(3) 推荐(1)
摘要:很久没有写东西了,这几天看了下以前看过的东西,然后下午看了下内核中PST的实现。因为在网上很少,也找不到什么权威的分析,所以这里的分析也不能保证是完全正确的。先看相关的结构体:下面是PST的根:struct prio_tree_root { struct prio_tree_node *prio_tree_node; unsigned short index_bits; unsigned short raw;};嵌入到vm_area_struct中的结构:struct raw_prio_tree_nod... 阅读全文
posted @ 2011-09-21 19:58 GG大婶 阅读(1514) 评论(0) 推荐(0)
摘要:在刚开始看的时候感觉缺页异常(这可是异常啊,搞Java的人表示对着个比较敏感)肯定是一些进程在搞鬼,看完才发现原来是内核在搞鬼,它是故意的!!!1、请求调页 请求调页是一种动态分配内存的策略,把页面的分配推迟到不能再迟的时候(不能再迟的时候就是进程要访问的时候)。为什么要这样呢?RAM一般情况下都是很宝贵的资源,而且进程在一段的运行时间段中一般不会访问到所有的地址空间,到时发现page不在就引发一个缺页异常。这样的话就以一个异常处理周期长度的时间换来更多的RAM去做更重要的事情。1.0、如何引起请求调页 在发生访问一个线性地址的时候发生了错误进入do_page_faule函数,在判断出【发生在 阅读全文
posted @ 2011-08-22 21:48 GG大婶 阅读(2308) 评论(0) 推荐(0)
摘要:在进入正题之前先看看vmalloc是怎么申请内存的(虽然在前面的文章中已经说过了)。管理vmalloc分配空间用到的数据结构是vm_struct。首先用slab分配一个vm_struct实例,然后从vm_struct链表中找到一个合适的位置准备插入这个实例。这个实例只是用来管理这块内存的,那下面就开始申请这些内存,也就是一页一页地从buddy system中分配单页来填充一个page数组(这就是vmalloc分配得到的内存)。那怎么访问这些分配的内存呢?下面就逐层地建立pgd、pmd、pte结构中的值。释放vmalloc申请的空间的过程就是逆过来的。 下面进入正题! 在逐层建立pgd、pmd. 阅读全文
posted @ 2011-08-19 15:05 GG大婶 阅读(1884) 评论(1) 推荐(0)
摘要:在实际需要某个虚拟内存区的数据之前,虚拟和物理内存之间的关联是不会建立的,我们就默认程序不着急用,先去处理认为重要的事情。如果要访问一个页面这而它却不在物理内存中,处理器自动引发一个缺页异常,内核必须处理此异常。这时需要考虑的几个问题是:1、出错地址有什么特点?2、出错的地址有相对应的现有映射吗?3、要怎样获取该区域的数据? 看过代码(还有网上关于这块的流程图)之后感觉实在太复杂了。处理缺页异常的函数是void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)下面就沿着这个函数开始看内核是怎么处理的. 阅读全文
posted @ 2011-08-18 18:09 GG大婶 阅读(2343) 评论(2) 推荐(0)
摘要:管理用户虚拟地址空间的方法比内核地址空间复杂一些:每个应用程序都有自己的地址空间,与所有其他应用程序分开;地址空间巨大,只有很少的段可用于各个用户空间进程,这些段之间有一定的距离,内核需要有效的管理这些分配的段;内核无法信任用户程序,必须做检查;地址空间只有极少的一部分和物理页帧直接关联,不经常使用的部分只有在必要时与页帧关联。进程由不同长度的段组成用于不同的目的:当前运行代码的二进制代码段、程序使用的动态库的代码、全局变量和动态产生的数据的堆、用于保存局部变量和实现函数调用的栈、环境变量和命令行参数、文件内容。系统中的每个进程都用一个mm_struct结构来保存内存管理信息:struct m 阅读全文
posted @ 2011-08-15 22:23 GG大婶 阅读(2110) 评论(2) 推荐(1)
摘要:看内核的时候发现很多东西都处于似懂非懂的状态,比如MMU、TLB,甚至各个寄存器的作用,今天就认真地学习一下这些东西。首先先来看CPU的寄存器: 32位CPU中有4个数据寄存器,分别是EAX,EBX,ECX和EDX。数据寄存器用来保存操作数和运算结果,从而节省读取操作数所需占用总线和访问存储器的时间。EAX通常称为累加器,用累加器进行的操作可能需要更少的时间。可用于乘、除、输入/输出操作,使用频率很高。EBX称为基地址寄存器,可作为存储器指针来使用。ECX称为计数寄存器,在循环和字符串操作时,要用它来控制循环次数。在位移操作中,如果位移多位时用CL来指明位数。EDX称为数据寄存器,在进行乘除运 阅读全文
posted @ 2011-08-13 20:25 GG大婶 阅读(1448) 评论(0) 推荐(1)
摘要:为什么要用slab分配器?程序运行的很多时候并不是去分配一下大的内存,比如task_struct这样的小的结构,如果用伙伴系统来管理者部分的内存分配就太慢了。还有在调用伙伴系统那个的时候对系统的数据和指令高速缓存有相当的影响(slab会减少对伙伴系统的调用)。如果数据存储在伙伴系统提供的页中,那么其地址总是出现在2的幂次的整数倍附近,这对高速缓存的利用有负面影响,这种分布使得部分缓存使用过度,而其他的则几乎为空。每个缓存都定义为一个kmem_cache结构(该结构在内核中的其他地方不可见因为是放在.c中的 =.=):struct kmem_cache { struct array_cache. 阅读全文
posted @ 2011-08-11 18:00 GG大婶 阅读(1599) 评论(0) 推荐(0)
摘要:先看相关的变量的意思:enum km_type {D(0) KM_BOUNCE_READ,D(1) KM_SKB_SUNRPC_DATA,D(2) KM_SKB_DATA_SOFTIRQ,D(3) KM_USER0,D(4) KM_USER1,D(5) KM_BIO_SRC_IRQ,D(6) KM_BIO_DST_IRQ,D(7) KM_PTE0,D(8) KM_PTE1,D(9) KM_IRQ0,D(10) KM_IRQ1,D(11) KM_SOFTIRQ0,D(12) KM_SOFTIRQ1,D(13) KM_TYPE_NR};还有一个是:enum fixed_addresses { FI 阅读全文
posted @ 2011-08-10 14:39 GG大婶 阅读(578) 评论(0) 推荐(0)
摘要:使用kmap函数将高端页帧长期映射到内核地址空间中:/* 参数page是要映射的页 */void *kmap(struct page *page){ /* 判断是不是高端内存 */ if (!PageHighMem(page)) return page_address(page); might_sleep(); /* 建立映射 */ return kmap_high(page);}page_address根据page返回对应的线性地址,这个函数就是区分处理了一下高端内存和非高端内存:/* 取得对应的线性地址 */void *page_address(struct page *page){ un 阅读全文
posted @ 2011-08-10 10:32 GG大婶 阅读(1169) 评论(0) 推荐(0)
摘要:有时候虽然buddy system已经尽力去找了,但是仍旧找不到一大块内存时就要像用户进程一样使用处理器的分页机制了(虽然慢一点)。内核中“vmalloc”来分配在虚拟内存中连续但是物理内存中不一定连续的内存。管理这部分内存的结构为:/* 每个vmalloc分配的子区间都对应于内核内存中的一个vm_struct实例 */struct vm_struct { struct vm_struct *next; void *addr; /* 分配空间在虚拟地址中的起始地址 */ unsigned long size; /* 长度 */ unsigned long flags; /* 与给内存区关联的标 阅读全文
posted @ 2011-08-07 13:19 GG大婶 阅读(1478) 评论(0) 推荐(0)
摘要:伙伴系统已经出现很长一段时间了,有了一些优化,看了一下,比想象中的复杂很多啊。 1 static void __init_refok alloc_node_mem_map(struct pglist_data *pgdat) 2 { 3 /* 如果这个节点没有page,那就直接跳过这个节点*/ 4 if (!pgdat->node_spanned_pages) 5 return; 6 7 #ifdef CONFIG_FLAT_NODE_MEM_MAP 8 /* 用node_mem_map这个page用来管理mem_map */ 9 if (!pgdat->node_mem_map) 阅读全文
posted @ 2011-08-05 12:52 GG大婶 阅读(2173) 评论(3) 推荐(0)
摘要:bootmem分配器是系统初始化的时候用的内存分配器,用到的结构为: 30 typedef struct bootmem_data { 31 unsigned long node_boot_start; 32 unsigned long node_low_pfn; 33 void *node_bootmem_map; 34 unsigned long last_offset; 35 unsigned long last_pos; 36 unsigned long last_success; /* Previous allocation point. To speed 37 * up searc 阅读全文
posted @ 2011-07-31 23:47 GG大婶 阅读(1922) 评论(0) 推荐(1)