image

编辑人: 舍溪插画

calendar2025-05-19

message8

visits173

Kernel & Driver 内核基础试题

内核基础试题

1. 简答题。(各10分)

1.1 Spin Lock 相对于信号量的特点;在UP/MP/SMP这些不同环境下,Spin Lock的不同实现方法。

1.2 简要说明e2compr压缩文件系统的压缩策略;经其处理后,上层文件系统(EXT2/3等)是否会受到影响。

1.3 比较linux操作系统内核态和用户态的抢占性,及两者之间存在差异的原因。

1.4 linux2.2支持的最大进程数是多少,演进至2.4后,这一制约是如何克服的。

1.5 列举中断屏蔽的类型,并简单比较。

1.6 列举linux所要处理的定时/计数器(实际的外围硬件设备,不是指软件定时器),

 

及其用途。

 

2. 问答题。(各20分)

2.1 穷举在用户态空间,内核消息的获取方式、差异、以及差异的原因。

2.2 解释linux进程调度中的epoch概念,该机制的目的。

2.3 描述一个硬件中断信号发生,到为其注册的中断服务例程开始执行,之间所经过的

 

内核处理过程。并进一步分析,制约linux中断响应时间的因素存在于哪些方面。

2.4 比较底半机制(BH)和Tasklet的特点,及运行方面的差异。

2.5 说明引导过程中initrd.img和linuxrc作用,给出制作initrd.img的伪代码形式的流程。

2.6 在VFS层中如何区分设备文件和正规文件?

2.7 内核有几种方式访问硬件设备?

2.8 内核如何访问iomem?请举例说明。

 

3. 分析题。

3.1 系统时间设置问题。(10分)

同样采用date命令,目的在于修改系统时间,在不同的系统上却有不同的现象:

假定初始时间(T1)为03月01日16:00 2003年,期望的修改后时间(T2)为12月31日00:00 2002年,

<1> 在EDK系统中,执行命令 #date 123100002002,系统时间立即会变为T2;但系统重新启动之后,系统时间仍恢复为T1的时间区间:03月01日16:02   2003年,修改并未保留下来。

<2> 在RedHat7.2/8.0中,重复上述设置,系统重新启动之后,时间设置得到了保留,系统运行于T2的时间区间:12月31日00:02 2002年。请分析<1> 中所表现出的现象是由于什么原因造成的;

 

3.2 在大家相关于串口的工作中,可能会遇到这样的问题:(20分)

串口在发送数据时,不是连续且迅速地发送,而是以一个固定的节拍(10秒),且每次只发送等长度的一段数据,请列举可能造成这一问题的所有原因;

 

3.3 Oops分析。(50分)

以下是一段经过符号解析过的Oops信息,我们知道造成这个Oops的直接原因在于对于内核函数__wake_up的调用过程之中出现了问题;基于上述判断,请基于已经给出的__wake_up相关源码和反汇编码,大致分析问题出现在哪个源码行,并给出分析结论;

———————————————————–

ksymoops信息:

ksymoops2.4.4on i686 2.2.19-rthal3. Options used

-v /usr/src/linux-2.2.19/vmlinux (specified)

-k /proc/ksyms (specified)

-l /proc/modules (specified)

-o /lib/modules/2.2.19-rthal3/ (default)

-m /usr/src/linux-2.2.19/System.map (specified)

 

current->tss.cr3 = 07d29000, %cr3 = 07d29000

*pde = 00000000

Oops: 0000

CPU: 0

EIP: 0010:[<C01110C1>]

Using defaults from ksymoops -t elf32-i386 -a i386

eax: 00000014 ebx: c0eabf74 ecx: 00000013 edx: 00000021

esi: 00000000 edi: 00000020 ebp: c0eabf6cesp: c0eabf60

ds: 0018 es: 0018 ss: 0018

Process in.identd (pid: 828, process nr: 6, stackpage=c0eab000)

Stack:00000000 c807ca0400000021 c0eabf74 c807be21 c0eabfb0 c807bf74

c807c940

