linux内核编译和移植过程

一、linux内核的特点

1、linux内核是开源的,
作者:linus
git : 版本管理工具
源码由C语言和汇编实现
2、linux内核支持多种硬件架构平台
3、linux内核采用模块化方式编写,分层思想
4、linux内核使用C和汇编代码实现,
在内核中最好不要使用C++
5、linux内核具有很好的移植和裁剪特性
通过图形化界面的配置方式就可以完成裁剪

二、linux内核源码的获取

1、linux官方获取
https://mirrors.edge.kernel.org/pub/linux/kernel/
2. 芯片厂家获取
3. 开发板厂家获取
4. 公司主管获取

由于三星没有将S5p6818芯片硬件支持开源到linux内核官方
本次实验不使用linux内核官方的源码。

本次使用使用:kernel-3.4.39-ok.tar.bz2

三、linux内核的版本命名方式

主版本号.次版本号.修订版本号

主版本号:内核源码有较大的改动才会更新主版本号
次版本号:修订版本号用完升级次版本号
	偶数:稳定版
	奇数:测试版
修订版本号:内核代码只要有更新就会修改修订版本号

四、linux内核版本的选择

1、不选太新
2、不选太旧
3、选择稳定版本

五、linux内核的配置和编译

1、拷贝linux内核源码压缩包到ubuntu中
1)、拷贝内核源码到ubuntu目录中

2)、解压缩内核源码
tar -vxf kernel-3.4.39-ok.tar.xz

3)、进入内核源码目录
cd kernel-3.4.39

2、分析内核源码的目录结构
平台相关代码:代码跟硬件相关
arch
平台无关代码:代码跟硬件无关
drivers
lib
include
net
fs
kernel

3、配置和编译内核
Cleaning targets:

clean		 
mrproper	  
distclean	  

Configuration targets:

menuconfig	  - Update current config utilising a menu based program
modules	  - Build all modules
uImage        - U-Boot wrapped zImage
fs6818_defconfig         - Build for fs6818

“make ${PLATFORM}_defconfig”
Create a ./.config file by using the default

symbol values from
arch/$ARCH/configs/${PLATFORM}_defconfig.

Use “make help” to get a list of all available
platforms of your architecture.

4、linux内核的详细配置和编译过程
1)、修改Makefile文件,配置交叉编译工具链

195 ARCH        ?= 
196 CROSS_COMPILE   ?= 

修改为:

195 ARCH        ?= arm
196 CROSS_COMPILE   ?= arm-none-linux-gnueabi-

2)、清除内核的中间文件
make distclean (只在源码第一次编译时执行一次)

3)、 配置内核源码支持fs6818硬件平台
make fs6818_defconfig
(只在源码第一次编译时执行一次,
如果执行了make distclean之后,
需要重新执行make fs6818_defconfig)

4)、 通过图形化界面的方式对内核进行配置(裁剪)
make menuconfig

注意:make menuconfig
第一次使用make menuconfig 需要安装图形化界面的工具
配置之前需要安装图形图(make meuconfig):
sudo apt-get install libncurses5-dev
sudo apt-get install lib32z1

注意 : 出现这个错误
scripts/kconfig/mconf Kconfig
Your display is too small to run Menuconfig!
It must be at least 19 lines by 80 columns.
make[1]: *** [menuconfig] Error 1
make: *** [menuconfig] Error 2
终端字体太大,缩小终端字体

5、编译内核
make uImage

注意:make uImage
在编译的过程中可能出现如下错误:
“mkimage” command not found - U-Boot images will not be built
make[1]: *** [arch/arm/boot/uImage] Error 1
make: *** [uImage] Error 2

错误的原因:找不到mkimage命令,
根据提示分析出来mkimage应该存在uboot源码目录中
uboot源码必须进行编译之后才会有mkimage可执行程序

解决问题的方法
将uboot源码的tools目录下的mkimage,
拷贝到到ubuntu的/usr/bin目录下:
sudo cp ~/uboot源码目录/tools/mkimage /usr/bin
再次make uImage重新编译内核即可。

打印以下信息表示编译成功:
Image Name:   Linux-3.4.39-farsight
Created:      Mon Jul 20 15:09:28 2020
Image Type:   ARM Linux Kernel Image (uncompressed)
Data Size:    5391608 Bytes = 5265.24 kB = 5.14 MB
Load Address: 40008000
Entry Point:  40008000
uImage内核镜像在一下目录中:
Image arch/arm/boot/uImage is ready	

六、分析make {platform}_defconfig过程详解。

1、打开linux内核源码顶层目录的Makefile文件,搜索“%config”

491 %config: scripts_basic outputmakefile FORCE
492     @mkdir -p include/linux include/config
493     @$(MAKE) $(build)=scripts/kconfig $@   
去掉命令前的@,重新执行make fs6818_defconfig
mkdir -p include/linux include/config
make -f scripts/Makefile.build obj=scripts/kconfig fs6818_defconfig
进入scripts/kconfig目录继续执行make fs6818_defconfig

2、打开scripts/kconfig 目录下的Makefile文件,搜索“defconfig”

