内核的编译和配置

注: 文章内容主要参考朱有鹏linux嵌入式课程

1.linux内核源码目录结构

源码哪里来

(1)使用2.6.35.7版本内核。该版本内核有三种:kernel.org上的官方版本,三星移植版,九鼎X210移植版。

分析时用X210版, 实验时用三星版;

(2)光盘F:\BaiduNetdiskDownload\2.X210V3S_A\BSP X210官方\QT4.8\bsp\qt_x210v3s_160307.tar.bz2

, 这个九鼎移植好的整个系统, 里面包括kernel, uboot, buildroot等;

(3)把上面的kernel/单独取出分析,是九鼎针对X210移植的内核。

 

文件和文件夹

COPYING

版权说明, 反正kernel是GPL, 开源的, 自己基于这版改造出来的也要开源;(不开源的话只提供 .o文件)

Kbuild

kernel build内核编译, linux内核特有内核编译体系文件;很多目录下有Kconfig与之对应

Makefile

整个内核工程用的Makefile;

mk

九鼎移植时添加, 来整体管理kernel的配置和编译,类似我们的make.sh。

arch

放不同架构的CPU目录,是linux在不同架构下运行的适配代码;

block

放一些linux存储体系中块设备的逻辑管理代码。

块设备(以块为单位访问),如SD卡、iNand、Nand、硬盘等;

crypto

放一些常见的加密算法的C语言代码实现。如crc32、md5、sha1等。

Documentation

放一些文档;

drivers

驱动目录,分类别列出内核支持的所有硬件设备的驱动代码。

firmware

固件。

固件其实是软件,不过软件是固化到IC里运行。像S5PV210的iROM代码。

fs

文件系统,放linux支持的各种文件系统实现。

include

各种架构共用的头文件。而CPU特有的头文件, 如arm在arch/arm/include目录及其子目录。

(位置变了编译时可能报找不到文件, 如老版本的公用include没有放一起)

init

放内核启动初始化的代码。

ipc

inter process commuication进程间通信,放linux支持的IPC实现。

kernel

放内核本身的代码文件。

lib

公用的库函数;

(C语言库函数是应用层的, 调用操作系统实现的, 在内核编程中不能用,这里的lib库用来替代标准库函数)。如字符串转数字: atoi,内核编程中用lib目录下的atoi函数,不能用标准C库的atoi。

如打印信息时不用printf,用lib目录下的printk。

mm

内存管理代码。

net

网络相关的代码,如TCP/IP协议栈等。

scripts

脚本文件,用来辅助我们对linux内核进行Kbuild的配置编译。不深入;

security

安全相关代码。不用管;

sound

音频处理相关;

tools

linux中用到的有用工具;

usr

initramfs相关,和内核启动有关,不用管, 做系统的才搞。

virt

内核虚拟机,暂时不用管。

总结:

关系紧密的只有arch和drivers目录,其他有点相关的有include、block、mm、net、lib等目录。

 

linux内核的配置体系

(1)模块很多,可配置性高, 需要一套机制保证内核可被正确配置。(uboot配置相比起来很简单,配置项都在xxx.h)

(2)配置项上千个,光靠人根本不可能,所以发明一种体系帮助人进行简单化配置。

 

 

 

2.内核配置和编译体验

内核编译

(0)安全起见先make distclean;

(1)先确认Makefile交叉编译工具链设置:

L193 CROSS_COMPILE   ?= /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi-

L191 ARCH = arm //为了编译时能找到arch/arm目录。

(2)配置: make x210ii_qt_defconfig, 最后只要出现configuration written to .config则正确。

可能错误:名字敲错。

配置后ls -a如果没有.config文件,不能进行下一步。虽然没有.config能编译,编译和烧写运行应该是有问题的。

(3)图形配置: make menuconfig, 因为九鼎移植配置过,出了图形界面直接exit

错误1:Unable to find the ncurses libraries ,  则apt-get install libncurses5-dev (文字式图形界面)

可能错误2:Your display is too small to run Menuconfig!  It must be at least 19 lines by 80 columns.

终端屏幕太小, 则全屏terminal,或者把字体调小。

(4)编译: make, 编译出zImage, 在arch/arm/boot这个目录下;

可能错误1:莫名其妙的错误,试试先make distclean

错误2: omit the defined()?) at kernel/timeconst.pl

            打开内核所在目录下的/kernel/timeconst.pl ,在line 373行将 if(!defined(@val)) 替换成 if(!@val)

 

内核烧写测试

(1)开发板用网卡能ping通开发板(ubuntu选桥接到物理网卡)

(2)cp zImage /tftpboot/ -f ,

然后在开发板uboot:setenv serverip 192.168.0.106, saveenv保存tftp 30008000 zImage下载到内存;

然后bootm 30008000启动内核;

(3)结果: 启动成功, 但是lcd是花屏; (用QT4.8的uboot启动的)

 

.config文件

(0)配置的关键是生成.config文件;  

(1)作用: 类似uboot的include/configs/x210_sd.h,编译过程会读取其中的配置项,拿去指导整个编译链接过程)

(2)内容:大部分是CONFIG_xxx=y的格式, 实质是定义变量, 并赋值为y。

有两千多个这种配置项, 很难全部搞明白。超出人能记忆和处理的数量级,因此发明了两步配置的机制, 图形化配置工具menuconfig。 //你也可以vim 手工生成, 但工作量太大了

 

3.配置和编译解析

两步配置的机制

(1)目的: 为了对.config做逐一合适的配置;

(2)make xxx_defconfig: 配置大部分配置项(99%);

