① linux 系统编程, 驱动编程 , 内核编程 有什么区别《UNIX高级编程》的内容是哪一类的
系统编程,注重性能,比如服务器端的编程,一般最底层使用c,自己对内存管理版文件系统管理进行优化权
驱动编程,主要是为了把linux一直到嵌入式设备,linux内核是一个庞大的系统,但不是所有设备都用上这些,而且对于兼容性问题,还要做一些修改。比如在iphone出来之前,都是使用嵌入式设计一些PDA和山寨手机系统
至于内核编程,其实也是对性能的追求,但内核编程调用的API级别更高,相对来说系统编程,是标准的API
《U高级编程》一般没太多说明,都是系统编程
② Linux内核编程的目录
目录
第1章概述1
1.1UNIX的历史2
1.2标准和通用接口3
1.3自由软件和开放源码3
1.4Linux发布版概览3
1.41Debian4
1.42Red Hat/Fedora 4
1.43Mandriva4
1.44SUSE4
1.45Gentoo4
1.46Yellow Dog5
1.47其他发布版5
1.5内核版本信息5
1.6基于Power的Linux5
1.7什么是操作系统6
1.8内核组织7
1.9Linux内核概述7
1.9.1用户接口7
1.9.2用户标识符8
1.9.3文件和文件系统8
1.9.4进程12
1.9.5系统调用15
1.9.6Linux调度程序15
1.9.7Linux设备驱动程序15
1.10可移植性和体系结构的相关性16
1.11小结16
1.12习题16
第2章内核探索工具集18
2.1内核中常见的数据类型18
2.1.1链表18
2.1.2查找21
2.1.3树22
2.2汇编24
2.2.1PowerPC24
2.2.2x8627
2.3汇编语言示例29
2.3.1x86中的汇编示例30
2.3.2PowerPC中的汇编示例31
2.4内联汇编33
2.4.1输出操作数34
2.4.2输入操作数34
2.4.3已修改过的寄存器(已修改的元素列表) 34
2.4.4参数的编号方式34
2.4.5约束条件34
2.4.6asm35
2.4.7__volatile__35
2.5特殊的C 语言用法38
2.5.1asmlinkage38
2.5.2UL39
2.5.3内联39
2.5.4const和volatile39
2.6内核探索工具一览40
2.6.1objmp/readelf40
2.6.2hexmp41
2.6.3nm41
2.6.4obj42
2.6.5ar42
2.7内核发言:倾听来自内核的消息42
2.7.1printk()42
2.7.2dmesg42
2.7.3/var/log/messages42
2.8其他奥秘43
2.8.1__init43
2.8.2likely()和unlikely()43
2.8.3IS_ERR和PTR_ERR44
2.8.4通告程序链44
2.9小结45
2.9.1项目:Hellomod45
2.9.2第一步:构造Linux模块的框架45
2.9.3第二步:编译模块46
2.9.4第三步:运行代码47
2.10习题48
第3章进程:程序执行的基本模型49
3.1程序51
3.2进程描述符52
3.2.1与进程属性相关的字段54
3.2.2与调度相关的字段55
3.2.3涉及进程间相互关系的字段58
3.2.4与进程信任状相关的字段59
3.2.5与进程权能相关的字段60
3.2.6与进程限制相关的字段61
3.2.7与文件系统及地址空间相关的字段63
3.3进程的创建:系统调用fork()、vfork 和clone()64
3.3.1fork()函数65
3.3.2vfork()函数66
3.3.3clone()函数67
3.3.4do_fork()函数68
3.4进程的生命周期70
3.4.1进程的状态70
3.4.2进程状态的转换71
3.5进程的终止74
3.5.1sys_exit()函数75
3.5.2do_exit()函数75
3.5.3通知父进程和sys_wait4()77
3.6了解进程的动态:调度程序的基本构架80
3.6.1基本结构80
3.6.2从等待中醒来或者激活81
3.7等待队列86
3.7.1添加到等待队列88
3.7.2等待事件89
3.7.3唤醒进程91
3.8异步执行流程93
3.8.1异常93
3.8.2中断95
3.9小结114
3.9.1项目:系统变量current114
3.9.2项目源码115
3.9.3运行代码116
3.10习题116
第4章内存管理117
4.1页119
4.2内存管理区121
4.2.1内存管理区描述符122
4.2.2内存管理区操作辅助函数124
4.3页面124
4.3.1请求页面的函数124
4.3.2释放页面的函数126
4.3.3伙伴系统126
4.4Slab分配器130
4.4.1缓存描述符133
4.4.2通用缓存描述符135
4.4.3Slab描述符136
4.5Slab分配器的生命周期138
4.5.1与Slab分配器有关的全局变量138
4.5.2创建缓存139
4.5.3创建slab与cache_grow()144
4.5.4Slab的销毁:退还内存与kmem_cache_destroy()146
4.6内存请求路径147
4.6.1kmalloc()147
4.6.2kmem_cache_alloc()148
4.7Linux进程的内存结构149
4.7.1mm_struct150
4.7.2vm_area_struct152
4.8进程映像的分布及线性地址空间153
4.9页表155
4.10缺页156
4.10.1x86缺页异常156
4.10.2缺页处理程序157
4.10.3PowerPC缺页异常164
4.11小结164
4.12项目:进程内存映射165
4.13习题166
第5章输入/输出167
5.1总线、桥、端口和接口的硬件实现167
5.2设备171
5.2.1块设备概述172
5.2.2请求队列和I/O 调度173
5.2.3示例:“通用”块设备驱动程序180
5.2.4设备操作182
5.2.5字符设备183
5.2.6网络设备184
5.2.7时钟设备184
5.2.8终端设备184
5.2.9直接存储器存取184
5.3小结185
5.4项目:创建并口驱动程序185
5.4.1并口的硬件185
5.4.2运行在并口上的软件187
5.5习题192
第6章文件系统194
6.1文件系统的基本概念194
6.1.1文件和文件名194
6.1.2文件类型195
6.1.3文件的附加属性195
6.1.4目录和路径名196
6.1.5文件操作197
6.1.6文件描述符197
6.1.7磁盘块、磁盘分区以及实现197
6.1.8性能198
6.2Linux虚拟文件系统198
6.2.1VFS的数据结构200
6.2.2全局链表和局部链表的引用211
6.3与VFS相关的结构212
6.3.1fs_struct结构212
6.3.2files_struct结构213
6.4页缓存216
6.4.1address_space结构217
6.4.2buffer_head结构219
6.5VFS的系统调用和文件系统层221
6.5.1open()221
6.5.2close()227
6.5.3read()229
6.5.4write()244
6.6小结246
6.7习题246
第7章进程调度和内核同步247
7.1Linux的调度程序248
7.1.1选择下一个进程248
7.1.2上下文切换253
7.1.3让出CPU261
7.2内核抢占269
7.2.1显式内核抢占269
7.2.2隐式用户抢占270
7.2.3隐式内核抢占270
7.3自旋锁和信号量272
7.4系统时钟:关于时间和定时器274
7.4.1实时时钟:现在几点了274
7.4.2读取PPC的实时时钟276
7.4.3读取x86的实时时钟278
7.5小结280
7.6习题280
第8章内核引导281
8.1BIOS和Open Firmware282
8.2引导加载程序282
8.2.1GRUB283
8.2.2LILO286
8.2.3PowerPC和Yaboot286
8.3与体系结构相关的内存初始化287
8.3.1PowerPC的硬件内存管理287
8.3.2基于Intel x86体系结构的硬件内存管理296
8.3.3PowerPC和x86的代码汇集305
8.4原始的RAM盘305
8.5开始:start_kernel()306
8.5.1调用lock_kernel()307
8.5.2调用page_address_init()309
8.5.3调用printk(linux_banner)311
8.5.4调用setup_arch311
8.5.5调用setup_per_cpu_areas()315
8.5.6调用smp_prepare_boot_cpu()316
8.5.7调用sched_init()317
8.5.8调用build_all_zonelists()319
8.5.9调用page_alloc_init319
8.5.10调用parse_args()320
8.5.11调用trap_init()322
8.5.12调用rcu_init()323
8.5.13调用init_IRQ()323
8.5.14调用softirq_init()324
8.5.15调用time_init()325
8.5.16调用console_init()326
8.5.17调用profile_init()326
8.5.18调用local_irq_enable()327
8.5.19配置initrd327
8.5.20调用mem_init()327
8.5.21调用late_time_init()333
8.5.22调用calibrate_delay()333
8.5.23调用pgtable_cache_init()334
8.5.24调用buffer_init()335
8.5.25调用security_scaffolding_startup()336
8.5.26调用vfs_caches_init()336
8.5.27调用radix_tree_init()343
8.5.28调用signal_init()344
8.5.29调用page_writeback_init()344
8.5.30调用proc_root_init()346
8.5.31调用init_idle()347
8.5.32调用rest_init()348
8.6init线程(或进程1)349
8.7小结353
8.8习题353
第9章构建Linux内核354
9.1工具链354
9.1.1编译程序355
9.1.2交叉编译355
9.1.3链接程序356
9.1.4ELF二进制目标文件356
9.2内核源代码的构建360
9.2.1解释源代码360
9.2.2构建内核映像364
9.3小结369
9.4习题369
第10章向内核添加代码371
10.1浏览源代码371
10.11熟悉文件系统371
10.12filp和fops372
10.13用户空间和内核空间374
10.14等待队列375
10.15工作队列及中断378
10.16系统调用380
10.17其他类型的驱动程序380
10.18设备模型和sysfs文件系统383
10.2编写代码386
10.2.1设备基础386
10.2.2符号输出388
10.2.3IOCTL388
10.2.4轮询与中断391
10.2.5工作队列和tasklet395
10.2.6增加系统调用的代码396
10.3构建和调试398
10.4小结399
10.5习题400
③ 如何进行Linux Kernel 开发
学习汇编语言、C语言,这两种语言是你进行Linux Kernel开发与维护的必备语言能力,这样你才有能力阅读与编写Linux Kernel的能力。
下载Linux Kernel源代码,建议下载先前的版本,因为目前的新版本代码数量太庞大,技术太新,如果是进行Linux Kernel的开发的话,先从简单的版本0.11或者1.XX.XX版本开始,以前的版本中没有过多的新技术的代码,适合入门Linux Kernel的学习。
当你熟悉了Linux Kernel了后,可以下载目前最新的版本Linux Kernel3.18版本的源代码,里面包含了很多的新技术的知识,方便你了解与学习~~~
这是一篇很重要的文档,它介绍了内核开发的方方面面。这篇文档已被加入到内核源码树的Documentation文档里(名字为HOWTO),你可以在最新的内核树里找到它。尽管已经有网友翻译过这篇文档,但是我还是决定自己再翻译一遍。翻译完之后,我的感触是如果依靠翻译来进行学习,速度太慢了。以后的技术文档直接看英文,适当的做做笔记即可。
山涛
-----------------------------------------------------
How to do Linux Kernel development
-----------------------------------------------------
关于如何进行Linux Kernel development,这篇文档是最值得你阅读的一篇。它指导你如何成为一名Linux内核开发者以及如何和Linux内核开发社区一同工作。尽管它不包含内核编程的技能方面的知识,但是本篇能够给你正确的指导去做内核开发。
如果这篇文档讲述的任何东西已经过时了的话,请给这篇文档的维护者发送你的更新。
Greg [email protected]
Introction
-----------------
你想成为一名Linux内核开发者吗?或者你的老板曾经告诉你:去给某个设备写个Linux驱动程序。这篇文档的目标是,通过描述你进行开发时需要经历的一些流程规则去指导你如何与社区一起工作,教会你所需要的一切从而让你实现你的目标(成为一名合格的内核开发者,或者写出合格的令老板满意的驱动程序);这篇文档也会说明内核社区工作的风格和原因。
内核绝大部分代码是基于C语言编程,与体系结构有关的一小部分由汇编完成。很好的理解和掌握C语言,是内核开发的必备要求。汇编语言(不同的体系结构有不同的汇编语言)不是必需的,除非你计划做体系结构相关的底层开发。如果你想加强C语言的掌握,很好的参考资料如下:
- "The C Programming Language" by Kernighan and Ritchie [Prentice Hall]
- "Practical C Programming" by Steve Oualline [O'Reilly]
Linux内核是使用GNU C和GNU工具链完成的。尽管它遵循ISO C89标准,但是内核的编写也使用了许多的GNU C的扩展特性,这些特性不属于标准的一部分。内核的C编程环境自成体系,不依赖于C标准库,所以C标准的一部分特性没有被支持:例如Arbitrary long long divisions和浮点指针不被支持。有时你会很难理解内核基于GNU工具链的一些假定以及内核使用的一些GNU C扩展,不幸的是对于这类问题没有确定性的参考资料。如果你遇到这类问题,建议你查阅GCC的info pages来获取相关的信息(在Linux PC上,通过命令info gcc可以获得信息)。
请记住你正在学习如何与已经存在的内核开发社区一起工作。内核开发社区由全球不同地方的开发人员组成,它以代码、风格、开发流程的高质量标准著称。这些高质量的标准使内核开发社区(这个组织非常大,地理位置非常分散)能够非常有效的进行。应当提早努力学习这些高质量标准(编程风格、代码要求以及开发流程),它们有很好的文档;不要期望内核开发社区别的开发人员会适应你自己的或者你公司的开发风格。
Legal Issues
------------------
Linux内核代码基于GPL许可协议发布。请阅读内核源码树的主目录里的COPYING文件,它提供了GPL许可的详细描述。如果你有关于GPL许可的进一步问题,请联系一名律师,不要在Linux kernel mailing list里询问。Linux kernel mailing list里的开发人员不是律师,所以你不应当听取他们的任何关于法律事务的建议。
对于一些通常的关于GPL许可的问题和解答,请参考:
http://www.gnu.org/licenses/gpl-faq.html
Documentation
---------------------
Linux内核源码树里有大量的非常有用的文档用于学习,使你与内核社区相互促进和共同发展。当一个新的特性要加入到内核里,建议相关的文档也要加入到内核里,用于描述如何使用这个新特性;当一个内核的修改导致了内核提供给用户的接口发生了变化,建议你发送信息或者一个补丁给[email protected],告诉manual pages的维护者用户接口的变化。
这里罗列了一些内核源码树里的需要阅读的文档:
README
这篇文档简要的介绍了Linux内核的背景,描述了配置和build内核需要什么。一个刚刚接触内核的新手应当从这里开始。(注:build kernel,就是编译内核源代码,生成可供系统使用的内核二进制文件(vmlinux/zImage)的过程。
Documentation/Changes
这篇文档给出了一个用于成功编译和运行内核的各种软件包的列表的最小集合。
Documentation/CodingStyle
这篇文档描述了Linux内核编码风格,和一些隐藏在背后的基本原理。所有的想加入内核的新代码应当遵循这篇文档的指导。绝大数的内核代码维护者只愿意接受那些符合这篇文档描述的风格的补丁,许多内核开发者也只愿意审查那些符合Linux内核编码风格的代码。
Documentation/SubmittingPatches
Documentation/SubmittingDrivers
这些文档清楚而又详细地告诉你如何成功的创建和向社区递交一个补丁,包括:
----邮件内容
----邮件格式
----发送者和接收者
遵循文档里提倡的规则并不一定保证你提交补丁成功(因为所有的补丁遭受详细而严格的内容和风格的审查),但是不遵循它们,提交补丁肯定不成功。
其他的一些非常优秀的描述如何正确的创建补丁的文档如下:
"The Perfect Patch"
http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt
"Linux kernel patch submission format"
http://linux.yyz.us/patch-format.html
Documentation/stable_api_nonsense.txt
这篇文档描述了有意决定在内核里没有固定内核API的基本原因,包含下面的讨论主题:
---子系统的shim-layers(为了兼容性?)
---操作系统之间的驱动移植性
---减缓内核源码树的快速变化(或者说,防止快速变化)
这篇文档对于理解Linux的开发哲学非常关键,也对于从其他操作系统转移到Linux上的开发人员非常重要。
Documentation/SecurityBugs
如果你确知你在Linux Kernel里发现了security problem,请遵循这篇文档描述的步骤,帮助通知内核的开发者们并解决这类问题。
Documentation/ManagementStyle
这篇文档描述了Linux内核开发者们如何进行管理运作,以及运作方法背后的分享精神(shared ethos)。这篇文档对于那些内核开发新手们(或者那些好奇者)值得一读,因为它解决或解释了很多对于内核维护者独特行为的误解。
Documentation/stable_kernel_rules.txt
这篇文档描述了一个稳定的内核版本如何发布的规则,以及需要做些什么如果你想把一个修改加入到其中的一个版本。
Documentation/kernel-docs.txt
关于内核开发的外部文档列表。如果你在内核开发的内部文档中找不到你想要的资料,请参考这篇文档提供的资料链接。
Documentation/applying-patches.txt
这篇文档很好地描述了什么是补丁(patch),以及如何将它应用到内核的不同开发分支(branch)上。
内核里也有大量的由内核源码自动生成的文档。其中包括了内核内部API的全面描述,和如何处理好锁的规则。这些文档在Documentation/DocBook/下创建,格式可以是PDF、Postscritpt、HTML和man pages,在内核源码主目录下通过运行下面命令自动生成:
make pdfdocs
make psdocs
make htmldocs
make mandocs
附上出处链接:http://www.cppblog.com/flyonok/archive/2011/04/15/144316.html
④ linux内核编译详细教程及开发Linux系统
⑤ 如何让linux的一段程序代码进入内核态运行
需要让linux的一段程序代码进入内核态运行产生的方式有二:
被动式
主动式
所谓被动式就是产生中断或者代码产出异常,代码不得不从用户态进入内核态进行中断操作或者是异常处理;
而主动式则是系统响应了程序对系统的一次调用过程,并且系统允许该运行级别的提升;