linux 内核源代码情景分析——linux 内核源代码中的C语言代码
linux 内核的主体是以GNU的C语言编写的,GNU为此提供了编译工具gcc。GNU对C语言本身作了不少扩充。
1) gcc 从 C++ 语言中吸收了“inline”和“const”。inline 函数的使用与#define 宏定义相似,但更有相对的独立性,也更安全,因为“inline”函数会进行参数的类型检查。使用inline 函数也有利于程序调试。如果编译时不加优化,则这些inline函数就是普通的、独立的函数,更便于调试。调试好了以后,再采用优化重新编辑一次,这些inline函数就像宏操作一样融入了引用处的代码中,有利于提高运行效率,由于inline函数的大量使用,相当一部分代码从.c文件移入了.h文件中。
2) gcc支持一些“属性描述符”,如“aligned”、“packed”等等,这些描述符的使用等于是在C语言上增加了一些新的保留字,可是,在原来的C语言中这些词并非保留字,这样就有可能产生一些冲突。例如,gcc支持保留字inline,可是由于inline 原非保留字,所以在老的代码中可能已经有一变量名为inline,这样就产生了冲突,为了解决这个问题,gcc允许在作为保留字使用“inline”前、后都加上“__”,因而“__inline__”等价于保留字“inline”,同样的道理,“__asm__”等价于“asm”。这就是我们在代码汇总有时候看到“asm”,而有时候又看到“__asm__”的原因。
3) gcc 还支持一个保留字“attribute”,用来作属性描述。如:
struct foo {
char a;
int x[z] __attribute__ ((packed));
}
这里属性描述“packed”表示在字符a与整型数组x之间不应为了与32位长整数边界对齐而留下空洞,这样,“packed”就不会与变量名发生冲突了。
4) 由于gcc 和Linux 内核在平行的发展,一旦在Linux内核中使用的gcc,在其较新版本中有了新增加扩充,就不能再使用较老版本的gcc来编译。也就是说,Linux 内核的各种版本有着对gcc 版本的依赖关系。
5)
page = ((struct page*)((char*)(curr)-(unsigned long)(&((struct page*)0)->list)));
这里的curr是一个page结构内部的成员list的地址,而我们需要的确实那个page结构本身的地址,所以要从地址curr减去一个偏移量,即成员list在page内部的偏移量,才能达到要求,那么这个偏移量到底是多少呢?&((struct page*)0)->list 就表示当结构page正好在地址0上时其成员list的地址,这就是偏移量。
最新文章
- MinHash算法
- BZOJ 1100: [POI2007]对称轴osi
- os.popen(command)
- SEO优化笔记
- 使用OVS
- Linux时间子系统之八:动态时钟框架(CONFIG_NO_HZ、tickless)
- Java:配置环境(Mac)——MySQL
- ng-app&;data-ng-app
- c# 访问共享文件
- PDB文件详解
- vue中使用scss
- C语言:统计数字空格其他字符程序
- 微软BI 之SSIS 系列 - Lookup 组件的使用与它的几种缓存模式 - Full Cache, Partial Cache, NO Cache
- MySQL 安装 用户管理 常用命令
- Jenkins参数化构建(三)之 Jenkins从文件中读取运行参数
- 《HTTP权威指南》学习笔记——URL和资源
- Python range
- 【代码笔记】iOS-ios7 StatusBar
- django 错误分类及解决办法汇总
- iOS事件拦截(实现触摸任意位置隐藏指定view)