树莓派支持多种操作系统,其中以Linux操作系统最为典型。Android操作系统同样也基于Linux内核。本系统的构建从移植Linux内核开始。
Linux通用内核维护网址是https://www.kernel.org。树莓派内核源码托管在https://www.github.com/raspberrypi/linux,它是通用的Linux内核的一个分支。从树莓派专门维护的网站获取的源码更新更快,针对树莓派的支持更加明确。可以用下面的命令将整个内核项目克隆到本机:
$ git clone https://www.github.com/raspberrypi/linux
然后检测出中意的版本:
$ cd linux $ git checkout rpi-5.4.y
克隆项目的优点是不仅可以随意在不同版本之间进行切换,而且当上游代码更新时,本地只要git pull命令就可以将源码与上游代码同步,pull的下载量很小;克隆项目的缺点是由于代码仓库记录了全部的开发过程,首次克隆整个仓库的代码量太大。如果只需要在某个特定的版本上编译,可以使用github的网页下载功能(见图1.8),仅下载某个版本的压缩包,然后在本地解压。
图1.8 github的内核源码下载页面
Arm64的默认配置文件在arch/arm64/configs/目录下,针对树莓派4B预制的配置文件是bcm2711_defconfig,如果是移植树莓派3,可使用文件bcmrpi3_defconfig作为配置的起点。在内核源码主目录下执行下面的命令,可以将预制的配置复制到.config文件:
$ ARCH=arm64 make bcm2711_defconfig
以后即以此为起点开始配置内核的选项。配置内核的过程实际上就是编辑.config文件。由于很多选项已在预制的配置文件中预先设好,从这个起点开始,可以大大简化后面的配置工作。
接着,打开配置界面:
$ ARCH=arm64 make menuconfig
make menuconfig将打开一个配置菜单界面。菜单中的每一项,有“y”“m”“n”三种选择,分别对应“将该功能编入内核”“编译成模块”“不编译该功能”,在菜单项前面分别用“*”“M”“空”作为标记。操作时将光标移动到对应的菜单项,用键盘按键“y”“m”“n”对该选项进行操作。选择编入内核时,该功能成为内核的一部分,内核启动后,该功能始终存在;如果选择编译成模块,则会在后面的编译中生成独立的模块(或驱动),可动态地加载或卸载;不编译该功能,意味着内核无此功能。图1.9是其中一个配置界面。
图1.9 内核配置界面
在有Qt或GTK+图形库支持时,还可以使用make xconfig或make gconfig方式使用图形化界面配置内核。图1.10是xconfig配置界面。
为了系统精简,运行便利,下面是一些针对树莓派4B的取舍。
图1.10 使用make xconfig打开的内核配置界面
(1)在General setup菜单下,将Initial RAM filesystem and RAM disk support编入内核,并选择下面的一种压缩格式,用于支持初始化RAM文件系统或RAMDisk;选择的压缩格式是后面制作RAMDisk使用的压缩命令的依据。
(2)在Platform selection菜单下,保留Broadcom BCM2835 family,其余选项均可去掉。
(3)在Device Drivers菜单下,选中Maintain a devtmpfs filesystem及其子菜单Automount devtmpfs at/dev。此功能支持在系统启动时自动创建设备文件。
(4)在Device Drivers→Block devices菜单下,将RAM block device support编入内核,RAMDisk需要这个选项支持。
(5)在Device Drivers→Network device support→Ethernet driver support菜单下,保留Broadcom GENET internal MAC support,这是树莓派4B的有线网卡支持项;其他型号的树莓派网卡有所不同,2B和3B系列的网卡在USB Network Adapters项目下,型号是SMSC LAN75XX/LAN95XX。不同型号的板卡,应根据网卡具体型号进行取舍。多余的选项通常不会导致错误,但不符合精简原则。无线网卡在Wireless LAN子菜单下,选择Broadcom FullMAC WLAN driver。
(6)选择Device Drivers→Character devices中的Unix98 PTY support。树莓派作为TELNET和SSH服务时,需要这个选项提供终端支持;选择Serial drivers中的ARM AMBA PL011 serial port support,串口调试器需要通过树莓派的这个功能支持。
(7)在Device Drivers→Graphics support→Frame buffer devices菜单下,选中BCM2708 framebuffer support,以实现图形接口支持。
(8)在Device Drivers→Graphics support菜单下,注意Broadcom V3D 3.x and newer和Broadcom VC4 Graphics选项,前者是树莓派4代的GPU支持,后者是树莓派系列3代之前的GPU支持。可以将它编译成模块,也可编译进内核。如果编译成模块,还需要在系统启动后加载模块,否则图形方式只能通过Frame buffer支持。
(9)选中Device Drivers→Staging drivers→Broadcom VideoCore support菜单下的模块,这是内核与GPU的接口,音频和视频的很多功能通过它完成。
(10)在Device Drivers→Sound card support→Advanced Linux Sound Architecture菜单下,选中SoC Audio support for the Broadcom BCM2835 I2S module。此选项用于支持耳机接口的音频输出。
(11)将File systems下的The Extended 4(ext4)filesystem编入内核,其他文件系统视需求而定,可编译成模块,也可编译进内核,甚至可以去除。
以上选项只考虑树莓派本身,不考虑其他外接设备。缺省配置中包含了大量的模块和外设。出于精简系统的目的,同时也是为了节省编译时间,可以考虑将这些用不到的设备移出内核。
完成配置修改后,保存并退出配置界面,配置文件.config会得到更新。注意备份这个文件,以便以后修改配置。下面的代码编译内核、模块,并将模块安装 到指定的目录:
“-j”是GNU Make的选项,表示多个线程同时工作,在多核处理器上可以大大加快编译速度。选取的数字与开发平台的处理器核数有关。处理器核的详细信息可以通过文件/proc/cpuinfo查看,也可以用命令nproc直接得到核数。后面编译软件的make命令都可以使用这个选项加快编译速度,不再专门写出。
make命令编译内核映像文件arch/arm64/boot/Image,所有在配置过程中被设定为模块的项目将通过make modules编译成模块.ko文件,这些.ko文件通过make modules_install集中复制到指定目录/home/devel/kmod/(需要保证用户对/home/devel/目录有写权限)。编译内核映像文件的同时也生成了二进制设备树文件,这些文件在arch/arm64/boot/dts/broadcom(dtb文件)和arch/arm/boot/dts/overlays(dtbo文件)目录中。
对以上文件的处理方法如下:
(1)内核映像文件Image复制到microSD卡的BOOT分区,重命名为kernel8.img,它对应config.txt文件中的kernel参数;
(2)将broadcom目录中针对硬件平台的设备树文件bcm2711-rpi-4-b.dtb复制到microSD卡的BOOT分区根目录;
(3)将overlays目录中的设备树文件(*.dtbo)复制到microSD卡BOOT分区的overlays子目录;
(4)将/home/devel/kmod/lib/modules目录下的内核模块目录复制到树莓派Ext4分区的/lib/modules目录。