Linux 的 Kernel 编译,并在其中添加驱动


  源码来源:各个arm官网下载,不同的CPU去对应的官网下载

  我们在做系统移植的过程中,从各个arm官网上下载的kernel源码一般都是只有一些常规的驱动的,很多时候需要我们添加一些新的其他IC的驱动,这里就简单说明一下。

0. 准备工作

  下载kernel源码,解压在自己的文件夹。

                                                             /*Linux内核源码目录分析*/ 路径 存放内容 /arch              不同CPU架构下的核心代码。其中的每一个子目录都代表Linux支持的CPU架构 ,比如arm,x86,MIPS,PPC等
/block             block目录下放的是一些linux存储体系中关于块设备管理的代码;譬如说SD卡、iNand、Nand、硬盘等都是块设备。你几乎可以认为块设备就是存储设备
/crypto            常见的加密算法的C语言实现代码,譬如crc32、md5、sha1等
/Documentation     说明文档,对每个目录的具体作用进行说明
/drivers           内核中所有设备的驱动程序,其中的每一个子目录对应一种设备驱动
/firmware          固件代码,固件其实是软件,不过这个软件是固话到IC里面运行的,所以叫固件
/fs                Linux支持的文件系统代码,及各种类型的文件的操作代码。每个子目录都代表Linux支持的一种文件系统类型
/include           头文件目录,公共的(各种CPU架构共用的)头文件都在这里。每种CPU架构特有的一些头文件在arch/arm/include目录及其子目录下
/init              init是初始化的意思,这个目录下的代码就是linux内核启动时初始化内核的代码
/ipc               内核中进程间的通信代码
/kernel            Linux核心功能源码,主要包括程序调度,控制进程,模块化等等
/lib               lib是库的意思,这里面都是一些公用的有用的库函数,注意这里的库函数和C语言的库函数不一样的。在内核编程中是不能用C语言标准库函数,
这里的lib目录下的库函数就是用来替代那些标准库函数的。
比如在内核中要把字符串转成数字用atoi,但是内核编程中只能用lib目录下的atoi函数,不能用标准C语言库中的atoi。
再比如在内核中要打印信息时不能用printf,而要用printk,这个printk就是我们这个lib目录下的 /mm 内存管理代码,譬如页式存储管理内存的分配和释放等 /net 网络通信相关代码 ,譬如TCP/IP协议栈等都在这里 /samples 内核编程的示例代码 /scripts 脚本,这个目录下全部是脚本文件,这些脚本文件不是linux内核工作时使用的,而是用来辅助对linux内核进行配置编译生成的,比如裁剪内核等等 /security 安全性相关的代码 /sound 音频设备的驱动程序 /tools Linux中的常用工具 /usr 内核启动相关的代码 /virt 内核虚拟机相关的代码 /Kbuild Kbuild是kernel build的意思,就是内核编译的意思。这个文件就是linux内核特有的内核编译体系需要用到的文件 /Makefile 这个是linux内核的总makefile,整个内核工程是用这个Makefile来管理的
/*注意,最后两个Kbuild和Makefile和上面提到的不一样,它们两个是文件,不是文件夹*/

  最后,还要补充两个重要的目录,这里以arm架构为例(注意,前提是内核源码经过了编译,才会在这些目录下生成这些文件):

    arch/arm/boot/ :Linux内核编译完成以后,在此目录下生成image,zImage镜像文件
    arch/arm/boot/dts:存放Linux内核所有设备树文件,包括dts编译后对应的.dtb文件

1. 配置Kernel编译环境

  主要就是配置交叉编译器。

  如果是 arm 的产品,就是  export ARCH=arm

  如果是 ARM64 的产品,就是 export ARCH=arm64

  其他的配置按常规交叉编译环境配置即可

2. 找到对应CPU的Kernel配置的配置

  这个文件夹里有一堆板载的配置文件,我们一般在这里选择跟我们CPU相近的来配置;如果在kernel官网下载的源码,里面可能不会有你这个CPU对应的配置文件,为此我们一般去各个厂家官网下载他们提供的源码,他们的源码里会有对应的配置文件。

  找到编译 Kernel需要的配置。如果是 ARM 架构的 CPU ,一般位置在 Kernel 目录下的:arch/arm/configs/

   

  如果是 ARM64, 一般配置的位置在kernel目录下的:arch/arm64/configs/

  

 

