1.linux内核源码目录结构1

源码从哪里来
  • 之前讲过,我们使用2.6.35.7版本的内核。这个版本的内核有三种:第一种是kernel.org上的官方版本,第二种是三星移植过的,第三种是九鼎X210的移植版本。我们讲课时使用第三种内核来讲解,后面的移植实验使用第二种内核来移植。
  • 源码在开发板光盘中有。可以自己去linux下解压然后make distclean清理然后再次打包传输到windows下去解压分析;也可以直接去我网盘中下载我打包好的。
  • 解压后最终在windows下得到了一个kernel的源码目录树,这个源码目录就是九鼎以三星移植过的内核为原材料自己针对X210移植后的内核版本。
  • 分析源码目录下的单个文件

    1 .mailmap      //开发者的邮箱
    2 COPYING       //版权
    3 COPYING.txt    //版权    
    4 CREDITS       //感谢
    5 initrd.img.cpio  //设备树传参
    6 Kbuild        //就是内核编译的意思。这个文件就是linux内核特有的内核编译体系需要用到的文件。
    7 Makefile      //这个是linux内核的总makefile,整个内核工程用这个Makefile来管理的。
    8 mk          //是九鼎在移植时自己添加的,不是linux内核本身的东西。九鼎添加这个文件的作用是用这个文件来整天管理kernel目录的配置和编译,也就是说这个文件有点类似于我们之前移植uboot时自己创建的那个cp.sh。
    9 README       //说明

简单讲一下linux内核的配置体系。
  • linux内核很庞大,里面模块很多,而且可配置性非常高。所以linux源代码的配置是一个很复杂的事情,必须要有一套很复杂的机制来保证linux内核可以被正确的配置。(对比一下uboot,uboot的配置项都是在xxx.h中,用宏定义来表示的。uboot的这种方式很依赖于人的水平,因为uboot的配置体系很简单。)
  • linux内核本身配置项有上千个,光靠人眼睛去看脑袋去记根本不可能,所以内核发明了一种体系用来帮助人进行简单化的配置。这种体系就是我们本次重点要研究的东西。
  • Kbuild、Kconfig等文件,都是和内核的配置体系有关的。

2.linux内核源码目录结构2

  • linux目录结构

     1 arch      //arch是architecture的缩写,意思是架构。arch目录下是好多个不同架构的CPU的子目录,譬如arm这种cpu的所有文件都在arch/arm目录下,X86的CPU的所有文件都在arch/x86目录下。2 block      //在linux中block表示块设备(以块(多个字节组成的整体,类似于扇区)为单位来整体访问),譬如说SD卡、iNand、Nand、硬盘等都是块设备。你几乎可以认为块设备就是存储设备。block目录下放的是一些linux存储体系中关于块设备管理的代码。    3 crypto     //英文意思是加密。这个目录下放了一些各种常见的加密算法的C语言代码实现。譬如crc32、md5、sha1等。4 Documentation //里面放了一些文档。5 drivers    //驱动目录,里面分门别类的列出了linux内核支持的所有硬件设备的驱动源代码。6 firmware  //固件。什么是固件?固件其实是软件,不过这个软件是固化到IC里面运行的叫固件。就像S5PV210里的iROM代码。7 fs       //fs就是file system,文件系统,里面列出了linux支持的各种文件系统的实现。8 include  //头文件目录,公共的(各种CPU架构共用的)头文件都在这里。每种CPU架构特有的一些头文件在arch/arm/include目录及其子目录下9 init    //init是初始化的意思,这个目录下的代码就是linux内核启动时初始化内核的代码。
    10 ipc    //ipc就是inter process commuication,进程间通信,里面都是linux支持的IPC的代码实现。
    11 kernel    //kernel就是内核,就是linux内核,所以这个文件夹下放的就是内核本身需要的一些代码文件。
    12 lib    //lib是库的意思,这里面都是一些公用的有用的库函数,注意这里的库函数和C语言的库函数不一样的。在内核编程中是不能用C语言标准库函数,这里的lib目录下的库函数就是用来替代那些标准库函数的。譬如在内核中要把字符串转成数字用atoi,但是内核编程中只能用lib目录下的atoi函数,不能用标准C语言库中的atoi。譬如在内核中要打印信息时不能用printf,而要用printk,这个printk就是我们这个lib目录下的。
    13 mm     //mm是memory management,内存管理,linux的内存管理代码都在这里
    14 net    //该目录下是网络相关的代码,譬如TCP/IP协议栈等都在这里。
    15 samples  //一些实例代码
    16 scripts   //脚本,这个目录下全部是脚本文件,这些脚本文件不是linux内核工作时使用的,而是用来辅助对linux内核进行配置编译生产的。我们并不会详细进入分析这个目录下的脚本,而是通过外围来重点学会配置和编译linux内核即可
    17 security  //安全相关的代码。不用去管。
    18 sound   //音频处理相关的。
    19 tools    //linux中用到的一些有用工具
    20 usr    //目录下是initramfs相关的,和linux内核的启动有关,暂时不用去管
    21 virt   //内核虚拟机相关的,暂时不用管。

  • 总结:这么多目录跟我们关系很紧密的就是arch和drivers目录,然后其他有点相关的还有include、block、mm、net、lib等目录。

