导航:首页 > 编程语言 > linuxkernel编程

linuxkernel编程

发布时间:2024-05-10 03:01:35

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是什么

Linux kernel 译为linux 内核,其基础为linux平台,linux为C语言编写的内核,基于此内核又衍生出了具体的Red hat linux 、open suse linux等具体的操作系统,一套基于Linux内核的完整操作系统叫作Linux操作系统,或是GNU/Linux。

对于linux kernel,先看它的目录结构,这里只挑几个重要的说明。
arch 包括所有和体系结构相关的核心代码。从里面我们能看到arm、alpha、i386、mips、ia64这些文件夹,每种处理器架构都有不一样的硬件模块,这里就是要针对不同的架构进行不同的初始化。
init包含内核的初始化代码(不是系统的引导代码),其中有一个main.c文件,用于执行内核所有的初始化工作(包括初始化内存、初始化所有硬件、创建第一个任务task0,设置中断允许标志位),然后移到用户模式调用fork()函数创建新进程,并在控制台运行shell。
kernel 包含内核管理的核心代码,瞅这名就知道,这货是个重量级目录,所有的处理任务的程序,包括fork、exit、调度程序(sched.c)以及一些系统调用(sys.c)、信号处理(signal.c)、时间函数(time.c),还有中断异常处理、电源管理等等一系列调用关系错综复杂的函数。
mm 包含所有的内存管理代码。其中包括实现进程的逻辑地址到实际物理地址的映射,实现分页、分段机制,实现内存页面异常中断处理程序等。
drivers包含系统中所有的设备驱动程序,比如什么cdrom啊bluetooth啊pci、i2c这些。
ipc 包含核心进程间的通信代码。
fs 存放Linux支持的文件系统代码,里面有ext2、ext3、ext4、fat、ntfs等等一堆目录。
net 内核的网络部分代码,其每个子目录对应于网络的一个方面,比如ieee80211、ipv4、ipv6这些目录。
lib 包含核心的库代码,什么strcpy、sprintf、sort这些函数都在里面。更多Linux知识可参考《Linux就该这么学》。

⑶ 什么是linux kernel有什么作用

Linux内核(英语:Linux kernel)是一种开源的类Unix操作系统宏内核。

工作于平板电脑、智能手机及智能手表的Android操作系统同样通过Linux内核提供的服务完成自身功能。

一个计算机系统是一个硬件和软件的共生体,它们互相依赖,不可分割。计算机的硬件,含有外围设备、处理器、内存、硬盘和其他的电子设备组成计算机的发动机。但是没有软件来操作和控制它,自身是不能工作的。

完成这个控制工作的软件就称为操作系统,在Linux的术语中被称为“内核”,也可以称为“核心”。Linux内核的主要模块(或组件)分以下几个部分:存储管理、CPU和进程管理、文件系统、设备管理和驱动、网络通信,以及系统的初始化(引导)、系统调用等。

整个Linux操作系统家族基于该内核部署在传统计算机平台(如个人计算机和服务器,以Linux发行版的形式)和各种嵌入式平台,如路由器、无线接入点、专用小交换机、机顶盒、FTA接收器、智能电视、数字视频录像机、网络附加存储(NAS)等。

工作于平板电脑、智能手机及智能手表的Android操作系统同样通过Linux内核提供的服务完成自身功能。尽管于桌面电脑的占用率较低,基于Linux的操作系统统治了几乎从移动设备到主机的其他全部领域。截至2017年11月,世界前500台最强的超级计算机全部使用Linux。

(3)linuxkernel编程扩展阅读:

编程语言

Linux是用C语言中的GCC版(这种C语言有对标准C进行扩展)写的,还有几个用汇编语言(用的是GCC的"AT&T风格")写的目标架构短段。因为要支持扩展的C语言,GCC在很长的时间里是唯一一个能正确编译Linux的编译器。

有许多其他的语言用在一些方面上,主要集中在内核构建过程中(这里指从源代码创建可引导镜像)。包括Perl、Python和多种脚本语言。有一些驱动可能是用C++、Fortran或其他语言写的,但是这样是强烈不建议的。