00000000 0000000000000000 c803fb60 c807e000 00000e20 2b124c28

0000027c

0010a000 c807c900 000000000000f944 bffff944 c803d2ec 00000000

00000000

Call Trace: [<c807ca04>] [<c807be21>] [<c807bf74>] [<c807c940>]

[<c803fb60>] [<c807e000>]

[<c807c900>] [<c803d2ec>] [<c803c0a0>]

Code: 8b 02 85 45 fc 74 1b 85 ff 74 10 837a44 00 740a85 f6 75

 

>>EIP; c01110c1 <__wake_up+2d/6c> <=====

 

Trace; c807ca04 <[rt_das]timeout+c4/c8>

Trace; c807be21 <[rt_das]read_timeout+25/28>

Trace; c807bf74 <[rt_das]pulse_isr+150/19c>

Trace; c807c940 <[rt_das]timeout+0/c8>

Trace; c803fb60 <[rtai]global_irq_handler+0/80>

Trace; c807e000 <.bss.end+14a1/????>

Trace; c807c900 <[rt_das]board+0/28>

Trace; c803d2ec <[rtai]dispatch_global_irq+28/90>

Trace; c803c0a0 <[rtai]GLOBAL0_interrupt+18/34>

Code; c01110c1 <__wake_up+2d/6c>

00000000 <_EIP>:

Code; c01110c1 <__wake_up+2d/6c> <=====

0: 8b 02 movl (%edx),%eax <=====

Code; c01110c3 <__wake_up+2f/6c>

2: 85 45 fc testl %eax,0xfffffffc(%ebp)

Code; c01110c6 <__wake_up+32/6c>

5: 74 1b je 22 <_EIP+0×22> c01110e3

<__wake_up+4f/6c>

Code; c01110c8 <__wake_up+34/6c>

7: 85 ff testl %edi,%edi

Code; c01110ca <__wake_up+36/6c>

9: 74 10 je 1b <_EIP+0×1b> c01110dc

<__wake_up+48/6c>

Code; c01110cc <__wake_up+38/6c>

b: 837a44 00 cmpl $0×0,0×44(%edx)

Code; c01110d0 <__wake_up+3c/6c>

f: 740aje 1b <_EIP+0×1b> c01110dc

<__wake_up+48/6c>

Code; c01110d2 <__wake_up+3e/6c>

11:85 f6 testl %esi,%esi

Code; c01110d4 <__wake_up+40/6c>

13: 75 00 jne 15 <_EIP+0×15> c01110d6

<__wake_up+42/6c>

 

Unable to handle kernel paging request at virtual address 66fe4603

current->tss.cr3 = 00e94000, %cr3 = 00e94000

*pde = 00000000

Oops: 0000

CPU: 0

EIP: 0010:[<c01113e6>]

EFLAGS:00010a83

Warning (Oops_read): Code line not seen, dumping what data is available

 

>>EIP; c01113e6 <interruptible_sleep_on+5a/78> <=====

 

1 warning issued. Results may not be reliable.

 

<附录>

1. __wake_up的源码:

void __wake_up(struct wait_queue **q, unsigned int mode)

{

struct task_struct *p, *best_exclusive;

struct wait_queue *head, *next;

unsigned int do_exclusive;

 

if (!q)

goto out;

/*

* this is safe to be done before the check because it

* means no deference, just pointer operations.

*/

head = WAIT_QUEUE_HEAD(q);

 

read_lock(&waitqueue_lock);

next = *q;

if (!next)

goto out_unlock;

 

best_exclusive = 0;

do_exclusive = mode & TASK_EXCLUSIVE;

while (next != head) {

p = next->task;

next = next->next;

if (p->state & mode) {

if (do_exclusive && p->task_exclusive) {

if (best_exclusive == NULL)

best_exclusive = p;

}

else {

wake_up_process(p);

}

}

}

if (best_exclusive)

wake_up_process(best_exclusive);

out_unlock:

read_unlock(&waitqueue_lock);

out:

return;

}

 

2. __wake_up的反汇编码:

c0111094 <__wake_up>:

c0111094: 55 pushl %ebp

c0111095: 89 e5 movl %esp,%ebp

c0111097: 83 ec 08 subl $0×8,%esp

c011109a: 57 pushl %edi

c011109b: 56 pushl %esi

c011109c: 53 pushl %ebx

c011109d: 89 55 fc movl %edx,0xfffffffc(%ebp)

c01110a0:85 c0 testl %eax,%eax

c01110a2: 74 50 je c01110f4 <__wake_up+0×60>

c01110a4: 8d 48 fc leal 0xfffffffc(%eax),%ecx

c01110a7: 89 4d f8 movl %ecx,0xfffffff8(%ebp)

c01110aa: 8b 18 movl (%eax),%ebx

c01110ac: 85 db testl %ebx,%ebx

c01110ae: 74 44 je c01110f4 <__wake_up+0×60>

c01110b0:31 f6 xorl %esi,%esi

c01110b2: 89 d7 movl %edx,%edi

c01110b4: 83 e7 20 andl $0×20,%edi

c01110b7: 39 cb cmpl %ecx,%ebx

c01110b9: 74 2d je c01110e8 <__wake_up+0×54>

c01110bb: 90 nop

c01110bc: 8b 13 movl (%ebx),%edx

c01110be: 8b 5b 04 movl 0×4(%ebx),%ebx

c01110c1: 8b 02 movl (%edx),%eax

c01110c3: 85 45 fc testl %eax,0xfffffffc(%ebp)

c01110c6: 74 1b je c01110e3 <__wake_up+0×4f>

c01110c8: 85 ff testl %edi,%edi

c01110ca: 74 10 je c01110dc <__wake_up+0×48>

c01110cc: 837a44 00 cmpl $0×0,0×44(%edx)

c01110d0: 740aje c01110dc <__wake_up+0×48>

c01110d2:85 f6 testl %esi,%esi

c01110d4: 75 0d jne c01110e3 <__wake_up+0×4f>

c01110d6: 89 d6 movl %edx,%esi

c01110d8: eb 09 jmp c01110e3 <__wake_up+0×4f>

c01110da:89 f6 movl %esi,%esi

c01110dc: 89 d0 movl %edx,%eax

c01110de: e8 2d f9 ff ff call c0110a10 <wake_up_process>

c01110e3: 3b 5d f8 cmpl 0xfffffff8(%ebp),%ebx

c01110e6: 75 d4 jne c01110bc <__wake_up+0×28>

c01110e8:85 f6 testl %esi,%esi

c01110ea: 74 08 je c01110f4 <__wake_up+0×60>

c01110ec:89 f0 movl %esi,%eax

c01110ee: e8 1d f9 ff ff call c0110a10 <wake_up_process>

c01110f3: 90 nop

c01110f4: 8d 65 ec leal 0xffffffec(%ebp),%esp

c01110f7: 5b popl %ebx

c01110f8: 5e popl %esi

c01110f9:5fpopl %edi

c01110fa: 89 ec movl %ebp,%esp

c01110fc: 5d popl %ebp

c01110fd: c3 ret

c01110fe:89 f6 movl %esi,%esi

 

———————————————————–

内核驱动题

以下设计应该包括设计文档,实现策略说明,代码包,测试用例,使用说明.要求:按照综合编程题目的要求编写代码和文档。

参考资料: <Linux设备驱动程序>第二版.

 

1.设计并实现一个软件watchdog设备,以监视系统运行情况.(50分)

说明:watchdog设备用于监测系统运行状态,正常运行的系统定期写watchdog以使其不会超时,一旦超时,意味系统已挂起;watchdog应该重启系统. 现在的软件watchdog不重启系统,只用于监视应用程序的运行.

 

2.设计并实现一个简化的、容量可以变化的内存FIFO设备.(50分)

喵呜刷题:让学习像火箭一样快速,快来微信扫码,体验免费刷题服务,开启你的学习加速器!

创作类型:
原创

本文链接:Kernel & Driver 内核基础试题

版权声明:本站点所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明文章出处。
分享文章
share