内核开发时应该注意的点
2016-03-02 15:21
246 查看
参考 http://m.blog.csdn.net/article/details?id=45953403
不能访问C库?
不是因为不允许访问,只是因为libc库有点大(内核一般是几百M,libc库可能就几百M了),这样编译连接出来不符合小内核的准则吧。另外有人说libc库效率低,我也不清楚。
大部分libc库中的API在内核中有实现,具体可以看https://www.kernel.org/doc/htmldocs/kernel-api/,大部分文件位于/linux/目录下,例如string.h文件。
内核只能调用printk(https://kernel.org/doc/htmldocs/device-drivers/API-printk.html)打印日志。
只能使用GNU C?
因为内核编译时候使用的是GNU GCC,所以语法必须是GNU C。
优先使用内联函数(static inline),其次使用宏,宏一般用来定义常亮,内联函数一般用来定义函数。内联函数与宏都是在预编译时候展开。
优先使用内联函数?参考/article/8763861.html,总之是相比宏内联函数具备函数的方便之处,例如可调式、编译器会做参数与返回值的语法检查、在C++中内联函数可以访问类的私有变量、C++中头文件声明函数的同时又实现了函数体那么这个函数编译器默认使用内联函数做了。
其余还有内嵌汇编与分支优化。
无内存保护机制?
用户空间的异常操作可以由内核来进行保护,例如内存越界、访问非法指针,这时会有core dump出现。内核操作内存不当就会出现oops,所以内核中一定不能访问非法指针、空指针之类的。
对于用户态进程,看到的内存是分页的,也就是用户态内存操作工作在虚拟内存之上,可以对换到外存。内核进程看到的内存就是物理内存,用多少少多少,所以内核内存操作很多时候是采用预先开辟内存池的方式。
浮点数很难使用?
总之很难用,glibc中可以模拟,但是内核不行。/article/1460253.html
用户态与内核态都要注意同步与并发?
用户态处理并发可以使用pthread库解决,这个库不属于libc库(因为cplus中没有他) ,但是内核态也不能使用这个库。
linux多任务系统支持异步中断(就是软中断或者硬中断都会在任何任务的任何时候中断),可抢占(注意是内核中的线程可抢占),SMP。
由于支持抢占,内核必须对任务(无论是内核态任务还是用户态任务)进行同步,也就是安排任务的运行次序和时间,也就是调度(schedule)。有很多种调度方式,例如按照时间片先来先服务、基于队列的先来先服务等。
由于支持SMP,多个处理器中运行了多个任务,可能会有多个任务共同访问一个共享资源,所以需要对共享资源加锁。
由于支持异步中断,中断之前运行的任务与中断时运行的任务可能访问共同的资源,所以也要采取保护措施。
可抢占同理。
pthread库采取了哪些措施?见 OVS中的封装。
常用的解决方法是使用自旋锁、信号量(mutex)。具体后面分析。
内核栈空间很小?
编译内核的时候可配置栈大小,一般是4、8KB,总之很小。栈小的话影响函数调用时候传参数与返回值。
移植时候问题?
字节序问题、64位对齐、不假定字长与页面长。
不能访问C库?
不是因为不允许访问,只是因为libc库有点大(内核一般是几百M,libc库可能就几百M了),这样编译连接出来不符合小内核的准则吧。另外有人说libc库效率低,我也不清楚。
大部分libc库中的API在内核中有实现,具体可以看https://www.kernel.org/doc/htmldocs/kernel-api/,大部分文件位于/linux/目录下,例如string.h文件。
内核只能调用printk(https://kernel.org/doc/htmldocs/device-drivers/API-printk.html)打印日志。
只能使用GNU C?
因为内核编译时候使用的是GNU GCC,所以语法必须是GNU C。
优先使用内联函数(static inline),其次使用宏,宏一般用来定义常亮,内联函数一般用来定义函数。内联函数与宏都是在预编译时候展开。
优先使用内联函数?参考/article/8763861.html,总之是相比宏内联函数具备函数的方便之处,例如可调式、编译器会做参数与返回值的语法检查、在C++中内联函数可以访问类的私有变量、C++中头文件声明函数的同时又实现了函数体那么这个函数编译器默认使用内联函数做了。
其余还有内嵌汇编与分支优化。
无内存保护机制?
用户空间的异常操作可以由内核来进行保护,例如内存越界、访问非法指针,这时会有core dump出现。内核操作内存不当就会出现oops,所以内核中一定不能访问非法指针、空指针之类的。
对于用户态进程,看到的内存是分页的,也就是用户态内存操作工作在虚拟内存之上,可以对换到外存。内核进程看到的内存就是物理内存,用多少少多少,所以内核内存操作很多时候是采用预先开辟内存池的方式。
浮点数很难使用?
总之很难用,glibc中可以模拟,但是内核不行。/article/1460253.html
用户态与内核态都要注意同步与并发?
用户态处理并发可以使用pthread库解决,这个库不属于libc库(因为cplus中没有他) ,但是内核态也不能使用这个库。
linux多任务系统支持异步中断(就是软中断或者硬中断都会在任何任务的任何时候中断),可抢占(注意是内核中的线程可抢占),SMP。
由于支持抢占,内核必须对任务(无论是内核态任务还是用户态任务)进行同步,也就是安排任务的运行次序和时间,也就是调度(schedule)。有很多种调度方式,例如按照时间片先来先服务、基于队列的先来先服务等。
由于支持SMP,多个处理器中运行了多个任务,可能会有多个任务共同访问一个共享资源,所以需要对共享资源加锁。
由于支持异步中断,中断之前运行的任务与中断时运行的任务可能访问共同的资源,所以也要采取保护措施。
可抢占同理。
pthread库采取了哪些措施?见 OVS中的封装。
常用的解决方法是使用自旋锁、信号量(mutex)。具体后面分析。
内核栈空间很小?
编译内核的时候可配置栈大小,一般是4、8KB,总之很小。栈小的话影响函数调用时候传参数与返回值。
移植时候问题?
字节序问题、64位对齐、不假定字长与页面长。
相关文章推荐
- x264代码剖析(一):图文详解x264在Windows平台上的搭建
- IPC机制之Messenger
- Recommending branded products from social media -RecSys 2013
- iOS进阶面试题
- c++上机报告
- Android6.0的phone应用源码分析(6)——RIL层框架分析
- c++第一次实验
- Logstash+Redis+Elasticsearch+Kibana+Nginx搭建日志分析系统
- Cortex-A8中bootloader研究(1)
- MSN三叉戟的要害程度都强于C罗
- ZJU_1145 OR POJ_1100 Dreisam Equations
- 面向对象的一些基本概念
- 常用 Git 命令
- swift——图片添加点击事件
- 绘画时的缩放比与字体大小
- FFmpeg合成h264视频流和aac音频流为mp4
- Google Guava Cache:本地缓存,过期实现
- iOS利用系统打电话和发短信
- 如何将一个文件夹复制到另一个文件夹中并保留其权限
- sfnttool的基本使用方法【很给力的字体抽取工具】