编译器兼容性

GCC是Linux内核源代码的缺省编译器。在2004年,Intel主张通过修改内核,以便Intel C++编译器能正确编译内核。在2009年,有通过修改内核2.6.22版而成功编译的报告(并带来平均8-9%性能增长)。

自从2010年,已经开始进行使用Clang建造Linux内核的努力,Clang是一个可作为替代的C语言编译器;截止2014年4月12日,官方内核几乎可以完全用Clang编译。致力于这个目标的计划叫做“LLVMLinux”,得名于Clang所基于的LLVM编译器下部构造。

LLVMLinux不意图复制Linux内核或LLVM,因此它是由最终提交给上游计划的补丁构成的一个元计划。使Linux内核可以用Clang编译最大的好处是比GCC有更快的编译速度,内核开发者可以得益于由此而来的更快的工作流程

⑷ 什么是LINUX内核编程

真佩服楼上的2位对“内核编程”的理解力!
简单说,Linux内核编程就是开发Linux驱动程序,学会内核编程后,将会对操作系统的内部机制和工作原理有充分了解,可以从事硬件驱动开发、嵌入式系统开发等。内核编程的语言仍是传统的C语言,但其编写方法和调用接口与传统应用程序的差别较大,你必须了解如何处理中断、如何在内核态和用户态之间转换、PCI、DMA、内核地址映射、内核I/O等,这不是《UNIX高级编程》所涉及的内容,可以找一本专门讲Linux驱动编程的书看看,或在网上搜寻相关资料(关键词:Linux DDK)。不过先提醒一句,学习内核编程的难度很大,必须做好长期心理准备

⑸ linux编译内核步骤

一、准备工作
a) 首先,你要有一台PC(这不废话么^_^),装好了Linux。
b) 安装好GCC(这个指的是host gcc,用于编译生成运行于pc机程序的)、make、ncurses等工具。
c) 下载一份纯净的Linux内核源码包,并解压好。

注意,如果你是为当前PC机编译内核,最好使用相应的Linux发行版的源码包。

不过这应该也不是必须的,因为我在我的Fedora 13上(其自带的内核版本是2.6.33.3),就下载了一个标准的内核linux-2.6.32.65.tar.xz,并且顺利的编译安装成功了,上电重启都OK的。不过,我使用的.config配置文件,是Fedora 13自带内核的配置文件,即/lib/moles/`uname -r`/build/.config

d) 如果你是移植Linux到嵌入式系统,则还要再下载安装交叉编译工具链。

例如,你的目标单板CPU可能是arm或mips等cpu,则安装相应的交叉编译工具链。安装后,需要将工具链路径添加到PATH环境变量中。例如,你安装的是arm工具链,那么你在shell中执行类似如下的命令,假如有类似的输出,就说明安装好了。
[root@localhost linux-2.6.33.i686]# arm-linux-gcc --version
arm-linux-gcc (Buildroot 2010.11) 4.3.5
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for ing conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
注:arm的工具链,可以从这里下载:回复“ARM”即可查看。

二、设置编译目标

在配置或编译内核之前,首先要确定目标CPU架构,以及编译时采用什么工具链。这是最最基础的信息,首先要确定的。
如果你是为当前使用的PC机编译内核,则无须设置。
否则的话,就要明确设置。
这里以arm为例,来说明。
有两种设置方法():

a) 修改Makefile
打开内核源码根目录下的Makefile,修改如下两个Makefile变量并保存。
ARCH := arm
CROSS_COMPILE := arm-linux-

注意,这里cross_compile的设置,是假定所用的交叉工具链的gcc程序名称为arm-linux-gcc。如果实际使用的gcc名称是some-thing-else-gcc,则这里照葫芦画瓢填some-thing-else-即可。总之,要省去名称中最后的gcc那3个字母。

b) 每次执行make命令时,都通过命令行参数传入这些信息。
这其实是通过make工具的命令行参数指定变量的值。
例如
配置内核时时,使用
make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig
编译内核时使用
make ARCH=arm CROSS_COMPILE=arm-linux-