make x210ii_qt_defconfig相当于cp arch/arm/configs/x210ii_qt_defconfig .config //复制fefault配置到当前

//这些文件是别人针对开发板配置好的, 如用S5PV210这SoC,肯定选三星的工程师做过的板子.config。(下他的内核)

(3)make menuconfig: 针对开发板进行细节调整, 读取.config文件,并启动图形化界面, 根据目录来找到修改的配置项;

(4)优点:

如果Soc相近, 第一步能够参考别人做好的配置,减少很多工作量,避开不懂的配置项(如内存管理、调度系统等模块配置项),只用管自己需要管的。

 

menuconfig的使用

(0)自带提示, 有所有的用法。

(1)按键说明: 还有特殊字符按键,如/  ?

上/下箭头

目录浏览时上下翻

左/右箭,

菜单选项(select、exit、help)间切换。

回车

选中并且执行select/exit/help。

ESC

返回上一层

(2)UI说明:

选项后面有 --->

表示有子菜单;

选项第一个字母高亮

表示可以键盘输入该字母快速选择;

Y、N、M按键

选中模块编入、去除、模块化(编译不链接, 单独生成 .ko文件, 内核启动后可动态加载)。

选项前的 < * >表示编入,  <  >表示去除, <M >表示模块化, []不可以模块化。

双击ESC/光标执行exit

退出, 光标返回上一层;

?按键

显示模块的帮助信息;

/按键

弹出搜索框全局搜索,[]不可以模块化,<>的才可以模块化。

 

menuconfig工作原理

(0)menuconfig由一套软件支持, linux内核中使用了ncurses库提供menuconfig;

(1)代码定位: scripts\kconfig\lxdialog\下, make menuconfig首先编译该脚本。

(2)读取Kconfig:

1)本身只负责menuconfig工作逻辑, 菜单项目由内核源码树各目录下的Kconfig文件支持, 菜单目录结构和Kconfig目录结构一样。(名字可能不同)

如Device Drivers-> Network device support-> Ethernet(10 or 100Mbit) 对应

~\kernel\drivers\net\下的Kconfig

 

3)验证: 相应Kconfig文件中删除一个配置项,再make menuconfig后对应config项消失。

(3)读取/写入.config:

根据.config文件的配置, 作为menuconfig各个菜单项的启动值, 修改配置后退出, 会检查是否写入.config。

总结:菜单项的项目内容从Kconfig文件来,菜单项的选择值从.config文件来

 

Kconfig的格式

(0)Kconfig按menuconfig可识别的格式写的, 做驱动移植时,有时需要添加某个设备驱动配置项添加到内核的配置项目中,要自己写Kconfig。

(1)编写格式:

1)menuconfig xxx(目录菜单项) 和

config xxx(配置项)

分成很多小单元。//能够对应.config中的config_xxx

2)depends on xxx       

依赖于另一个配置项是否选中编译, 否则不显示;

如不勾DM9000, 下面的配置项立马消失;

运算可以用 或||  非! 与&&

3) bool/tristate xxx     

二态(Y和N)/三态(Y、N、M三种选择)+ 菜单项提示符xxx;

4)---help---                

表示按?时的帮助信息, 包含:

手写的: 配置项含义

自动生成的: 当前值/提示符/Kconfig路径及第几行/菜单中的路径/依赖项.. ;

5)遇到第二个menuconfig xxx表示子菜单

下跟一个if xxx, 表示if后面的是子菜单的配置项;

6)source "xxx/xxx.."     

每个父目录都会引入子Kconfig, 保证了所有的Kconfig项目都被包含;

如果自己编写Kconfig文件,要在上层目录的Kconfig中source引入。

7)select xxx

当选中了当前配置项, 会自动选中某配置项

8)default

配置项默认值, 某些配置项不是=y,= =m, 如DM9000_16BIT的default是n, 表示不是16位;

注意:

depends项目会导致菜单中找不到配置项, 可能是依赖的配置项不成立的。

 

Kconfig / menuconfig / .config / Makefile 的关联

(1)配置项被配置成Y、N、M会影响.config文件中的CONFIG_xxx变量, =y则编入(built-in), 没有则不编译,=m单独编译成ko模块。是通过makefile实现的。如

obj-$(CONFIG_DM9000) += dm9000.o //CONFIG_DM9000变量值为y,则obj += dm9000.o,dm9000.c能编译, =m编译成ko模块, 是Makefile的规则;

(2)总结:Kconfig影响menuconfig, menuconfig/手工配置影响.config, .config影响Makefile

(3)验证:

1)menuconfig和.config的关系:

思路: make menuconfig时,读取.config作为menuconfig默认配置值。

方法: menuconfig中修改了(按Y、N、M)配置项的值,退出时保存,结果会修改.config相应行。

2)menuconfig和Kconfig的关系:

思路: menuconfig读取Kconfig作为菜单项内容。

方法: Kconfig中删除/添加config项,再次make menuconfig时看不到/新增这个项目。

3)menuconfig和Makefile的关系

思路: 找个配置项,选中配制成y,make编译连接后, zImage中包含该模块。

方法:

一:去模块源码目录看有没有被编译成.o //没有搞统一的obj目录

二:打开zImage对应的vmlinux, 二进制中可能存在dm9000的符号, 或者打开System.map(符号链接地址表);

三:将vmlinux反编译([命令目录/] objdump -D vmlinux >vmlinux.txt 嗨大800多M),在vim中 :/dm9000

四:zImage下载到开发板启动,看模块能不能工作

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值