Ⅰ 如果想学linux,应该怎么学
学嵌入式Linux要先学以下几点:
1.C语言。要有C语言的基础,当然越熟练越好,不熟也没关系,具备基本技能就可以:比如写一个数组排序、输入数字求和什么的。C语言的学习就是多些多练。
2.Linux基础
Linux操作系统的概念、安装方法,详细了解Linux下的目录结构、基本命令、编辑器VI ,编译器GCC,调试器GDB和 Make 项目管理工具, Shell、 Makefile脚本编写等知识,嵌入式开发环境的搭建。
3.Linux系统编程
重点学习标准I/O库,Linux多任务编程中的多进程和多线程,以及进程间通信(pipe、FIFO、消息队列、共享内存、signal、信号量等),同步与互斥对共享资源访问控制等重要知识,主要提升对Linux应用开发的理解和代码调试的能力。
4.Linux网络编程
计算机网络在嵌入式Linux系统应用开发过程中使用非常广泛,通过Linux网络发展、TCP/IP协议、socket编程、TCP网络编程、UDP网络编程、Web编程开发等方面入手,全面了解Linux网络应用程序开发。重点学习网络编程相关API,熟练掌握TCP协议服务器的编程方法和并发服务器的实现,了解HTTP协议及其实现方法,熟悉UDP广播、多播的原理及编程方法,掌握混合C/S架构网络通信系统的设计,熟悉HTML,Javascript等Web编程技术及实现方法。
5.数据结构与算法
数据结构及算法在嵌入式底层驱动、通信协议、及各种引擎开发中会得到大量应用,对其掌握的好坏直接影响程序的效率、简洁及健壮性。此阶段的学习要重点理解数据结构与算法的基础内容,包括顺序表、链表、队列、栈、树、图、哈希表、各种查找排序算法等应用及其C语言实现过程。
6.Cortex A8 、Linux 平台开发
通过基于ARM Cortex-A8处理s5pv210了解芯片手册的基本阅读技巧,掌握s5pv210系统资源、时钟控制器、电源管理、异常中断控制器、nand flash控制器等模块,为底层平台搭建做好准备。Linux平台包括内核裁减、内核移植、交叉编译、GNU工具使用、内核调试、Bootloader介绍、制作与原理分析、根文件系统制作以及向内核中添加自己的模块,并在s5pv210实验平台上运行自己制作的Linux系统,集成部署Linux系统整个流程。同时了解Android操作系统开发流程。Android系统是基于Linux平台的开源操作系统,该平台由操作系统、中间件、用户界面和应用软件组成,是首个为移动终端打造的真正开放和完整的移动软件,目前它的应用不再局限于移动终端,还包括数据电视、机顶盒、PDA等消费类电子产品。
7.驱动开发
驱动程序设计是嵌入式Linux开发工作中重要的一部分,也是比较困难的一部分。本阶段的学习要熟悉Linux的内核机制、驱动程序与用户级应用程序的接口,掌握系统对设备的并发操作。熟悉所开发硬件的工作原理,具备ARM硬件接口的基础知识,熟悉ARM Cortex-A8处理器s5pv210各资源、掌握Linux设备驱动原理框架,熟悉工程中常见Linux高级字符设备、块设备、网络设备、USB设备等驱动开发,在工作中能独立胜任底层驱动开发。
Ⅱ 怎么学编程啊
如何学习编程,主要有自学和报班两种途径,至于需不需要报班,可以结合自己的实际情况来进行判断,这里简单介绍下。
学编程的注意点:
1、要确定好自己一定能学下去,不能是三分钟的热度,只是学个热闹,这样永远没有办法学的会。
2、一定要打好基础,刚开始学习编程的时候可能会很慢,感觉自己没学会啥,这可能是因为正处于打基础的阶段,只有把基础打好,未来才可以学得更好。
3、要注意实践操作,理论知识学得再多,如果不能实际的运用,还是等于0的。
自学还是报班:
1、如果你可以规划好自己的学习过程,坚持一步步向前走,那么自学当然是很好的。
2、如果你没人监督就学不进去,也没有自己的学习规划,那么还是建议你报班,可以少走冤枉路。
不管是自学还是报班,学编程的要注意的点是相差不大的,希望我的回答对你有帮助!
Ⅲ c语言的主要功能是保数据吗
其实,主要功能是效率和语法 。。。。。。。。。。
Ⅳ 麻烦给完整编程
print('\n'.join(input('请输入多种水果名称:').strip().split()))
Ⅳ 如何将linux下的程序,移植到freertos中
方法/步骤
嵌入式操作系统有分时操作系统和实时操作系统,如果操作系统能够使计算机系统及时响应外部事件请求,并能控制所有实时设备和实时任务协调运行,且能在一个规定的时间内完成对事件的处理,怎么这种系统称为实时操作系统。
如果系统必须在极其严格的时间内完成的任务叫做硬件的实时操作系统,如果不是很严格的话就是软件的实时操作系统。
Ⅵ LINUX 和 WINDOWS 内核的区别
二者最大的区别在于WINDOWS是个商业软件,而LINUX是开源软件。商业软件的好处是可以集中一大批人力物力做一件事情。容易统一,兼容(因为客户需求)。而开源的好处在于灵活,开放。
在下面的比较中,我一般先介绍下WINDOWS的,然后再介绍LINUX的。
1、观念:商业 VS 开源
WINDOWS是个商业软件,它的源码是保密的. 当然,其他非MS的人也还是有机会看到源码的. 如果你和MS 签订一个NDA(NON DISCLOSURE AGREEMENT),那么你也有可能拿到WINDOWS代码.
不过对于广大穷学生,以及连VISUAL STUDIO都在用盗版的抠门公司来说,和MS签个NDA几乎是不可想象的. 所以在WINDOWS世界,想了解WINDOW 内核的具体信息变得很难. 只能靠DDK(DRIVER DEVELOPMENT KIT) 和WINDBG(内核调试工具)泄漏出来的一些. 然后就是REVERSE ENGINEERING (逆向工程,可以简单的理解为反汇编,实际上更复杂一些).
这也造成了 <WINDOWS INTERNALS> 一书超级火爆的原因. 因为它是微软授权的,而且公布了很多内部细节. 另外一本讲内核的书是<UNDOCUMENTED WINDOWS 2K SECRETS>,虽然老了点,但是很多内幕。关于WINDOWS, undocumented 和secrets 这2个字绝对是可以类比“超级美女”的字眼。因为这些东西平时是看不到的.
与此对应,在LINUX世界,常见的一个词是RTFS。也就是READ THE FXXXXXX SOURCE CODE (这句话据说最早出于linus torvalds, 也就是LINUX之父)。意思也就是说“去读该死的代码”。言外之意,我把代码都给你你了,你还想要啥啊?这就好像一个男人对他GF / LP / LD说,我把全部的银行帐户密码都给你了,你还想要啥啊?
其实他不知道(或者认识不到)女人还需要你的时间,精力来陪她。就好像LINUX 程序员意识不到文档也是很重要的。当然,LINUX程序员应该也是知道文档的重要的,不过一个是维护成本太高,另外是LINUX 内核变化太快。所以LINUX 的文档总感觉比MSDN要差点。
话说当年WIN 2K的源码泄漏出来了一些,我也迫不及待的下载了一份.虽然至今也没看过,但是拿到WINDOWS 源码的感觉,绝对不比娶了一个绝世美女差. (当然,真要娶老婆还是看内在).
相比之下, LINUX 是开源的,代码随时可见. 这对刚从WINDOWS世界转过来的我是十分震撼的. 虽然我一直都知道这个事实, 但是当你发现了以前需要用尽各种方法,采用各种手段才可以得到只言片语的信息现在完全呈献在你面前的时候,你才能真正体会开源确实是一件伟大的工程.
看了LINUX源码之后,我终于发现,原来内核里大部分也是C语言(而不是以前想象的汇编). 同时内核似乎也就那样,不像之前想象的那么神秘. 原来编译内核也就是比编译个普通程序稍微麻烦点,用的时间长点. 原来编译内核用普通的C编译器就可以. 原来内核也是一个普通的可执行文件.(PS: 我怀疑MS也是用VS来编译WINDOWS的. 同时我也知道WINDOWS内核也是一个可执行文件.) 原来更换内核是如此的简单.
终于,内核可以被我随便改了. 哇哈哈哈!
言规正传,我觉得商业也还是有好处的。比如兼容性好,我以前用WDM写一个驱动,最多改下编译选项就可以在WIN 98, WIN 2K, WIN XP下运行。十分方便。而如果换成LINUX,那么你只好祈祷不同的内核版本之间没改那些你用到的头文件,函数接口。否则就要改代码了。
同时,开源的好处是适合学习,十分灵活。我觉得LINUX十分适合学校,学生。因为开源,当你发现不明白的地方的时候,可以直接去看源码(还记得RTFS? )。看不懂还可以到论坛上问。而对于WINDOWS,你想了解它的内部机制就只好GOOGLE,然后祈祷了。比较好的一个资源是MSDN下面的一个杂志,其中有一个主题叫UNDER THE HOOD, 或者搜搜 BUGSLAYER 也可以。这2个专题的作者Matt Pietrek和John Robbins都是大牛级的人物。
顺便说下UNDER THE HOOD 这个名字本身。以前一直不太理解,因为查字典的话,HOOD 的意思也就是个盖子。那么盖子下面有啥呢?为啥要看盖子下面呢?
来到美国之后,我渐渐明白了。HOOD 在这里应该理解为汽车的引擎盖。在美国,汽车是很普遍的。如果你开车,但是从来没打开过引擎盖,那么说明你只会用,而不了解汽车内部。那么如果你打开盖子看看呢?就可以看到很多内部细节,比如发动机啥的了。
在美国这个汽车王国,很多软件术语和汽车有关,因为人们日常生活中对汽车也很了解。比如“引擎”这个词,以前玩3D游戏的时候,常会看到介绍说,本游戏采用了最新的3D引擎。啥意思呢?就是游戏最核心的部分(汽车引擎)已经升级了。不是只把外面的人物形象改了下而已。
另外,开源软件也经常用汽车来类比。开源意外着你买了车(软件)后,可以随便拿到一个修理厂去修。也就是什么人都可以改,只要他懂。而COPY RIGHT 软件呢,就是你买了车,但是引擎盖子是锁着的,坏了只能去生产厂家修,其他人修不了。如果万一生产厂家不想修或者不会修呢?那你就只能认命了。
扯得有点远了,打住。
1.1、发布:2进制 VS 源码
这里主要讨论下WINDOWS和LINUX在发布程序采用的不同的形式和观念,这些和前面的商业还是开源的基本观念是联系在一起的。
在WINDOWS 世界,安装程序几乎全部都是以二进制形式发布的。也就是说,用户下载了一个程序,然后双击,一路NEXT,NEXT,NEXT就可以了。这个方法很适合初学者。在LINUX世界也有类似的机制,比如YUM, APT-GET 等。不过YUM和APT-GET都是比较晚才出现的,在那之前,在LINUX世界安装程序要更麻烦些。
有的时候,LINUX的YUM, APT-GET还不够用。比如有的人写的一个小软件,没有放到这些大的公共的库里面。这时,你就会发现他们一般提供一个或者一堆源文件,然后需要使用者自己下载,“编译”,安装。这也就是LINUX世界常见的源代码发布的形式。
一开始的时候,十分不习惯LINUX的这种发布形式。用惯了WINDOWS的双击安装,总觉得LINUX的安装很麻烦,又要自己./CONFIGURE, MAKE, MAKE INSTALL. 万一这个软件又依赖于其他的库,那么又要自己去找那些库,万一那些库又依赖其他的库...... 另外,各种库的版本也是一个问题,万一不兼容,那么又要找一个兼容的。
为什么LINUX世界这么多源代码发布呢?为什么WINDOWS世界流行2进制文件发布,而不是源代码呢?关于后者,很好解释,因为WINDOWS那边很多源代码都是商业秘密,是不公开的。同时,WINDOWS的程序用到的那些库在一般的系统里都装好了。所以2进制发布可行,也十分方便。
关于前一个问题,我觉得源代码发布的一个好处是可以在编译的时候进行一些优化和设置。比如同样的代码,在32或64位平台下编译的时候可以进行适当的优化。另外,用户也可以在编译的时候设置一些开关,这样在编译期间的优化一般要好于运行时间的优化。
不过源代码发布的一个坏处就是对使用者要求较高。如果运行configue,make命令顺利的话还好。如果万一不顺利,要自己改下头文件啥的,无疑是一般的使用者无法做到的。另外库之间的依赖关系如果是人手工处理的话也十分麻烦。好在LINUX世界后来有了YUM APT-GET之类的包管理系统。大多数软件都可以很方便的安装了。
2、进程及其创建 CreateProcess VS fork+execv
在WINDOWS世界,创建进程最常用的WIN 32 API 是 CreateProcess以及相关函数。这个函数需要一堆参数(WINDOWS API 的特点),不过很多参数可以简单的用NULL, TRUE OR FALSE来表示。另外,你直接告诉它要执行的是哪个文件。
到了LINUX世界,我模糊的知道fork是用来创建一个新进程的。但是当我看fork的函数说明的时候,呆住了。因为fork不需要任何参数。习惯了 CreateProcess 的10来个参数,突然换成一个不要任何参数的函数,感觉很奇妙。一方面觉得似乎事情简单了很多,不用去把10来个参数的每个意思都搞明白。另外一方面又很疑惑,我怎么告诉它我要执行某个文件呢?
后来才知道,LINUX中的进程的含义和WINDOWS中是不一样的。LINUX中的进程本身是可以执行的。而WINDOWS中,进程只是表示一个资源的拥有体,是不能执行的。要执行的话,一定需要一个线程。这也部分解释了为什么CreateProcess中为啥一定要传入要执行的文件的名字。
而fork的含义是把进程本身CLONE一个新的出来。也就是说,FORK之后,父进程和子进程都执行同样的一段代码。如果想区分的话,可以根据FORK的返回值来区分。引用一段fork的说明:
On success, the PID of the child process is returned in the parent's thread of execution, and a 0 is returned in the child's thread of execution.
同时在LINUX程序中,常见的写法如下:
int pid;
pid = fork();
switch (pid)
{
case 0: //I am the child
;
case -1: //failed.
;
default: //I am the parent
}
为什么要这样设计呢?因为LINUX的设计目标之一就是应用于服务器。这种情况下,一个SERVICE可能会启动很多进程(线程)来服务不同的CLIENT. 所以FORK设计成快速复制父进程。子进程直接使用父亲的地址空间,只有子进程加载一个新的可执行文件的时候才创建自己的地址空间。
这样节省了创建地址空间这个庞大的开销,使得LINUX的进程创建十分快。不过实际上,这里的进程相对于WINDOWS中的线程,所以同WINDOWS中的线程创建相比,二者的开销应该差不多。
那么如何才能让新的进程加载一个可执行文件呢,这时就要用execv以及相关函数了。所以LINUX中,代替CreateProcess()的函数是fork+execv
3、文件格式 PE VS ELF
WINDOWS中的可执行文件格式是PE。到了LINUX就变成了ELF。2者有相似的地方,比如都分成几个SECTION,包含代码段,数据段等。但是2个又不一样。使得从一个转到另外一个的人不得不重新学习下。有点象在国内开惯了车的人,到了香港或者英国开车,虽然也是4个轮子一个方向盘,但是一个靠左行驶,一个靠右。总是需要些时间来习惯。
那么为啥LINUX不能和WINDOWS用同样的文件格式呢?我觉得可能的原因有几个。首先可能是2个差不多同时在设计的,彼此不知道对方的存在。所以也没法一方压倒一方。另外一个可能的原因是PE格式最开始还是保密的(后来MS公开了PE的SPEC),所以即使LINUX想直接用PE都不行。
顺便说下,MS OFFICE 的文档格式以前也是保密的,直到最近(好像是2008年)才公开。希望这可以使得OPEN OFFICE的开发顺利很多。
4、内核API:固定 VS 非固定
WINDOWS内核有一套固定的API,而且向后兼容。这使得WINDOWS 驱动的开发人员在不同版本之间移植时变得很容易。比如我用WDM (WINDOWS DEVICE MODEL) 开发一个驱动,最多改下编译选项就可以在WIN 98, 2K, XP, 2003 下使用。VISTA 我觉得也许都可以。
而LINUX没有固定的内核API。2.4版本的内核模块在2.6几乎很大可能是不能兼容的。要移植的话,不只是改个编译选项,而是要改一堆的头文件和实现文件等。而麻烦的是,即使都是2.6内核,不同的小版本之间也有些不同。如果你的内核模块刚好用到了变化的部分,那么也只好重新学习,然后改自己的头文件或者实现文件了。
固定内核API的好处是兼容性好,坏处是包袱比较大,不得不随时支持老的,也许是过时的接口。比如WINDOWS内核里有WDM 一套API, 但是又有网卡专用的 NDIS 一套API. 实际上2套API的很多设计目标是重合的。那么为什么有2个呢?因为NDIS是先出来的,为了兼容性,一定要支持。而NDIS又只针对网卡,所以又出来了WDM。
不固定API的坏处是升级很麻烦,外围的内核模块维护者很辛苦。好处是可以随时采用更新的设计。
5. WINDOWS与LINUX中的中断处理比较
5.1不同之处:
在WINDOWS中,有一个IRQL (注意不是IRQ)的概念。最早的时候,我以为是CPU设计里就包括了这个东东。后来看INTEL CPU手册,发现似乎没有。最近又看了一遍WINDOWS INTERALS 4TH。感觉这个东西应该是包括在PIC OR APIC里面的(关于APIC,可以看我以前的帖子)。对于X86-32,硬件设备的IRQ于IRQL之间的关系是:IRQL= 27-IRQ。引入IRQL的动机似乎是这样的:当CPU运行在低IRQL时,如果来了一个高IRQL对应的中断,那么低的中断的ISR是会被高的ISR抢过去的。就是说低的ISR又被一个更高级的ISR中断了。这样的好处是优先级高的ISR可以更快的得到响应。
另外,在具体实现中,由于操作PIC OR APCI改IRQL是比较费时的,所以WINDOWS是尽量不去直接操作硬件,而是等到万不得已的时候才改。
在LINUX中,似乎没有类似IRQL这样的观念。就我目前看过的书和代码来看,LINUX中的ISR或者是KERNLE最多是操作下CPU上的中断标志位(IF)来开启或者关闭中断。也就是说,要么中断全开,要么全关。
从这一点来看,LINUX在这部分的设计上比WINDOWS简单。
5.2 相似之处:
WINDOWS和LINUX似乎都把中断分成了2部分。在LINUX中叫ISR(还是其他?)和BOTTOM HALF。而WINODWS中,DPC(Deferred Procere Calls)和APC(Asynchronous Procere Calls)就非常类似BOTTOM HALF。二者把中断分成两部分的动机是差不多的。都是为了把ISR搞得越快越好。LINUX中,在ISR里一般关中断,所以时间太长的话,其他中断就得不到响应。WINDOWS中,ISR跑在一个很高的IRQL里面,同样会阻塞其他IRQL比较低的任务。
LINUX中的BOTTOM HALF 又可以分为TASKLET 和SOFIRQ。二者的主要区别是复杂度和并发性(CONCURRENCY)。下面COPY自<UNDERSTANDING LINUX NETWORK INTERNALS>一书。
Tasklet: Only one instance of each tasklet can run at any time. Different tasklets can run concurrently on different CPUs.
Softirq: Only one instance of each softirq can run at the same time on a CPU. However, the same softirq can run on different CPUs concurrentlyOnly one instance of each softirq can run at the same time on a CPU. However, the same softirq can run on different CPUs concurrently.
WINDOWS中的DPC有点类似TASKLET和SOFTIRQ。 DPC是系统范围内的,并且运行在DPC IRQL。是一个类似中断上下文的环境(INTERRUPT CONTEXT)。APC和DPC的区别是运行在更低级别的APC IRQL。另外,APC是针对每一个线程的。执行在某个线程环境中。主要目的也是把一部分事情放到以后去执行。APC又分为KERNEL APC 和USER APC。APC这个观念在LINUX中似乎没有类似的?至少我还没想到。
5.3 参考文献:
1. WINDOWS INTERALS 4TH
2. UNDERSTANDING LINUX NETWORK INTERNALS, 2005
UNICODE VS ASCII
KERNEL 4M/4K MIXED PAGE VS 4K PAGE
FS SEGMENT VS NO FS
GDI VS XWINDOWS
IRP VS FUNCTION POINTER
注册表 VS 普通文件
Ⅶ Linux内核API完全参考手册的目录
前言 本书使用方法第1章 Linux内核API分析必备知识 1Linux内核编程注意事项 1本书中模块编译Makefile模板 1内核调试函数printk 2内核编译与定制 4温馨提示 10参考文献 11第2章 Linux内核模块机制API 12函数:__mole_address ( ) 12函数:__mole_ref_addr ( ) 14函数:__mole_text_address ( ) 16函数:__print_symbol ( ) 18函数:__symbol_get ( ) 20函数:__symbol_put ( ) 22函数:find_mole ( ) 24函数:find_symbol ( ) 27函数:mole_is_live ( ) 30函数:mole_put ( ) 32函数:mole_refcount ( ) 34函数:sprint_symbol ( ) 36函数:symbol_put_addr ( ) 38函数:try_mole_get ( ) 40函数:use_mole ( ) 42参考文献 44第3章 Linux进程管理内核API 45函数:__task_pid_nr_ns( ) 45函数:find_get_pid( ) 47函数:find_pid _ns( ) 49函数:find_task_by_pid_ns( ) 51函数:find_task_by_pid_type _ns( ) 53函数:find_task_by_vpid( ) 55函数:find_vpid( ) 57函数:get_pid( ) 59函数:get_task_mm( ) 60函数:is_container_init( ) 63函数:kernel_thread( ) 65函数:mmput( ) 67函数:ns_of_pid( ) 69函数:pid_nr( ) 71函数:pid_task( ) 73函数:pid_vnr( ) 75函数:put_pid( ) 77函数:task_active_pid_ns( ) 79函数:task_tgid_nr_ns( ) 81参考文献 83第4章 Linux进程调度内核API 84函数:__wake_up( ) 84函数:__wake_up_sync( ) 87函数:__wake_up_sync_key( ) 89函数:abort_exclusive_wait( ) 91函数:add_preempt_count( ) 95函数:add_wait_queue( ) 97函数:add_wait_queue_exclusive( ) 100函数:autoremove_wake_function( ) 102函数:complete( ) 106函数:complete_all( ) 108函数:complete_done( ) 111函数:current_thread_info( ) 113函数:default_wake_function( ) 115函数:do_exit( ) 118函数:finish_wait( ) 120函数:init_waitqueue_entry( ) 123函数:init_waitqueue_head( ) 125函数:interruptible_sleep_on( ) 127函数:interruptible_sleep_on_timeout( ) 130函数:preempt_notifier_register ( ) 133函数:preempt_notifier_unregister ( ) 136函数:prepare_to_wait( ) 139函数:prepare_to_wait_exclusive( ) 142函数:remove_wait_queue( ) 146函数:sched_setscheler( ) 149函数:set_cpus_allowed_ptr( ) 152函数:set_user_nice( ) 155函数:sleep_on( ) 158函数:sleep_on_timeout( ) 160函数:sub_preempt_count( ) 162函数:task_nice( ) 164函数:try_wait_for_completion( ) 166函数:wait_for_completion( ) 169函数:wait_for_completion_interruptible( ) 172函数:wait_for_completion_interruptible_ timeout( ) 175函数:wait_for_completion_killable( ) 179函数:wait_for_completion_timeout( ) 182函数:wake_up_process( ) 184函数:yield( ) 187参考文献 188第5章 Linux中断机制内核API 189函数:__set_irq_handler( ) 189函数:__tasklet_hi_schele( ) 191函数:__tasklet_schele( ) 194函数:disable_irq( ) 196函数:disable_irq_nosync( ) 196函数:disable_irq_wake( ) 198函数:enable_irq( ) 201函数:enable_irq_wake( ) 203函数:free_irq( ) 205函数:kstat_irqs_cpu( ) 207函数:remove_irq( ) 209函数:request_irq( ) 213函数:request_threaded_irq( ) 216函数:set_irq_chained_handler( ) 219函数:set_irq_chip( ) 221函数:set_irq_chip_data( ) 225函数:set_irq_data( ) 227函数:set_irq_handler( ) 229函数:set_irq_type( ) 232函数:set_irq_wake( ) 234函数:setup_irq( ) 237函数:tasklet_disable( ) 239函数:tasklet_disable_nosync( ) 241函数:tasklet_enable( ) 243函数:tasklet_hi_enable( ) 244函数:tasklet_hi_schele( ) 246函数:tasklet_init( ) 248函数:tasklet_kill( ) 250函数:tasklet_shele( ) 252函数:tasklet_trylock( ) 254函数:tasklet_unlock( ) 255参考文献 257第6章 Linux内存管理内核API 258函数:__free_pages( ) 258函数:__get_free_pages( ) 258函数:__get_vm_area( ) 260函数:__krealloc( ) 262函数:alloc_pages( ) 265函数:alloc_pages_exact( ) 268函数:alloc_vm_area( ) 270函数:do_brk( ) 272函数:do_mmap( ) 273函数:do_mmap_pgoff( ) 276函数:do_munmap( ) 279函数:find_vma( ) 281函数:find_vma_intersection( ) 284函数:free_pages( ) 286函数:free_pages_exact( ) 287函数:free_vm_area( ) 288函数:get_unmapped_area( ) 288函数:get_user_pages( ) 290函数:get_user_pages_fast( ) 292函数:get_vm_area_size( ) 294函数:get_zeroed_page( ) 295函数:kcalloc( ) 297函数:kfree( ) 299函数:kmalloc( ) 299函数:kmap_high( ) 301函数:kmem_cache_alloc( ) 303函数:kmem_cache_create( ) 305函数:kmem_cache_destroy( ) 308函数:kmem_cache_free( ) 308函数:kmem_cache_zalloc( ) 309函数:kmemp( ) 311函数:krealloc( ) 313函数:ksize( ) 315函数:kstrp( ) 318函数:kstrnp( ) 319函数:kunmap_high( ) 321函数:kzalloc( ) 321函数:memp_user( ) 323函数:mempool_alloc( ) 325函数:mempool_alloc_pages( ) 327函数:mempool_alloc_slab( ) 329函数:mempool_create( ) 331函数:mempool_create_kzalloc_pool ( ) 333函数:mempool_destroy( ) 334函数:mempool_free( ) 335函数:mempool_free_pages( ) 335函数:mempool_free_slab( ) 336函数:mempool_kfree( ) 336函数:mempool_kmalloc( ) 337函数:mempool_kzalloc( ) 339函数:mempool_resize( ) 341函数:nr_free_buffer_pages( ) 343宏:page_address( ) 345宏:page_cache_get( ) 346宏:page_cache_release( ) 348函数:page_zone( ) 349宏:probe_kernel_address( ) 352函数:probe_kernel_read( ) 354函数:probe_kernel_write( ) 355函数:vfree( ) 357函数:vma_pages( ) 358函数:vmalloc( ) 359函数:vmalloc_to_page( ) 361函数:vmalloc_to_pfn( ) 363函数:vmalloc_user( ) 365参考文献 366第7章 Linux内核定时机制API 368函数:__round_jiffies( ) 368函数:__round_jiffies_relative( ) 369函数:__round_jiffies_up( ) 371函数:__round_jiffies_up_relative( ) 373函数:__timecompare_update( ) 375函数:add_timer( ) 377函数:current_kernel_time( ) 378函数:del_timer( ) 380函数:del_timer_sync( ) 382函数:do_gettimeofday( ) 384函数:do_settimeofday( ) 386函数:get_seconds( ) 388函数:getnstimeofday( ) 390函数:init_timer( ) 391函数:init_timer_deferrable( ) 393函数:init_timer_deferrable_key( ) 395函数:init_timer_key( ) 398函数:init_timer_on_stack( ) 400函数:init_timer_on_stack_key( ) 402函数:mktime( ) 404函数:mod_timer( ) 406函数:mod_timer_pending( ) 408函数:ns_to_timespec( ) 410函数:ns_to_timeval( ) 412函数:round_jiffies( ) 414函数:round_jiffies_relative( ) 416函数:round_jiffies_up( ) 418函数:round_jiffies_up_relative( ) 420函数:set_normalized_timespec( ) 422函数:setup_timer( ) 424函数:setup_timer_key( ) 426函数:setup_timer_on_stack( ) 428函数:setup_timer_on_stack_key( ) 430函数:timecompare_offset( ) 432函数:timecompare_transform( ) 435函数:timecompare_update( ) 436函数:timer_pending( ) 439函数:timespec_add_ns( ) 441函数:timespec_compare( ) 442函数:timespec_equal( ) 444函数:timespec_sub( ) 446函数:timespec_to_ns( ) 448函数:timeval_compare( ) 450函数:timeval_to_ns( ) 452函数:try_to_del_timer_sync( ) 453参考文献 456第8章 Linux内核同步机制API 457函数:atomic_add( ) 457函数:atomic_add_negative( ) 458函数:atomic_add_return( ) 460函数:atomic_add_unless( ) 461宏:atomic_cmpxchg( ) 463函数:atomic_dec( ) 464函数:atomic_dec_and_test( ) 466函数:atomic_inc( ) 467函数:atomic_inc_and_test( ) 469宏:atomic_read( ) 470宏:atomic_set( ) 471函数:atomic_sub( ) 472函数:atomic_sub_and_test( ) 474函数:atomic_sub_return( ) 475函数:down( ) 477函数:down_interruptible( ) 479函数:down_killable( ) 481函数:down_read( ) 483函数:down_read_trylock( ) 485函数:down_timeout( ) 487函数:down_trylock( ) 489函数:down_write( ) 491函数:down_write_trylock( ) 492函数:downgrade_write( ) 494宏:init_rwsem( ) 496宏:read_lock( ) 498函数:read_seqbegin( ) 499函数:read_seqretry( ) 500宏:read_trylock( ) 503宏:read_unlock( ) 504宏:rwlock_init( ) 505函数:sema_init( ) 508宏:seqlock_init( ) 509宏:spin_can_lock( ) 511宏:spin_lock( ) 513宏:spin_lock_bh( ) 514宏:spin_lock_init ( ) 516宏:spin_lock_irq( ) 518宏:spin_lock_irqsave( ) 520宏:spin_trylock( ) 522宏:spin_unlock( ) 525宏:spin_unlock_bh( ) 526宏:spin_unlock_irq( ) 526宏:spin_unlock_irqrestore( ) 527宏:spin_unlock_wait( ) 527函数:up( ) 529函数:up_read( ) 531函数:up_write( ) 532宏:write_lock( ) 532函数:write_seqlock( ) 534函数:write_sequnlock( ) 534宏:write_trylock( ) 535宏:write_unlock( ) 537参考文献 537第9章 Linux文件系统内核API 539函数:__mnt_is_readonly( ) 539函数:current_umask( ) 541函数:d_alloc( ) 542函数:d_alloc_root( ) 544函数:d_delete( ) 547函数:d_find_alias( ) 547函数:d_invalidate( ) 549函数:d_move( ) 550函数:d_validate( ) 551函数:dput( ) 553函数:fget( ) 554函数:find_inode_number( ) 557函数:generic_fillattr( ) 559函数:get_empty_filp( ) 561函数:get_fs_type( ) 563函数:get_max_files( ) 565函数:get_super( ) 566函数:get_unused_fd( ) 569函数:have_submounts( ) 570函数:I_BDEV( ) 572函数:iget_locked( ) 573函数:inode_add_bytes( ) 575函数:inode_get_bytes( ) 576函数:inode_needs_sync( ) 578函数:inode_set_bytes( ) 580函数:inode_setattr( ) 581函数:inode_sub_bytes( ) 584函数:invalidate_inodes( ) 586函数:is_bad_inode( ) 587函数:make_bad_inode( ) 588函数:may_umount( ) 590函数:may_umount_tree( ) 591函数:mnt_pin( ) 593函数:mnt_unpin( ) 594函数:mnt_want_write( ) 596函数:new_inode( ) 596函数:notify_change( ) 598函数:put_unused_fd( ) 600函数:register_filesystem( ) 602函数:unregister_filesystem( ) 604函数:unshare_fs_struct( ) 604函数:vfs_fstat( ) 606函数:vfs_getattr( ) 608函数:vfs_statfs( ) 610参考文献 613第10章 Linux设备驱动及设备管理API 614函数:__class_create( ) 614函数:__class_register( ) 615函数:cdev_add( ) 616函数:cdev_alloc( ) 617函数:cdev_del( ) 619函数:cdev_init( ) 624宏:class_create( ) 628函数:class_destroy( ) 629宏:class_register( ) 631函数:class_unregister( ) 632函数:device_add( ) 637函数:device_create( ) 638函数: device_del( ) 640函数:device_destroy( ) 640函数:device_initialize( ) 646函数:device_register( ) 652函数:device_rename( ) 652函数:device_unregister( ) 657函数:get_device( ) 663函数:put_device( ) 663函数:register_chrdev( ) 667函数:register_keyboard_notifier( ) 668函数:unregister_chrdev( ) 669函数:unregister_keyboard_notifier( ) 675部分相关函数说明 679参考文献 679附录 Linux内核API快速检索表 680