搭建Linux内核学习平台

嵌入式80%的技能都可以脱离开发板学习,包括Linux命令、系统编程、C语言编程、U-boot、kernel内核源码研究及开发,这些知识和技能都是嵌入式开发所需要的通用技能,跟具体的硬件关联不大,因此我们可以放到主机上学习:使用VMware+Ubuntu+qemu,就可以在自己的电脑上搭建一个仿真的嵌入式开发平台:仿真一块ARM开发板,在上面移植U-boot、kernel,并挂载NFS文件系统。在这个仿真的平台上,可以学习u-boot 、Linux内核、研究文件系统、应用程序开发等多个学习项目。使用虚拟的开发板平台学习内核的好处有:

  • 省去硬件的各种干扰,专注软件的业务逻辑
  • 研究U-boot、内核的理想平台
  • 可以更换最新的内核、使用方便
  • 本课程拟使用内核:Linux-5.10

小宅实验室

为了帮助大家省去搭建环境的烦恼,本课程基于Ubuntu-20.04,使用qemu-5.x,在虚拟机上搭建了一个学习嵌入式、内核开发的理想学习环境,制作好的虚拟机镜像已经分享到网盘,不需要任何配置,用户下载后使用VMware打开即可使用。

百度网盘:https://pan.baidu.com/s/1qaRT9A1Pj2o5U-fxg1Qojg 提取码: wjns
微云:https://share.weiyun.com/IQjOE4bi 密码:ynm2nr
若下载地址失效,请关注公众号:宅学部落;进入公众号,输入:小宅实验室,即可获取最新镜像下载地址。

在这个平台上如何编译和运行自己的u-boot、kernel,可以参考qemu教程:小宅实验室:Ubuntu-20.04使用手册

内核版本的选择

在Linux内核的官方网站上可以看到,Linux内核有各种不同的版本:

那我们学习内核驱动开发,到底该选择什么版本呢?在选择版本之前,首先我们需要了解内核的各个版本有什么不同。

  • mainline:Linux内核的主线版本,由 Linus 维护,每2~3月发布一次新版本
  • RC1~RC5:待发布(pre-release)内核,添加了新的功能,在进入stable版本前需要测试、bug fix
  • stable :每周发布一次,bugfix backporting
  • Linux-next:CI 提前bugfix测试,由 Stephen Rothwell 维护
  • LTS:Long Time Service,5年的维护周期

Linux内核版本每天都在发生变化,每个stable稳定版本基本上每周也会发布一次。对于从事手机、平板、智能音箱、汽车电子等开发的公司来说,一个产品开发周期可能半年甚至一年以上,需要系统移植、功能开发、产品测试、认证等严格流程,内核每更新一次,就要把最新的内核重新移植到自己的产品硬件平台上显然是不现实的。

Linux内核一般会有一些长期服务版本,也就是LTS版本,挑选几个稳定版本,提供长达5年的服务维护周期,后续会不断地打补丁。更多的嵌入式开发公司更喜欢使用这种LTS版本的内核来开发自己的产品。目前Linux内核社区维护着5个LTS版本的内核,这5个版本都是由Greg Kroah-Hartman & Sasha Levin维护的。

Linux内核除了LTS版本,还有SLTS(Super Long Time Service)版本,SLTS版本的内核可以提供长达10~20年的服务维护周期,主要是由几家从事汽车、工业控制行业的公司维护的。这些行业对Linux内核的需求不是追求最新的功能,而是稳定的性能。

而对于从事互联网、云计算的公司来说,使用内核的最新特性(虚拟化、云、容器、namespace、cgroup、DPDK)可以更加满足自己对云计算、互联网新业务的技术需求。而且由于Intel公司对内核开发的大力投入,Linux最新内核对X86平台的支持也是最完善的。

Android kernel

随着Android在手机、平板等移动设备领域的流行,Android下的kernel开发也有一个很大的需求。Android内核使用的是Linux kernel,但对kernel做了很多修改,以Android-4.4.y为例,对Linux-4.4做了很多修改:

  • 新增代码32266行,删除1546行,替换255行
  • 19.8% Energy Aware Scheduling (kernel/sched)
  • 13.8% 网络 (net/netfilter)
  • 13.5% Sdcardfs (fs/sdcardfs)
  • 9.4% USB (drivers/usb)
  • 7.2% SoC (arch/arm64, arch/x86)
  • 6.1% 输入 (drivers/input/misc)
  • 5.4% FIQ 调试 (drivers/staging/android/fiq_debugger)
  • 3.6% Goldfish 模拟器 (drivers/platform/goldfish)
  • 3.4% Verity (drivers/md)
  • 11.6% 其他

Android操作系统对内核kernel做了很多修改,使得Linux内核更适合在手机、平板等移动设备上运行,但也使得Android kernel和官方的kernel主线版本不兼容,Android添加的这些修改也无法提交到内核社区。很多嵌入式产品开发,不是从Linux内核官方社区下载内核源码,而是从AOSP(Android open source project)下载内核源码。

Android下的内核驱动开发,跟原生态下的Linux内核开发差别不大,但也有一定的差异:比如驱动开发,在Android上一般还会有一个硬件抽象层(Hardware Abstraction Layer,简称HAL),HAL介于内核驱动和framework层之间,使得Android更加容易在不同处理器、不同厂家的硬件平台上运行。

Android对内核通过一系列改造,虽然更加适合在移动设备上运行,更加兼容不同厂家的CPU和硬件平台,但带来的问题是:Android越来越碎片化,不同的版本,不同的厂家,都需要分别适配,无疑增加了开发的工作量。

目前Android也在尽力解决这个问题:比如使用Android通用内核,将Android版本androi-x.y直接与LTS版本的内核linux-x.y对应,将LTS版本的内核patch定期合并,通过内核模块化设计,将芯片外设、板属组件和Linux通用内核分离。通过提供给各大手机厂商一个剥离了硬件和板属组件的通用内核,各大手机厂商就可以基于这个通用内核开发驱动,这样做的好处,以后跟具体的硬件平台无关的Linux通用内核以后可以直接通过Android官方升级,不再经过芯片原厂、设备制造商等环节。

驱动开发核心理论,Linux内核开发入门实战视频教程:《Linux内核编程》,具有一线芯片原厂开发经验的驱动工程师录制,详情点击:王利涛老师个人淘宝店:Linux内核编程