相对于用户空间内应用程序的开发,内核开发有很大的不同,最重要的差异包括以下几种:
(1) 内核编程时不能访问C库
对内核来说,完整的C库太大,不过大部分常用的C库函数在内核中已经被实现。
(2)内核编程时必须使用GNU C
Linux内核是用C语言编写的,但却不完全符合ANSI C标准,更偏向于gcc(多种GNU编译器的集合,GNU扩展了很多特性)。比如:内联函数、内联汇编、分支声明。
(3)内核编程时缺乏像用户空间那样的内存保护机制
一个用户程序试图进行一次非法的内存访问,内核会发现这个错误,发送SIGSEGV,并结束整个进程。但是如果内核自己非法访问了内存,那就很难控制了。内核中发生内存错误会导致oops,在内核中不应该去访问非法的内存地址,引用空指针之类的事情。
内核中的内存都不分页,每用掉一个字节,物理内存就减少一个字节。
(4)内核编程时浮点数很难使用
在用户空间中,使用浮点数,内核会完成从整数操作到浮点数操作的模式切换,但在内核空间中不能完美的支持浮点操作,因此,不要再内核中使用浮点数。
(5)内核只有一个很小的定长堆栈
用户空间的程序可以从栈上分配大量的空间存放变量。因为用户空间的栈本身比较大,而且还能动态的增长。内核栈的准确大小随体系结构而变,在X86上,栈的大小在编译时设置,可以是4KB或者8KB。从历史上说,内核栈的大小是两页,32位机上内核栈是8KB,64位机上是16kB,这是固定不变的。
(6)由于内核支持异步中断、抢占和SMP,因此必须时刻注意同步和并发
Linux是抢占多任务操作系统。内核必须对这些任务同步。
Linux内核支持多处理器系统,如果没有适当的保护,在两个或两个以上的处理器上运行的代码很可能会同时访问共享的同一个资源。
解决以上等问题的方法是自旋锁和信号量。
(7)要考虑可移植性的重要性
Linux是一个可移植的操作系统,大部分C代码应该和体系结构无关,在许多不同体系结构的计算机上都能够编译和执行。必须把体系结构相关的代码从内核代码树的特定目录中适当的分离出来。
参考自:《Linux Kernel Development》
原文:http://www.cnblogs.com/blkspm/p/5264763.html