这里记录了我学习Linux kernel的历程和心得.是对我的学习的一个总结,也是对我的一种鞭策.
Vim_Chinese_Documentation
另外,对于Linux,可以将多个文件系统 mount 到同一个目录上,这样的话, 新 mount
的文件系统会覆盖原来mount的文件系统。
比如我们再把一个 '/dve/hdb2' 的设备 mount 到 '/home/xpl'
这样,如果我们访问 '/home/xpl' 的时候,就会访问到 '/dev/hdb2'
当新mount的文件系统被 unmount 之后,原来被覆盖的文件系统就会再次显露出来了。
这个过程的之所以是这样的,是因为在路径查找的时候,如果发现要查找的目录上mount了
文件系统(其dentry的d_mounted 不为0),会切换文件系统。
比如我们上面的例子,当路径查找 '/home/xpl' 的时候,当查找到根文件系统的目录 'xpl'
的dentry时,发现有一个文件系统已经mount到这个目录上,就会切换文件系统,进而找到 '/dev/hdb1' 的根目录的
dentry
这样,路径查找'/home/xpl' 返回的时候,返回的是 '/dve/hdb1' 根目录的 dentry
这样,在我们 mount 第二个文件系统 '/dev/hdb2' 的时候,其mountpoint 就是 '/dev/hdb1'
的根目录的 dentry。
这个过程如下图所示:
找到了要 mount 的目录,下面就开始实际的mount过程
mount的过程就是把设备的文件系统加入到 vfs 框架中
1. 首先,要mount一个新的设备,需要创建一个新的 super block。
2. 对于任何一个 mount 的文件系统,都要有一个 vfsmount, 创建这个vfsmount, 并设置好其属性(就是 vfsmount 中的各个成员)
3. 将创建好的 vfsmount 加入到系统中。
整个过程如下所示:
mount 文件系统
主要数据结构:
struct namespace {
};
struct vfsmount
{
前面我们介绍了高速缓存的基本概念,下面我们将介绍它和memory中的页框是如何关联到一起的.
slab alloctor是通过buddy alloctor来申请页框的.
这在 kmem_cache_alloc()
中,通过调用kmem_getpages();而kmem_getpages()又会相应的调用alloc_pages().
当一个页框被分配给slab之后,page->flag 中的 PG_slab会被置位.同时,该page描述符的lru会分别指向相应的cache和slab, 如下图所示:
主要数据结构:
struct kmem_cache_s {
Char Device Driver
相关数据结构:
struct cdev {
};
struct kobj_map {
};
static struct char_device_struct {
}
6. 切换数据
00014:
00015: __switch_data:
00016:
00017:
00018:
00019:
00020:
00021:
00022:
00023:
00024:
00025:
00026:
00034:
00035: __mmap_switched:
00036:
00037:
00038:
5. 开启mmu
r0 = c1 parameters
r4 =
pgtbl
r8 = machine info
r9 = cpu
id
4. 调用平台特定的 __cpu_flush 函数
当 __create_page_tables 返回之后
此时,一些特定寄存器的值如下所示:
r4 =
pgtbl
r8 = machine info
r9 = cpu
id
r10 =
procinfo
在我们需要在开启mmu之前,做一些必须的工作:清除ICache, 清除 DCache, 清除 Writebuffer,
清除TLB等.
这些一般是通过cp15协处理器来实现的,并且是平台相关的. 这就是 __cpu_flush 需要做的工作.
00091:
00092: &nb
3. 创建页表
通过前面的两步,我们已经确定了processor type 和 machine type.
此时,一些特定寄存器的值如下所示:
r8 = machine info
r9 = cpu
id
r10 =
procinfo
创建页表是通过函数 __create_page_tables 来实现的.
这里,我们使用的是arm的L1主页表,L1主页表也称为段页表(section page table)
L1 主页表将4 GB 的地址空间分成若干个1 MB的段(section),因此L1页表包含4096个页表项(section
entry). 每个页表项是32 bits(4 bytes)
因而L1主页表占用 4096 *4 = 16k的内存空间.