3.内核配置和编译体验

先确认Makefile
  • 主要是检查交叉编译工具链有没有设置对。CROSS_COMPILE ?= /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi-
  • 确认ARCH = arm。主要目的是为了编译时能找到arch/arm目录。
make x210ii_qt_defconfig
  • 最后只要出现:configuration written to .config这句话,就证明我们的操作是正确的。如果没有出现这句话,就有错误。
  • 可能出现的错误1:名字敲错了。名字是字符串匹配的,一定要正确。
  • 注意:如果这一步配置没有得到.config文件,是不能进行到下一步的。实际测试时没有.config也可以make menuconfig,但是这样做出来的内核编译和烧写运行应该是有问题的。
make menuconfig
  • 可能出现的错误1:ncurses库没装
  • 错误信息:
    *** Unable to find the ncurses libraries or the
    *** required header files.
    *** 'make menuconfig' requires the ncurses libraries.
    ***
    *** Install ncurses (ncurses-devel) and try again.

  • 解决方案: apt-get install libncurses5-dev (参考了:http://blog.csdn.net/yao_qinwei/article/details/8805101)
  • 可能出现的错误2:屏幕太小
  • 错误信息:
    Your display is too small to run Menuconfig!
    It must be at least 19 lines by 80 columns.

  • 解决方案:全屏,或者是把字体调小。
  • 总结:make menuconfig是第二步配置,具体的用法和配置意义在后面课程讲。我们这里因为是九鼎已经移植过的,所以第二步配置是可以不做的,直接退出即可。
  • 用键盘的向右方向键移动到EXIT,按回车退出。

make

  • 可能出现的错误1:莫名其妙的错误,可以试试先make distclean
  • 代码本身的错误:具体问题具体分析
  • 编译完成后得到的内核镜像不在源码树的根目录下,在arch/arm/boot这个目录下。得到的镜像名是zImage

4.内核的配置原理1

烧写测试
配置的关键是得到.config文件
  • .config以.开头,是一个隐藏文件,因此平时是看不到的,需要ls -a来看
  • 当我们make distclean后(也就是说默认情况下)是没有.config文件的,我们配置的两步过程就是为了得到内容合适的.config文件
  • .config文件是linux内核在编译过程中很重要的一个文件,其作用类似与uboot中的include/configs/x210_sd.h,内核在编译过程中会读取.config中的配置项,并且用这些配置项去指导整个编译链接过程。
  • .config文件的格式类似于脚本文件,其中内容为类似于于:CONFIG_ARM=y的一个一个的配置项。这些配置项就类似于脚本文件中定义的一个一个变量,所以这一行可以被理解为定义了一个变量CONFIG_ARM,这个变量的值为y。
  • .config文件中每一行都是一个配置项,从.config文件的规模可以看出linux内核的可配置项有两三千个。所以linux内核是高度可配置的,而且linux内核的所有配置项很难全部搞明白。因为linux内核的配置项太多太繁杂超出了人的大脑能够记忆和处理的数量级,因此linux内核不像uboot那样直接手工配置,而是发明了一个图形化的配置工具menuconfig。
make xx_defconfig 和 make menuconfig相配合
  • 我们为了对.config文件中的两三千个配置项做逐一合适的配置,专门发明了两步结合的配置方式。
  • 其实只要人的记忆足够好,大脑足够厉害,完全可以手工去书写/修改.config文件完成内核配置,最终只要.config中内容是正确的,就不影响编译过程。
  • 第一步:make xxx_defconfig解决的问题是大部分的配置项(这一步结束后99%的配置项就已经正确了),下来就是对个别不同的针对我们的开发板进行细节调整,细节调整就通过make menuconfig来完成。
  • make xxx_defconfig这一步其实是参考别人已经做好的,这样做有很多好处:减少很多工作量,避开了很多自己不懂的配置项(譬如对内存管理的、调度系统的等模块的配置项),我们只用管自己需要管的。
  • make menuconfig其实就是读取第一步得到的 .config,然后给我们一个图形化的界面,让我们可以更加容易的找到自己想要修改的配置项,然后更改配置他。
make xx_defconfig到底做了什么?
  • make x210ii_qt_defconfig  其实相当于:cp arch/arm/configs/x210ii_qt_defconfig .config
  • arch/arm/configs目录下的这么多个xxx_defconfig哪里来的?其实这些文件都是别人手工配置好适合一定的开发板的.config文件后自己把.config文件保存过去的。譬如说我们用S5PV210这个SoC,针对这个SoC的开发板的最初配置肯定是三星的工程师去做的。

5.menuconfig的使用和演示

使用说明解释
  • make ,menuconfig中本身自带的提示就有所有的用法,这里只要全部理解就可以了。
  • menuconfig中间的选择区中有很多个选择项,menuconfig中每个选择项对应.config文件中的一个配置项,每一个选择项都可以被选择和配置操作,选择区中的每一项都是有子目录的,将光标放在选择项上按Enter键可以进入子目录(子目录可能还会有子目录)。选择区太短放不下所有的一个目录层级的选项,可以用箭头按键的向上箭头和向下箭头来上翻和下翻。
  • 注:在menuconfig中操作相关的几个键盘按键,主要是;Enter、ESC、四个方向箭头按键。还有一些特殊字符按键,如/ ?
  • 向上和向下箭头,主要用来在选择项菜单中目录浏览时上下翻
  • 回车,主要作用是选中并且执行select/exit/help。
  • ESC,主要作用是返回上一层
  • 向左和向右箭头,主要作用是在菜单选项(select、exit、help)间切换。
  • 用法翻译:
  • 箭头按键导航整个菜单,回车按键选择子菜单(注意选项后面有 --->的选项才是有子菜单的,没有这个标识的没有子菜单),高亮的字母是热键(快捷键),键盘按键Y、N、M三个按键的作用分别是将选中模块编入、去除、模块化。双击ESC表示退出,按下?按键可以显示帮助信息,按下/按键可以输入搜索内容来全局搜索信息(类似于vi中的搜索),[]不可以模块化,<>的才可以模块化。
  • 注:linux内核中一个功能模块有三种编译方法:编入、去除、模块化。
  • 编入就是将这个模块的代码直接编译连接到zImage中去,用 * 号表示,快捷键:Y
  • 去除就是将这个模块不编译链接到zImage中,用 空白 表示, 快捷键:N
  • 模块化是将这个模块仍然编译,但是不会将其链接到zImage中,用 M 表示,快捷键:M
  • 模块化会将这个模块单独链接成一个内核模块.ko文件,将来linux系统内核启动起来后可以动态的加载或卸载这个模块。
  • 在menuconfig中选项前面的括号里,*表示编入,空白表示去除,M表示模块化, < > 表示可模块化,[ ] 表示不可模块化。

6.menuconfig的工作原理

menuconfig本身由一套软件支持的
  • linux为了实现图形化界面的配置,专门提供了一套配置工具menuconfig。
  • ncurses库是linux中用来实现文字式的图形界面,linux内核中使用了ncurses库来提供 menuconfig
  • scripts\kconfig\lxdialog目录下的一些c文件就是用来提供menuconfig的那些程序源代码。
menuconfig读取Kconfig文件
  • menuconfig本身的软件只负责提供menuconfig工作的这一套逻辑(譬如在menuconfig中通过上下左右箭头按键来调整光标,Enter ESC键等按键按下的响应),而并不负责提供内容(菜单里的项目)。
  • menuconfig显示的菜单内容(一方面是菜单的目录结构,另一方面是每一个菜单项目的细节)是由内核源码树各个目录下的 Kconfig 文件来支持的。Kconfig文件中按照一定的格式包含了一个又一个的配置项,每一个配置项在make menuconfig中都会成为一个菜单项目。而且menuconfig中显示的菜单目录结构和源码目录中的Kconfig的目录结构是一样的。
  • 在相应的Kconfig文件中删除一个config项,则再次make menuconfig时这个项目已经看不到了。
menuconfig读取/写入.config文件
  • 刚才已经知道menuconfig的菜单内容来自于Kconfig文件,但是每一个菜单的选择结果(Y、N、M)却不是保存在Kconfig文件中的。Kconfig文件是不变的,Kconfig文件只是决定有没有这个菜单项,并不管这个菜单项的选择结果。
  • menuconfig工作时在我们make menuconfig打开时,他会读取.config文件,并且用.config文件中的配置选择结果来初始化menuconfig中各个菜单项的选择值。
  • 总结:菜单项的项目内容从 Kconfig 文件来,菜单项的选择值从 .config 文件来
  • 当我们每次退出make menuconfig时,menuconfig机制会首先检查我们有没有更改某些配置项的值,如果我们本次没有更改过任意一个配置项目的值那直接退出;如果我们有改动配置项的值则会提示我们是否保存。此时如果点保存,则会将我们更改过的配置重新写入.config文件中记录,下一次再次打开make menuconfig时会再次加载.config,最终去编译内核时编译连接程序会考虑.config中的配置值指导整个编译连接过程。
  • 总结:本次主要内容就是讲:menuconfig和Kconfig和.config的关系。

7.Kconfig文件详解1

Kconfig的格式
  • Kconfig按照一定的格式来书写,menuconfig程序可以识别这种格式,然后从中提取出有效信息组成menuconfig中的菜单项。
  • 将来在做驱动移植等工作时,有时需要自己添加Kconfig中的一个配置项来将某个设备驱动添加到内核的配置项目中,这时候就需要对Kconfig的配置项格式有所了解,否则就不会添加。
  • #开头的行是注释行
  • menuconfig表示菜单(本身属于一个菜单中的项目,但是他又有子菜单项目)、.config表示菜单中的一个配置项(本身并没有子菜单下的项目)。

  • menuconfig或者config后面空格隔开的大写字母表示的类似于 NETDEVICES 的就是这个配置项的配置项名字,这个字符串前面添加CONFIG_后就构成了.config中的配置项名字。
  • 一个menuconfig后面跟着的所有config项就是这个menuconfig的子菜单。这就是Kconfig中表示的目录关系。
  • 内核源码目录树中每一个Kconfig都会source引入其所有子目录下的Kconfig,从而保证了所有的Kconfig项目都被包含进menuconfig中。这个也告诉我们:如果你自己在linux内核中添加了一个文件夹,一定要在这个文件夹下创建一个Kconfig文件,然后在这个文件夹的上一层目录的Kconfig中source引入这个文件夹下的Kconfig文件。
tristate和bool的含义
  • tristate 意思是三态 < >(3种状态,对应Y、N、M三种选择方式),bool 是要么真要么假 [ ](对应Y和N)。所以tristate的意思就是这个配置项可以被三种选择,bool的意思是这个配置项只能被2种选择。

8.Kconfig文件详解2

depends的含义
  • depends中文意思是“取决于”或者“依赖于”,所以depends在这里的意思是:本配置项依赖于另一个配置项。依赖的配置项为Y或者M,则本配置项才有意义;如果依赖的哪个配置项本身被设置为N,则本配置项根本没有意义。
  • depends项目会导致make menuconfig的时候找不到一些配置项。所以你在menuconfig中如果找不到一个选项,但是这个选项在Kconfig中却是有的,则可能的原因就是这个配置项依赖的一个配置项是不成立的。
  • depends并不要求依赖的配置项一定是一个,可以是多个,而且还可以有逻辑运算。这种时候只要依赖项目运算式子的裸机结果为真则依赖就成立。
help
  • 帮助信息,告诉我们这个配置项的含义,以及如何去配置他。

9.Kconfig和.config文件和Makefile三者的关联

  • 配置项XXX被配置成Y、N、M会影响.config文件中的CONFIG_XXX变量的配置值。
  • 这个.config中的配置值(=y、=m、没有)会影响最终的编译链接过程。如果=y则会被编入(built-in),如果=m会被单独连接成一个ko模块,如果没有则对应的代码不会被编译。那么这么是怎么实现的?都是通过makefile实现的。
  • obj-$(CONFIG_DM9000) += dm9000.o
  • 如果CONFIG_DM9000变量值为y,则obj += dm9000.o,因此dm9000.c会被编译;如果CONFIG_DM9000变量未定义,则dm9000.c不会被编译。如果CONFIG_DM9000变量的值为m则会被连接成ko模块(这个是在linux内核的Makefile中定义的规则)
  • 总结:把menuconfig中的菜单项、Kconfig中的配置项、.config中的一行、 Makefile中的一行,这4个东西结合起来理解,则整个linux内核的配置体系就明了了。
  • menuconfig中的菜单项取决于Kconfig中配置项,我们在配置Kconfig后,会更改.config 中变量的值,在编译的时候,Makefile会根据变量的值来决定哪些文件被编译。

10.menuconfig的实验学习思路

验证menuconfig和.config的关系
  • make menuconfig时,会读取.config中的配置值来初始化menuconfig中的配置项。
  • 验证:如果理论正确的,那么我自己手工修改了.config的配置后,再次make menuconfig时看到的初始值就应该是我手工修改的。
  • menuconfig中修改了(按Y、N、M)配置项的值,然后退出时保存,则这个保存结果会修改.config文件中的相应行。
  • 验证:如果结论是正确的,那么在menucofig中修改了配置后保存退出,再次去手工打开.config文件则可以看到相应配置的一行内容被修改了。
验证menuconfig和Kconfig的关系
  • menuconfig读取Kconfig的内容作为菜单项目内容。
  • 验证1:在Kconfig中删除一个config项,则再次make menuconfig时就看不到这个项目了。(上课时已经验证过了)
  • 验证2:在Kconfig中自己添加创建一个config项,则再次make menuconfig时就能看到多了一个项目。
验证验证menuconfig和Makefile的关系
  • 我找一个模块,把他配制成y,然后去make编译连接,最后得到的zImage中这个模块就应该被编译连接进去到zImage中了。
  • 验证:
  • 方法一:去这个模块对应的源代码目录看一下这个源码有没有被编译
  • 方法二:去zImage对应的elf格式的vmlinux中查看符号
  • 方法三:将vmlinux反编译(objdump)后得到的文件中找模块对应的符号
  • 方法四:将zImage下载到开发板中启动,启动后看你的模块能不能工作

转载于:https://www.cnblogs.com/icefree/p/8542138.html

2、内核的配置和移植相关推荐

  1. 十六.linux开发之Kernel移植——内核的配置和编译原理

    有道云笔记地址: 详情看这里链接,记录太多,就不一一排版了. http://note.youdao.com/noteshare?id=d25dbce79566963e3699574a74048154& ...

  2. 移植基于linux-2.6.26.5内核s3c2410触摸屏驱动移植

    移植基于linux-2.6.26.5内核s3c2410触摸屏驱动移植的过程记录下来: (1)首先打一个补丁:s3c2410_touchscreen.patch, 在内核解压的根目录下 patch -N ...

  3. Linux内核的配置和编译

    文章目录 前言 1.内核介绍 2.linux内核源码目录结构 3.内核配置和编译实验 4.内核的配置原理 5.menuconfig 6.Kconfig文件详解 7.menuconfig的实验 前言 以 ...

  4. 万字长文---手把手教你加固内核安全配置

    ​更多内核安全.eBPF分析和实践文章,请关注博客和公众号: CSDN博客:内核功守道 公众号: 内核功守道 知识背景 正如Linus Torvalds曾经说过的,大多数安全问题都是bug造成的,而b ...

  5. 基于ARM的嵌入式linux 内核的裁剪与移植

    0 引言     微处理器的产生为价格低廉.结构小巧的CPU和外设的连 接提供了稳定可靠的硬件架构,这样,限制嵌入式系统发展的瓶颈就突出表现在了软件方面.尽管从八十年代末开始,已经陆续出现了一些嵌入式 ...

  6. Linux内核的配置和编译原理

    目录 一.linux内核源码目录结构 二.内核配置和编译体验 三.内核的配置原理 四.menuconfig的使用和演示 五.menuconfig的工作原理 六.Kconfig文件详解 七.menuco ...

  7. 1. Linux内核的配置与裁减:

    一.内核的配置和编译流程: 1)编写driver及其子目录下的Kconfig文件,将驱动的配置项写入menuconfig配置界面: 2)  执行make menuconfig命令,进入内核配置界面,将 ...

  8. linux安装oracle 操作系统内核参数 aio,Oracle Study之案例--安装Oracle内核参数配置

    Oracle Study之案例--安装Oracle内核参数配置 在Linux系统下,安装Oracle之前,除了检查操作系统的硬件和软件是否满足安装需要之外,一个重点就是修改内核参数,其中最主要的是和内 ...

  9. 2.6内核的配置与编译

    首先对内核进行菜单配置, 代码: CODE: cd /usr/src/linux make menuconfig 代码成熟度选项, 代码: CODE: Code maturity level opti ...

