Linux命令
基本shell命令
mount
cp:将一个档案copy到另一档案,或将数个档案copy至另一目录
通过VFS提供的系统调用接口进行文件操作
pwd:
cat
grep
find
ls
man: 帮助手册的章节,1-用户命令,2-系统调用,5-文件格式,8-关于系统维护的命令
Linux编译基本命令
make
config
基本概念
/proc:虚拟文件系统,在这里可以获取系统状态信息并且修改系统的某些配置信息
如内存情况在/proc/meminfo文件中
vfs:存在于内存空间,根据不同的文件系统抽象出了一个通用的文件模型,由四种数据对象组成:
- 超级块对象superblock:存储已安装文件系统的信息,通常对应磁盘文件系统的文件系统超级块或者控制块
- 索引节点对象inode object:存储某个文件的信息。通常对应磁盘文件系统的文件控制块。
- 目录项对象dentry object:dentry对象主要是描述一个目录项,是路径的组成部分。
- 文件对象file object:存储一个打开文件和一个进程的关联信息。只要文件一直打开,这个对象就一直存在。
task_struct:进程控制块PCB,是进程存在的唯一标志。
- struct mm_struct *mm //进程的虚存信息
- struct fs_struct *fs //进程的可执行映象所在的文件系统
- struct files_struct *files //进程打开的文件
内核编译
添加系统调用mysyscall:每发生一次缺页都要进入缺页中断服务函数do_page_fault一次,所以可以认为该函数的次数就是发生缺页的次数
缺页中断调用机理
缺页中断矢量设置(3分)
区分是页面异常(地址非法,访问权限等)还是缺页(3分)
Linux的页面管理,虚拟地址段管理,换页等(4分)
进程状态转换
进程是由正文段、用户数据段和系统数据段、堆栈段组成的一个动态实体
fork()函数进程创建过程
- 为新进程分配task_struct内存空间
- 把父进程task_struct拷贝到子进程的task_struct
- 为新进程在其虚拟内存建立内核堆栈
- 对子进程task_struct中部分进行初始化设置
- 把父进程的有关信息拷贝给子进程,建立共享关系
- 把子进程的counter设为父进程counter值的一半
- 把子进程加入到可运行队列中
- 结束do_fork()函数返回PID值
do_fork()函数
三个系统调用实现创建子进程都会调用do_fork()函数
- sys_clone():对应的clone_flags可能是多个标志位的组合,取决于具体情况
- sys_vfork():对应的clone_flags值是SIGCHIILD。SIGCHILD的作用是子进程终结或暂停时给父进程发信号。
- sys_fork():对应的clone_flags值是CLONE_VFORK|CLONE_VM|SIGCHILD
do_fork()的执行过程
- 调用alloc_task_struct()分配子进程task_struct空间。
- 把父进程task_struct的值全部赋给子进程task_struct。
- 检查是否超过了资源限制,如果是,则结束并返回出错信息。更改一些统计量的信息。
- 修改子进程task_struct的某些成员的值使其正确反映子进程的状况,如进程状态被置成TASK_UNINTERRUPTIBLE。
- 调用get_pid()函数为子进程得到一个pid号。
- 共享或复制父进程文件处理、信号处理及进程虚拟地址空间等资源。
- 调用copy_process()初始化子进程的内核栈,内核栈保存了进程返回用户空间的上文。(以i386为例,其中很重要的一点是寄存器eax值的位置被置0,这个值就是执行系统调用后子进程的返回值。)
- 将父进程的当前的时间配额counter分一半给子进程。
- 利用宏SET_LINKS将子进程插入所有进程都在其中的双向链表。调用hash_pid(),将子进程加入相应的hash队列。
- 调用wake_up_process(),将该子进程插入可运行队列。至此,子进程创建完毕,并在可运行队列中等待被调度执行。
- 如果clone_flags包含有CLONE_VFORK标志,则将父进程挂起直到子进程释放进程空间。(进程控制块中有 一个信号量vfork_sem可以起到将进程挂起的作用。)
- 返回子进程的pid值,该值就是系统调用后父进程的返回值。
文件系统mount命令
语法:
mount [-t fstype] [-o options] device dirname
内核与之对应的系统调用是sys_mount()。该函数根据文件 系统类型得到相应的file_system_type 对象,再取得该分区 的超级块对象。
系统中断
导致缺页异常(缺页中断)的原因有:
- 编程错误。可分为内核程序错误和用户程序错误
- 操作系统故意引发的异常。操作系统利用硬件机制,在适当时间触发异常,使得该异常的处理程序被调用,以达到预期目的。
补充:
- do_page_fault()得到的异常发生虚拟地址对于IA32在CR2寄存器中;此函数执行次数可认为系统发生缺页
- 每个进程都有一个页目录,当进程运行时,寄存器CR3指向该页目录的地址。
- 系统三级页表:
- 页目录PGD
- 页中间目录PMD
- 页表PTE
- 2.6.11以后Linux采用四级页表模型来使用硬件分页机制,分别是:pgd_t,pud_t,pmd_t,pte_t
- Linux使用两个运行模式:特权级0和特权级3,即内核模式和用户模式
- 每个系统调用号至少有一个参数,即通过eax寄存器传递来的系统调用号
- Linux利用守护进程kswapd定期检查系统内的空闲页帧数是否小于预定义的极限,一旦发现空闲帧数太少,就先将若干页换出。kswapd相当于一个进程,它有自己的进程控制块task_struct结构,与其他进程一样同样受内核调度,但没有独立的地址空间
写时拷贝的处理过程
- 首先改写对应页表项的访问标志位,表明其刚被访问过,
这样在页面调度时该页面就不会被优先考虑。 - 如果该页帧目前只为一个进程单独使用,则只需把页表项置为可写。
- 如果该页帧为多个进程共享,则申请一个新的物理页帧并 标记为可写,复制原来物理页帧的内容,更改当前进程相应的页表项,同时原来的物理页帧的共享计数减一。
- 首先改写对应页表项的访问标志位,表明其刚被访问过,
按需调页的处理过程
- 第一种情况页面从未被进程访问,这种情况页表项的值全部为0
- 另一种情况是该页面被进程访问过,但是目前已被写到交换 分区, 页表项的存在标志位为0,但其他位被用来记录该页 面在交换分区中的信息。
伙伴系统的操作:
- 申请空间的函数为alloc_pages( );
- 释放函数为free_pages( );
- 当在申请内存发现页帧短缺时,还会唤醒kswapd内核线程运行,该线程会腾出一些空间以满足要求。