编程知识 cdmana.com

让面试者头大如斗的linux内核30道题

前言

前些天的面试尸横遍野,因为面试官问了linux内核,很多同学平时并不注重这个,所以自然也就没办法答得出来,一起来看看是哪些题难住了大家,答案也帮大家整理好了,不过只写了了几个,因为不知道有没有人看,我犯懒,剩下的答案感兴趣的朋友可以进群获取

1. Linux中主要有哪几种内核锁?

=============================

Linux 的同步机制从 2.0 到 2.6 以来不断发展完善。从最初的原子操作,到后来 的信号量,从大内核锁到今天的自旋锁。这些同步机制的发展伴随 Linux 从单处 理器到对称多处理器的过渡;伴随着从非抢占内核到抢占内核的过度。Linux 的锁机制越来越有效,也越

来越复杂。 自旋锁最多只能被一个可执行线程持有,如果一个执行线程试图请求一个已被争用已经被持有)的自旋锁,那么这个线程就会一直进行忙循环——旋转——等待 锁重新可用。要是锁未被争用,请求它的执行线程便能立刻得到它并且继续进行。 自旋锁可 

以在任何时刻防止多于一个的执行线程同时进入临界区。 信号量的睡眠特性,使得信号量适用于锁会被长时间持有的情况;只能在进程上 下文中使用,因为中断上下文中是不能被调度的;另外当代码持有信号量时,不 可以再持有自旋锁。 Linux 内核中的同步机

制:原子操作、信号量、读写信号量和自旋锁的 API,另 外一些同步机制,包括大内核锁、读写锁、大读者锁、RCU (Read-Copy Update, 顾名思义就是读-拷贝修改),和顺序锁。

2. Linux中的用户模式和内核模式是什么含意?  

=====================================

MS-DOS 等操作系统在单一的 CPU 模式下运行,但是一些类 Unix 的操作系统则使 用了双模式,可以有效地实现时间共享。在 Linux 机器上,CPU 要么处于受信任 的内核模式,要么处于受限制的用户模式。除了内核本身处于内核模式以外,所 有的用户进程都运

行在用户模式之中。 内核模式的代码可以无限制地访问所有处理器指令集以及全部内存和 I/O 空间。 如果用户模式的进程要享有此特权,它必须通过系统调用向设备驱动程序或其他 内核模式的代码发出请求。另外,用户模式的代码允许发生缺页,而内核模式的

代码则不允许。 在 2.4 和更早的内核中,仅仅用户模式的进程可以被上下文切换出局,由其他进 程抢占。除非发生以下两种情况,否则内核模式代码可以一直独占 CPU:

(1) 它自愿放弃 CPU;

(2) 发生中断或异常。

2.6 内核引入了内核抢占,大多数内核模式的代码也可以被抢占。

3.怎样申请大块内核内存?

========================

在 Linux 内核环境下,申请大块内存的成功率随着系统运行时间的增加而减少, 虽然可以通过 vmalloc 系列调用申请物理不连续但虚拟地址连续的内存,但毕竟

其使用效率不高且在 32 位系统上 vmalloc 的内存地址空间有限。所以,一般的 建议是在系统启动阶段申请大块内存,但是其成功的概率也只是比较高而已,而 不是 100%。如果程序真的比较在意这个申请的成功与否,只能退用“启动内 存”Boot Memory)。下面就

是申请并导出启动内存的一段示例代码:

void* x_bootmem = NULL;
EXPORT_SYMBOL(x_bootmem);
unsigned long x_bootmem_size = 0;
EXPORT_SYMBOL(x_bootmem_size);
static int __init x_bootmem_setup(char *str)
{
x_bootmem_size = memparse(str, &str);
x_bootmem = alloc_bootmem(x_bootmem_size);
printk("Reserved %lu bytes from %p for xn", x_bootmem_size, x_bootmem);
return 1;
}
__setup("x-bootmem=", x_bootmem_setup);

可见其应用还是比较简单的,不过利弊总是共生的,它不可避免也有其自身的限

制:

内存申请代码只能连接进内核,不能在模块中使用。被申请的内存不会被页分配 器和 slab 分配器所使用和统计,也就是说它处于系统的可见内存之外,即使在 将来的某个地方你释放了它。一般用户只会申请一大块内存,如果需要在其上实

现复杂的内存管理则需要自己实现。在不允许内存分配失败的场合,通过启动内 存预留内存空间将是我们唯一的选择。

4.用户进程间通信主要哪几种方式?

===========================

  1. 管道 Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个 与它有共同祖先的进程之间进行通信
  2. 命名管道 named pipe):命名管道克服了管道没有名字的限制,因此,除具有 管道所具有的功能外,它还允许无亲缘关系进程间的通信。命名管道在文件系统 中有对应的文件名。命名管道通过命令 mkfifo 或系统调用 mkfifo 来创建。
  3. 信号 Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发 生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux 除了支持 Unix 早期信号语义函数 sigal 外,还支持语义符合 Posix.1 标准的信号函数 sigaction 实际上,该函数是基于 BSD 的,BSD 为了实现可靠信号机制,又能够 统一对外接口,用 sigaction 函数重新实现了 signal 函数)。
  4. 消息 Message)队列:消息队列是消息的链接表,包括 Posix 消息队列 system V 消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则 可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格 式字节流以及缓冲区大小受限等缺
  5. 信号量 semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。
  6. 套接字 Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间 通信。起初是由 Unix 系统的 BSD 分支开发出来的,但现在一般可以移植到其它 类 Unix 系统上:Linux 和 System V 的变种都支持套接字。

5、调用schedule()进行进程切换的方式有几种?

=============================================

1.系统调用 do_fork();

2.定时中断 do_timer();

3.唤醒进程 wake_up_process

4.改变进程的调度策略 setscheduler();

5.系统调用礼让 sys_sched_yield();


6、通过伙伴系统申请内核内存的函数有哪些?

7、通过slab分配器申请内核内存的函数有?

8、Linux的内核空间和用户空间是如何划分的(以32位系统为例)?

9、vmalloc()申请的内存有什么特点?

10、用户程序使用malloc()申请到的内存空间在什么范围?

11、在支持并使能MMU的系统中,Linux内核和用户程序分别运行在物理地址模式还是虚拟地址模式?

12、ARM处理器是通过几级也表进行存储空间映射的?

13、Linux是通过什么组件来实现支持多种文件系通的?

14、Linux虚拟文件系统的关键数据结构有哪些?(至少写出 四个)

15、对文件或设备的操作函数保存在那个数据结构中?

16、创建进程的系统调用有那些?

17、Linux调度程序是根据进程的动态优先级还是静态优先级来调度进程的?

18、进程调度的核心数据结构是哪个?

19、如何加载、卸载一个模块?

20、Linux中的浮点运算由应用程序实现还是内核实现?

21、模块程序能否使用可链接的库函数?

22、TLB中缓存的是什么内容?

23、Linux中有哪几种设备?

24、字符设备驱动程序的关键数据结构是哪个?

25、设备驱动程序包括哪些功能函数?

26、如何唯一标识一个设备?

27、Linux 通过什么方式实现系统调用?

28、Linux 软中断和工作队列的作用是什么?


好了,文章就到这里吧,你问我后面的答案怎么没有了?因为我懒得打字了,如果自己做不出来或者想印证一下做的对不对的朋友,可以进群973961276跟大家一起交流,如果有人看的话我再给大家贴一个讲解linux内核的视频,散会!

版权声明
本文为[秃头大哥]所创,转载请带上原文链接,感谢
https://segmentfault.com/a/1190000038144248

Scroll to Top