最新文章

  1. umi脚手架搭建的项目_15天零成本搭建静态博客,托管于Github Page
  2. ASP.NET Core 认证与授权[2]:Cookie认证
  3. 【商城购物车】购物车逻辑
  4. HDU 2544 最短路(各种最短路算法的实现)
  5. inux中限制用户进程CPU和内存占用率
  6. 使用LXCFS实现容器资源的视图隔离
  7. php里面优先级最高的是,数据结构-PHP 优先级队列(最大堆)的实现
  8. codevs 3981 动态最大子段和
  9. locky勒索样本分析
  10. Django基础--4
  11. 离开,是一个新的开始
  12. linux 内核与分析 -- 内存管理(下)
  13. DOS简介及常用命令
  14. html5闪光效果,HTML5 canvas元素背景梦幻小星星闪烁特效
  15. 一回生,二回熟,三回巧
  16. LaTeX tabular实现垂直居中
  17. java任意长度获取随机数
  18. JSP网站开发技术两种模式介绍
  19. c语言课程设计之桌面日历(完整源码+注释)
  20. 想考数据库工程师?你需要了解这些

热门文章

  1. 声音分析软件公司Cogito完成1500万美元B轮融资
  2. 【OpenCV归纳】4 关于HighGUI
  3. 无线安全入门、芯片选型、扫描器使用
  4. 在apache访问日志中统计统计前十名pv
  5. 工作多年的.NET程序员,是否建立了自己的开发知识库?分享制作电子书的经验...
  6. python学习笔记——类
  7. c++面试准备之螺旋队列
  8. 促进儿童语言发展的方法
  9. 2007注册会计师考试
  10. Go 语言:我那么值钱,我骄傲了吗?