3. 加载配置

  像 Amlogic的 A311D 芯片,通过上步的路径找到他的配置 arch/arm64/configs/aplex_cmi_aa158_defconfig 注意:路径是:arch/arm64/configs/ ,管网下载的源码里该芯片的配置文件文件名并不是这个aplex_cmi_aa158_defconfig,这个文件名是我修改过的,初始文件名是 一般是板子CUP的命名加defconfig 

   

  接着加载配置的方法就是:make aplex_cmi_aa158_defconfig ARCH=arm64(ARCH=arm64是指定编译64位的,一般这个 ARCH=arm64 会放在 ~/.bashrc 里面,放在编译这里也行)。

  

  make aplex_cmi_aa158_defconfig ARCH=arm64,这个步骤就是把 arch/arm64/configs/aplex_cmi_aa158_defconfig 里面的配置写到了,Linux 代码目录下的   .config 文件里面;要执行这一步后,后面执行make编译kernel才会编译生成对应的dtb文件。

 

4. 打开 menuconfig

   执行 make menuconfig ARCH=arm64 (或者是32位平台的话,执行 make menuconfig ARCH=arm 根据你的平台来决定) ,把 menuconfig 操作就是把  .config 文件里面的配置读取出来,然后显示在一个可视化的界面里:

  

  如果没有执行  make aplex_cmi_aa158_defconfig ARCH=arm64 的话,那么执行  make  menuconfig  可能加载的就是 X86 架构的配置。在  make  menuconfig 里面,可以配置自己想要添加的驱动,Exit的时候要选择保存。

  如果你只是编译kernel还是要执行一次这个操作,不过只需要打开menuconfig再保存退出即可,不然后面编译容易报一些错误。

5. 保存配置

   如果是 ARM32 的CPU ,就在 Kernel 目录执行 make  savedefconfig  ARCH=arm

   如果是 ARM64 的CPU ,就在 Kernel目录执行 make  savedefconfig  ARCH=arm64

  

  执行完毕之后,会生成一个保存的配置文件为: defconfig

  

   再把 defconfig 文件配置覆盖先前的配置(步骤3加载的配置)。执行指令 cp  defconfig  arch/arm64/configs/aplex_cmi_aa158_defconfig -rf 这样,配置就保存下来了。

  

6. menuconfig 添加 HYM8653 RTC 驱动举例  

  如果你只是编译kernel的话,这步可以跳过。

  先加载原始的配置:make aplex_cmi_aa158_defconfig 在打开 make menuconfig 找到 RTC 的驱动。

  

  

   

  按 Enter是选择目录。按空格键 是切换是否选择, * 代表驱动加载到 Kernel里面去,M 代表编译成模块。空白表示不操作。退出之后保存。执行 make  savedefconfig 指令保存配置,再将保存好的 defconfig文件保存在arch/arm64/configs/  目录下的对应文件:执行指令 cp  defconfig  arch/arm64/configs/aplex_cmi_aa158_defconfig  -rf 进行保存,这样 make 编译的时候就会将 RTC HYM8563 的驱动编译进去。

7. 配置 HYM8653 RTC 驱动的设备树 dts

  如果你只是编译kernel的话,这步可以跳过。

  这一步步骤放在4、5、6步骤前后操作都可以,设备树文件一般的位置:

    像 ARM 的CPU ,一般的位置在  Kernel 的 arch/arm/boot/dts/ 目录下。

    像 ARM64 的CPU,一般的位置在 Kernel 的 arch/arm64/boot/dts/ 目录下。

  不同设备的设备树配置不同,需要看该设备挂载在哪个节点上,再在相对应的节点添加改驱动的设备节点信息,一些设备信息配置官网会给出相应的文档,一些没有的就需要自己去查,还有一些设备信息可以在Linux 源码目录 /Documentation/devicetree/bindings里查看。

  例如, 这里举例的例子的设备树就在 :arch/arm64/boot/dts/aplex/aplex文件夹是我自己添加的,一般官网下载的源码,设备树文件都保存到dts文件夹)目录下:

   

  关于设备树的说明可以参考我另一个文档:https://www.cnblogs.com/xingboy/p/14898899.html  

  例如 添加 RTC 的设备节点就在: arch/arm64/boot/dts/aplex/cmi_aa158.dts 如下位置:

  

8. 编译Kernel

  一般官网下载的Kernel的编译都有其写好对应的脚本,每个Kernel编译的方法都有一点点不同,如果系统全部是你自己制作的,编译一般是直接make,如果需要开多线程编译,可以执行 make -j** 指令(**是指你需要开启的线程数)。

  编译后会在arch/arm/boot文件夹生成一个zImage文件,还会在arch/arm/boot/dts文件夹生成一个 ***.dtb 文件(***是你编译的内核名,跟前面编译配置文件时配置文件前的***一致,修改该文件夹里的Makefile文件可以添加编译的dtb文件) ,这两个文件后续做系统镜像需要用到。

  编译后的烧录镜像制作可以参考我另一个博客文章:https://www.cnblogs.com/xingboy/p/14858853.html

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM