linux复习Word下载.docx
- 文档编号:17443354
- 上传时间:2022-12-01
- 格式:DOCX
- 页数:22
- 大小:67.29KB
linux复习Word下载.docx
《linux复习Word下载.docx》由会员分享,可在线阅读,更多相关《linux复习Word下载.docx(22页珍藏版)》请在冰豆网上搜索。
网络:
它提供了对各种网络标准协议的存取和各种网络硬件的支持,分为网络协议和网络驱动程序两部分;
E.
进程间通信:
支持进程间各种通信机制,包括共享内存、消息队列和管道等。
第二章内存寻址
1、在80x86的寄存器中,哪些寄存器供一般用户使用?
哪些寄存器只能被操作系统使用?
答:
通用寄存器EAX,EBX,ECX,EDX,EBP(基址指针),ESP(堆栈指针),ESI(扩展源指针),EDI(扩展目的指针),还有EFLAGS(标志寄存器).
专供操作系统使用的寄存器:
IDTR中断描述符寄存器,GDTR全局描述符表寄存器,LDTR局部描述符表寄存器,TaskRegisters任务寄存器,DebugRegister调试寄存器,ControlRegister控制寄存器,Model-SpecificRegisters模型专用寄存器。
4、Linux是如何利用段机制又巧妙的绕过段机制的?
在内核代码中如何表示各种段,查找最新源代码并进行阅读和分析。
IA32规定段机制是不可禁止的,因此不可能绕过它直接给出线性地址空间的地址。
万般无奈之下,Linux的设计人员干脆让段的基地址为0,而段的界限为4GB,这时任意给出一个偏移量,则等式为“0+偏移量=线性地址”,也就是说“偏移量=线性地址”。
另外由于段机制规定“偏移量<
4GB”,所以偏移量的范围为0H~FFFFFFFFH,这恰好是线性地址空间范围,也就是说虚拟地址直接映射到了线性地址,我们以后所提到的虚拟地址和线性地址指的也就是同一地址。
看来,Linux在没有回避段机制的情况下巧妙地把段机制给绕过去了。
另外,由于IA32段机制还规定,必须为代码段和数据段创建不同的段,所以Linux必须为代码段和数据段分别创建一个基地址为0,段界限为4GB的段描述符。
不仅如此,由于Linux内核运行在特权级0,而用户程序运行在特权级别3,根据IA32的段保护机制规定,特权级3的程序是无法访问特权级为0的段的,所以Linux必须为内核和用户程序分别创建其代码段和数据段。
这就意味着Linux必须创建4个段描述符——特权级0的代码段和数据段,特权级3的代码段和数据段。
2.12为什么在设计两级页表的线性结构时,给页目录和页表分别分配10位,如果不是这样举例说明会产生什么后果?
所谓两级页表就是对页表再进行分页。
页目录共有1K个表项,于是线性地址的最高10位(即22~31位)用来产生第一级的索引。
两级表结构的第二级称为页表,每个页表也刚好存放在一个4KB的页中,并且每一个页表包含1K的表项,第二级页表由线性地址中间的10位(即21~12位)进行索引,最低12位表示页内偏量。
14深入理解图2,12,并结合图叙述线性地址到物理地址的转换。
第一步,用32位线性地址的最高10位第31~22位作为页目录项的索引,将它乘以4,与CR3中页目录的起始地址相加,获得相应目录项在内存的地址;
第二步,从这个地址开始读取32位页目录项,取出其高20位,再给低12位补0,形成的32位就是页表在内存的起始地址;
第三步,用32位线性地址中的第21~12位作为页表中页表项的索引,将它乘以4,与页表的起始地址相加,获得相应页表项在内存的地址;
第四,从这个地址开始读取32位页表项,取出其高20位,再将线性地址的第11~0位放在低12位,最终形成32位页面物理地址。
第三章
15.什么是进程控制块,它包含哪些基本信息
1)Linux中把对进程的描述结构叫做task_struct,将这样的数据结构称作进程控制块(PCB);
系统为了管理进程设置的一个专门的数据结构,用它来记录进程的外部特征,描述进程的运动变化过程。
系统利用PCB来控制和管理进程,所以PCB是系统感知进程存在的唯一标志。
进程与PCB是一一对应的。
2)PCB是一个其域多达80多项的相当庞大的数据结构,按其功能将所有域划分为:
状态信息,链接信息、各种标识符、进程间通信信息、时间和定时器信息、调度信息、文件系统信息、虚拟内存信息和处理器环境信息
3.4linux内核状态有哪些,请画出状态转换图,查看最新源代码,确认有哪些状态。
1)Linux最基本的进程状态有三种:
运行态、就绪态和阻塞态(或等待态);
2)为了管理上的方便,就绪态(TASK_RUNNING);
睡眠(或等待)态:
浅度睡眠态(TASK_INTERRUPTIBLE),深度睡眠态(TASK_UNINTERRUPTIBLE);
暂停状态(TASK_STOPPED);
僵死状态(TASK_ZOMBIE)
3.6linux的进程控制块如何存放?
为什么?
假设ESP中存放的是栈顶指针,请用三句汇编语句描述如何获得current的PC的地址。
当进程一进入内核态,CPU就自动设置进程的内核栈。
这个栈位于内核的数据段上,为了节省空间,Linux把内核栈和一个紧挨近的PCB的小数据结构,thread_info放在一起,占用8kb的内存区。
因为这样可以节省空间,内核很容易从ESP寄存器的值获得,当前在CPU上正在运行的thread_info结构的地址。
movl$0xfffe000,%eax
andl%esp,%ecx
movl%ecx,p
3.7PCB的组织方式有哪几种?
为什么要采取这些组织方式?
答:
有进程链表、哈希表、就绪队列、等待队列四种组织方式,采取这些组织方式是为了能更有效的管理系统中大量的进程。
7、什么是写时复制技术,这种技术在什么情况下最能发挥其优势?
父进程和子进程共享页面而不是复制页面。
然而,只要页面被共享,它们就不能被修改。
无论父进程和子进程何时试图写一个共享的页面,就产生一个错误,这时内核就把这个页复制到一个新的页面中并标记为可写。
原来的页面仍然是写保护的:
当其它进程试图写入时,内核检查写进程是否是这个页面的唯一属主;
如果是,它把这个页面标记为对这个进程是可写的。
采用这种技术,显然只有预测到将要修改的页才会被复制,而且必须被复制,不然的话,就会破坏父进程的程序执行。
9、init内核线程与init进程是一回事吗?
它们有什么本质的区别?
(1)init()函数是内核代码的一部分,在内核态运行,是独立的可执行代码的一部分。
(2)init进程在Linux操作系统中是一个具有特殊意义的进程,它是由内核启动并运行的第一个用户进程,因此它不是运行在内核态,而是运行在用户态。
它的代码不是内核本身的一部分,而是存放在硬盘上可执行文件的映象中,和其他用户进程没有什么两样。
第四章
4.3内核空间存放什么内容?
如何把其中一个虚拟地址转换成物理地址?
内核空间存放的是内核代码和数据。
给定一个虚拟地址x,其物理地址为x-PAGE_OFFSET(一般为3GB,表示虚拟地址和物理地址之间的位移量)
4.4什么是内核映像?
它存放在物理空间和内核空间的什么地方?
内核空间由所有进程共享,其中存放的是内核代码和数据,即“内核映象”
Linux内核映像被装入在物理地址0x00100000开始的地方
内核映像在内核空间的起始地址就为0xC0100000。
4-5.用户空间划分为哪几部分?
用户程序调用malloc()分配的内存属于哪一部分?
分为堆栈段、BSS(未初始化的数据段)、数据段和代码段。
从数据段的顶部到堆栈段地址的下沿这个区间是一个巨大的空洞,这就是进程在运行时调用malloc()可以动态分配的空间,也叫动态内存或堆。
4-11.什么是虚存映射?
有哪几种类型?
Linux并不将映像装入到物理内存,相反,可执行文件只是被连接到进程的用户空间中。
随着进程的运行,被引用的程序部分会由操作系统装入到物理内存,这种将映像链接到进程用户空间的方法被称为“虚存映射”,也就是把文件从磁盘映射到进程的用户空间,这样把对文件的访问转化为对虚存区的访问。
有两种类型的虚存映射:
(1)共享的:
有几个进程共享这一映射,也就是说,如果一个进程对共享的虚存区进行写,其它进程都能感觉到,而且会修改磁盘上对应的文件。
(2)私有的:
进程创建的这种映射只是为了读文件,而不是写文件,因此,对虚存区的写操作不会修改磁盘上的文件,由此可以看出,私有映射的效率要比共享映射的高。
除了这两种映射外,如果映射与文件无关,就叫匿名映射。
7、Linux是如何实现“请求调页”的?
1)如果被访问的页不在内存,也就是说,这个页还没有被存放在任何一个物理页面中,那么,内核分配一个新的页面并将其适当地初始化,这种技术称为“请求调页”;
2)“请求调页”是一种动态内存分配技术,它将页面的分配推迟到不能再推迟为止,也就是说,一直推迟到进程要访问的页不在物理内存时为止,由此引起一个缺页异常;
该技术的引入主要是因为进程开始运行时并不访问其地址空间中的全部地址。
8、试叙述伙伴算法的工作原理,并说明为什么伙伴算法可以消除外碎片?
假设要求分配的块其大小为128个页面。
该算法先在块大小为128个页面的链表中查找,看是否有这样一个空闲块。
如果有,就直接分配;
如果没有,该算法会查找下一个更大的块,具体地说,就是在块大小为256个页面的链表中查找一个空闲块。
如果存在这样的空闲块,内核就把这256个页面分为两等份,一份分配出去,另一份插入到块大小为128个页面的链表中。
如果在块大小为256个页面的链表中也没有找到空闲页块,就继续找更大的块,即512个页面的块。
如果存在这样的块,内核就从512个页面的块中分出128个页面满足请求,然后从384个页面中取出256个页面插入到块大小为256个页面的链表中。
然后把剩余的128个页面插入到块大小为128个页面的链表中。
如果512个页面的链表中还没有空闲块,该算法就放弃分配,并发出出错信号。
9、vmalloc()和kmalloc()有何区别?
编写内核模块程序,调用这两个函数以观察二者所分配空间位于不同的区域。
在内核空间中调用kmalloc()分配连续物理空间,而调用vmalloc()分配非物理连续空间。
我们把kmalloc()所分配内核空间中的地址称为内核逻辑地址
把vmalloc()分配的内核空间中的地址称为内核虚拟地址
vmalloc()在分配过程中须更新内核页表
10、分析守护进程kswapd的运行时机,你认为怎样换出页面比较合理?
为了避免在CPU忙碌的时候,也就是在缺页异常发生时,临时搜索可供换出的内存页面并加以换出,Linux内核定期地检查系统内的空闲页面数是否小于预定义的极限,一旦发现空闲页面数太少,就预先将若干页面换出,以减轻缺页异常发生时系统所承受的负担。
当然,由于无法确切地预测页面的使用,即使这样做了也还可能出现缺页异常发生时内存依然没有足够的空闲页面。
但是,预换出毕竟能减少空闲页面不够用的概率。
并且通过选择适当的参数(如每隔多久换出一次,每次换出多少页),可以使临时寻找要换出页面的情况很少发生。
为此,Linux内核设置了一个定期将页面换出的守护进程kswapd。
第五章
5-2.什么是中断向量?
Linux是如何分配中断向量的?
Intelx86系列微机共支持256种向量中断,为使处理器较容易地识别每种中断源,将它们从0到256编号,即赋以一个中断类型码n,Intel把这个8位的无符号整数叫做一个向量,因此,也叫中断向量。
Linux对256个向量的分配如下:
(1)
从0~31的向量对应于异常和非屏蔽中断。
(2)
从32~47的向量(即由I/O设备引起的中断)分配给屏蔽中断。
剩余的从48~255的向量用来标识软中断。
Linux只用了其中的一个(即128或0x80向量)用来实现系统调用。
5-3.什么是中断描述符表?
啥是门描述符?
描述其格式。
在保护模式下,中断向量表中的表项由8个字节组成,中断向量表也改叫做中断描述符表IDT(InterruptDescriptorTable)。
其中的每个表项叫做一个门描述符(gatedescriptor),
5.6如何对中断描述符表进行初始化?
Linux内核在系统的初始化阶段要初始化可编程控制器8259A;
将中断描述符表的起始地址装入IDTR寄存器,并初始化表中的每一项,当计算机运行在实模式时,中断描述符表被初始化,并由BIOS使用。
真正进入Linux内核,中断描述符表就被移到内存的另一个区域,并为进入保护模式进行预初始化
5.7在中断描述符表中如何插入一个中断门、陷阱门和系统门?
插入一个中断门:
set_intr_gate(unsignedintn,void*addr)
Voidset_intr_gate(unsignedintn,void*addr)
{_set_gate(idt_table+n,14,0,addr);
}
插入一个陷阱门:
set_trap_gate(unsignedintn,void*addr)
Staticvoid_initset_trap(unsignedintn,void*addr){_set_gate(idt_table+n,15,0,addr);
}
插入一个系统门:
set_system_gate(unsignedintn,void*addr)
Staticset_system_gate(unsignedintn,void*addr){_set_gate(idt_table+n,15,3,addr)}
5、CPU为什么要进行有效性检查?
如何检查?
CPU是如何跳到中断或异常处理程序的?
有效性检查避免用户应用程序访问特殊的陷阱门或中断门。
当从用户态堆栈切换到内核态堆栈时,先把用户态堆栈的值压入中断程序的内核态堆栈中,同时把EFLAGS寄存器自动压栈,然后把被中断进程的返回地址压入堆栈。
如果异常产生了一个硬错误码,则将它也保存在堆栈中。
如果特权级没有发生变化,则压入栈中的内容如图5.4中。
此时,CS:
EIP的值就是IDT表中第i项门描述符的段选择符和偏移量的值,于是,CPU就跳转到了中断或异常处理程序。
分两步进行有效性检查:
首先是“段”级检查,将CPU的当前特权级CPL(存放在CS寄存器的最低两位)与IDT中第i项段选择符中的DPL相比较,如果DPL(3)大于CPL(0),就产生一个“通用保护”异常,因为中断处理程序的特权级不能低于引起中断的进程的特权级。
这种情况发生的可能性不大,因为中断处理程序一般运行在内核态,其特权级为0。
然后是“门”级检查,把CPL与IDT中第i个门的DPL相比较,如果CPL大于DPL,也就是当前特权级(3)小于这个门的特权级(0),CPU就不能“穿过”这个门,于是产生一个“通用保护”异常,这是为了避免用户应用程序访问特殊的陷阱门或中断门。
但是请注意,这种“门”级检查是针对一般的用户程序,而不包括外部I/O产生的中断或因CPU内部异常而产生的异常,也就是说,如果产生了中断或异常,就免去了“门”级检查。
6、中断处理程序和中断服务程序有何区别?
Linux如何描述一条共享的中断线?
中断服务程序ISR与中断处理程序是两个不同的概念。
在Linux中,15条中断线对应15个中断处理程序。
具体来说,中断处理程序相当于某个中断向量的总处理程序,例如IRQ0x05_interrupt()是中断号为5(向量为37)的总处理程序,如果这个5号中断由网卡和图形卡共享,则网卡和图形卡分别有其相应的中断服务程序。
typedefirqreturn_t(*irq_handler_t)(int,void*);
structirqaction{
irq_handler_thandler;
unsignedlongflags;
cpumask_tmask;
constchar*name;
void*dev_id;
structirqaction*next;
intirq;
...};
7、叙述中断处理程序的执行过程,并给出几个主要函数的调用关系和功能。
CPU从中断控制器的一个端口取得中断向量I;
根据I从中断描述符表IDT中找到相应的中断门;
从中断门获得中断处理程序的入口地址;
判断是否要进行堆栈切换;
调用do_IRQ()对所接收的中断进行应答,并禁止这条中断线;
调用handle_IRQ_event()来运行对应的中断服务例程。
8、为什么把中断分为两部分来处理?
中断服务例程一般都是在中断请求关闭的条件下执行的,以避免嵌套而使中断控制复杂化。
但是,中断是一个随机事件,它随时会到来,如果关中断的时间太长,CPU就不能及时响应其他的中断请求,从而造成中断的丢失。
因此,内核的目标就是尽可能快的处理完中断请求,尽其所能把更多的处理向后推迟。
例如,假设一个数据块已经达到了网线,当中断控制器接受到这个中断请求信号时,Linux内核只是简单地标志数据到来了,然后让处理器恢复到它以前运行的状态,其余的处理稍后再进行(如把数据移入一个缓冲区,接受数据的进程就可以在缓冲区找到数据)。
因此,内核把中断处理分为两部分:
前半部分(tophalf)和后半部分(bottomhalf),前半部分内核立即执行,而后半部分留着稍后处理。
9、实时时钟和操作系统时钟有何不同?
大部分PC机中有两个时钟源,分别是实时时钟(RTC)和操作系统(OS)时钟
实时时钟也叫硬件时钟,它靠电池供电,即使系统断电,也可以维持日期和时间。
RTC是OS时钟的时间基准,操作系统通过读取RTC来初始化OS时钟,此后二者保持同步运行,共同维持着系统时间。
所谓同步,是指操作系统在运行过程中,每隔一个固定时间会刷新或校正RTC中的信息
10、jiffies表示什么?
什么时候对其增加?
jiffies是Linux内核中的一个全局变量,用它来表示系统自启动以来的时钟节拍总数。
启动时,内核将该变量初始化为0,此后,每次时钟中断处理程序都会增加该变量的值。
11、时钟中断的下半部分主要做什么?
run_lock_timers()函数去处理所有到期的定时器,定时器作为软中断在下半部分中执行。
Scheduler_tick()函数负责减少当前运行进程的时间片计数值并且在需要时设置need_resched标志。
当update_process_timer()函数返回后,do_timer()函数接着会调用update_times()函数更新墙上时钟。
第六章
6.2系统调用与库函数、系统命令及内核函数有什么区别或联系?
系统调用与API:
API其实是一个函数定义,这些函数说明了如何获得一个给定的服务,而系统调用是通过软中断向内核发出一个明确的请求,系统调用实现是在内核完成的,而用户态的函数是在函数库中实现的;
系统调用与系统命令:
系统命令相对于应用程序接口更高一层,每个系统命令都是一个可执行程序,这些命令的实现调用了系统调用;
系统调用与内核函数:
系统调用是用户进程进入内核的接口层,它本身并非内核函数,但他是由内核函数实现的,进入内核后不同的系统调用会找到各自对应的内核函数,这些内核函数称为系统调用的服务进程。
6-3内核为什么要设置系统调用处理程序,他与服务例程有什么区别?
系统调用不能直接调用内核函数,因为用户空间的程序无法直接执行内核代码,内核驻留在受保护的地址空间上,不允许用户进程在内核地址空间上读写,所以,应用程序应该以某种方式通知系统,告诉内核自己需要执行一个系统调用,这种通知内核的机制是靠软中断来实现的,通过引发一个异常来促使系统切换到内核态去执行异常处理程序,此时的异常处理程序就是所谓的系统调用处理程序。
系统调用处理程序是调用系统调用服务例程的相应的C函数来处理系统调用的。
6-6说明系统调用号的作用。
Linux系统有几百个系统调用,为了唯一的标识每一个系统调用,linux为每一个系统调用定义了一个唯一的编号,此编号称为系统调用号,它的另一个目的是作为系统调用表的下标,当用户空间的进程执行一个系统调用的时候,这个系统调用号就被用来指明到底是要执行哪一个系统调用。
第七章
7-1什么是临界区?
什么是竞争状态?
什么是同步?
1)临界区(criticalregions)就是访问和操作共享数据的代码段,多个内核任务并发访问同一个资源通常是不安全的;
2)如果两个内核任务可能处于同一个临界区,就是一种错误现象;
如果确实发生了这种情况,就称它为竞争状态;
3)避免并发和防止竞争状态称为同步
7-5内核中造成并发执行的原因是什么?
“并发”分为“伪并发”和“真并发”两种,内核中造成并发执行的原因有以下几种:
1.中断——中断几乎可以在任何时刻异步发生,也可能随时打断正在执行的代码。
2.内核抢占——若内核具有抢占性,内核中的任务就可能会被另一任务抢占。
3.睡眠及与用户空间的同步——在内核执行的进程可能会睡眠,这将唤醒调度程序,导致调度一个新的用户进程执行4.对称多处理——两个或多个处理器可以同时执行代码
3、给出信号量的定义,并说明down()和up()的含义。
信号量是在1968年由EdsgerWybeDijKstra提出的,此后它逐渐成为一种常用的锁机制。
信号量支持两个原子操作P()和V(),这两个名字来自荷兰语Proberen和Vershogen。
前者做测试操作(字面意思是探查),后者叫做增加操作。
后来的系统把这两种操作分别叫做down()和up(),Linux也遵从这种叫法。
down()操作通过对信号量计数减1来请求获得一个信号量。
如果结果是0或大于0,信号量锁被获得,任务就可以进入临界区了。
如果结果是负数,任务会被放入等待队列,处理器执行其它任务。
down()函数如同一个动词“降低(down)”,一次down()操作就等于获取该信号量。
相反,当临界区中的操作完成后,up()操作用来释放信号量,该操作也被称作是“提升(upping)”信号量,因为它会增加信号量的计数值。
如果在该信号量上的等待队列不为空,处于队列中等待的任务在被唤醒的同时会获得该信号量。
4、申明一个信号量,并给出如何使用它。
定义:
structsemaphore{
atomic_tcount;
intsleepers;
wait_queue_head_twait;
使用:
staticDECLARE_
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- linux 复习