注意,实际上,对于编译PC机内核的情况,虽然用户没有明确设置,但并不是这两项没有配置。因为如果用户没有设置这两项,内核源码顶层Makefile(位于源码根目录下)会通过如下方式生成这两个变量的值。
SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
-e s/arm.*/arm/ -e s/sa110/arm/ \
-e s/s390x/s390/ -e s/parisc64/parisc/ \
-e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
-e s/sh[234].*/sh/ )
ARCH?= $(SUBARCH)
CROSS_COMPILE ?=

经过上面的代码,ARCH变成了PC编译机的arch,即SUBARCH。因此,如果PC机上uname -m输出的是ix86,则ARCH的值就成了i386。

而CROSS_COMPILE的值,如果没配置,则为空字符串。这样一来所使用的工具链程序的名称,就不再有类似arm-linux-这样的前缀,就相当于使用了PC机上的gcc。

最后再多说两句,ARCH的值还需要再进一步做泛化。因为内核源码的arch目录下,不存在i386这个目录,也没有sparc64这样的目录。

因此顶层makefile中又构造了一个SRCARCH变量,通过如下代码,生成他的值。这样一来,SRCARCH变量,才最终匹配到内核源码arch目录中的某一个架构名。

SRCARCH := $(ARCH)

ifeq ($(ARCH),i386)
SRCARCH := x86
endif

ifeq ($(ARCH),x86_64)
SRCARCH := x86
endif

ifeq ($(ARCH),sparc64)
SRCARCH := sparc
endif

ifeq ($(ARCH),sh64)
SRCARCH := sh
endif

三、配置内核

内核的功能那么多,我们需要哪些部分,每个部分编译成什么形式(编进内核还是编成模块),每个部分的工作参数如何,这些都是可以配置的。因此,在开始编译之前,我们需要构建出一份配置清单,放到内核源码根目录下,命名为.config文件,然后根据此.config文件,编译出我们需要的内核。

但是,内核的配置项太多了,一个一个配,太麻烦了。而且,不同的CPU架构,所能配置的配置项集合,是不一样的。例如,某种CPU的某个功能特性要不要支持的配置项,就是与CPU架构有关的配置项。所以,内核提供了一种简单的配置方法。

以arm为例,具体做法如下。

a) 根据我们的目标CPU架构,从内核源码arch/arm/configs目录下,找一个与目标系统最接近的配置文件(例如s3c2410_defconfig),拷贝到内核源码根目录下,命名为.config。

注意,如果你是为当前PC机编译内核,最好拷贝如下文件到内核源码根目录下,做为初始配置文件。这个文件,是PC机当前运行的内核编译时使用的配置文件。
/lib/moles/`uname -r`/build/.config
这里顺便多说两句,PC机内核的配置文件,选择的功能真是多。不编不知道,一编才知道。Linux发行方这样做的目的,可能是想让所发行的Linux能够满足用户的各种需求吧。

b) 执行make menuconfig对此配置做一些需要的修改,退出时选择保存,就将新的配置更新到.config文件中了。

阅读全文

与linuxkernel编程相关的资料

热点内容
真空压缩袋手泵怎么用 浏览:425
镜面的命令 浏览:202
51单片机蓝牙模块有延迟 浏览:114
b解压药 浏览:568
跳空缺口指标源码怎么写 浏览:699
怎么杀掉服务器上所有进程 浏览:179
c语言中水仙花数的算法分析 浏览:493
心烦时玩儿的解压神器 浏览:496
linux安装的库文件 浏览:919
加密货币架构分析 浏览:523
我的世界怎么把材料包加到服务器里 浏览:757
平板内存卡新建文件夹失败 浏览:204
python模块打包 浏览:360
腾讯云服务器centos没有桌面 浏览:891
冒泡排序算法实验心得 浏览:687
php入侵教程 浏览:103
航电服务器地址 浏览:23
pdf是撒 浏览:488
五格数学算法 浏览:172
服务器怎么添加连接 浏览:17