95 %_defconfig: $(obj)/conf
96     $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
去掉命令前的@,重新执行make fs6818_defconfig
scripts/kconfig/conf --defconfig=arch/arm/configs/fs6818_defconfig Kconfig
使用file命令查看conf文件的属性:

作用:根据arch/arm/configs/fs6818_defconfig
	和内核源码顶层目录下的Kconfig文件,
	生成默认的.config配置文件

七、分析make menuconfig过程详解。

1、打开linux内核源码顶层目录的Makefile文件,搜索“%config”

491 %config: scripts_basic outputmakefile FORCE
492     @mkdir -p include/linux include/config
493     @$(MAKE) $(build)=scripts/kconfig $@   
去掉命令前的@,重新执行make menuconfig
mkdir -p include/linux include/config
make -f scripts/Makefile.build obj=scripts/kconfig menuconfig
进入scripts/kconfig目录继续执行make menuconfig

2、打开scripts/kconfig 目录下的Makefile文件,搜索“menuconfig”

//obj = scripts/kconfig
20 menuconfig: $(obj)/mconf                                        
21     $< $(Kconfig)

展开后

menuconfig: scripts/kconfig/mconf 
	scripts/kconfig/mconf Kconfig
mconf作用:根据Kconfig文件中的信息,生成图形化界面。
mconf中调用了图形化界面的库:ncurses

3、打开内核源码顶层目录的Kconfig

  5 mainmenu "Linux/$ARCH $KERNELVERSION Kernel Configuration"
  6 
  7 config SRCARCH
  8     string
  9     option env="SRCARCH"
 10 
 11 source "arch/$SRCARCH/Kconfig"
mainmenu: 主菜单 
语法格式:mainmenu "主菜单的名字"

source :引入下一级菜单
语法格式: source "下一级菜单的Kconfig的路径"

4、打开 arch/arm/目录下的Kconfig文件
menu…endmenu : 菜单
格式:
menu “菜单的名字”
菜单选项
source “下一级的菜单”
endmenu

256 config MMU
257     bool "MMU-based Paged Memory Management Support"
258     default y
259     help                                                          
260       Select if you want MMU-based virtualised addressing space
261       support by paged memory management. If unsure, say 'Y'.

bool : 菜单选项
语法格式: bool “菜单选项的名字”

default : 默认

help :帮助信息

分析.config的作用?
drivers/char/farsight/

.config :最终起决定作用将那些编译到内核中,
哪些驱动不编译到内核中
内核的工程的管理通过Makefile实现。。

打开drivers/char/farsight/Kconfig文件

  1 menu "FS6818 board device driver support" 
  3 config FS_ADC
  4     bool "adc driver for farsight FS6818 all platform"
  5     default y
  6     help
  7     different sensor select different channel
    .... 
	endmenu

打开drivers/char/farsight/Makefile文件

3 obj-$(CONFIG_FS_ADC) += adc_driver.o

如果CONFIG_FS_ADC = y 对应的驱动被编译到内核镜像中
如果CONFIG_FS_ADC变量为空 对应的驱动不被编译到内核镜像中

那么CONFIG_FS_ADC变量在哪里定义呢?
在.config文件中进行的定义。

重点:.config Kconfig Makefile三个文件之间的关系?
Makefile: 进行工程管理,配置和编译内核

.config : 存放的默认的配置信息
给Makefile文件使用,Makefile文件根据
CONFIG_**** = y ,对应的驱动被编译到uImage中
#CONFIG_**** is not set,对应的驱动不被编译到uImage中

make fs6818_defconfig时根据arch/arm/configs/fs6818_defconfig
和Kconfig文件生成.config文件
make menuconfig时,根据菜单选项的配置
.config会被修改
Kconfig:生成图形化界面的菜单选项的配置文件

大多数目录下都有一个Kconfig文件和Makefile文件。

linux内核编译和移植过程_第1张图片

七、模块化编译内核

模块化的方式编译内核驱动
bool : []
[*] : 驱动被编译到uImage内核镜像中
[ ] :驱动不被编译到uIamge内核镜像中

tristate :<> 三态
<*> : 驱动被编译到uImage内核镜像中
< > :驱动不被编译到uIamge内核镜像中
: 驱动采用模块化的方式进行编译

使用make modules命令编译驱动,
会将***.c的文件编译生成***.ko的驱动文件。

需要使用驱动时使用insmod命令将驱动加载到内核:

insmod ***.ko 

不需要使用驱动时使用rmmod命令将驱动从内核中卸载:

rmmod ***     # 卸载时只需要指定驱动的名字

使用lsmod命令可以查看动态加载的所有的驱动。

八、内核启动过程做了什么

1> uboot通过tftp命令将uImage下载到内存中
2> uImage需要完成自解压
3> 获取cpu的ID号,创建页表,
初始化MMU,完成物理地址到虚拟地址的映射
4> 清除BSS段
5> 完成绝大多数硬件的初始化,进一步对硬件初始化
内存,时钟,串口,EMMC,nfs客户端…
5> 从u-boot环境变量的内存分区获取bootargs参数,
根据bootargs参数,决定从哪里挂载根文件系统。
6> 挂载根文件系统,
7> 执行根文件系统中的1号进程,linuxrc程序
8> 到此开发板的linux系统启动成功

你可能感兴趣的:(ARM专栏)