Raspberry Pi 内核编译

时间:2024-04-02 10:34:51

本例使用(Raspberry Pi Zero-w)

一、树莓派系统安装

1.1 准备工作

(1)硬件准备:Raspberry Pi Zero W(以下简称RPI),RPI电源线,SD卡,SD卡读卡器,笔记本电脑,无线路由器(电脑和RPI处于同一wifi网络下即可)。

(2)软件准备:Raspbrain系统镜像文件,SDFormatter,Win32diskim,PuTTY。

1.2 步骤

(1)从官网(https://www.raspberrypi.org/downloads/raspbian/)下载Raspbrain系统,解压得到镜像文件。

(2)将SD卡插入读卡器然后接入电脑,用SDFormatter格式化SD卡/或使用linux mkfs.vfat命令也可。

(3)用Win32diskim软件烧系统。

         镜像处选择你刚才下好的系统镜像,设备处选择你的SD卡,点击"写",写完后会显示成功。

(4)配置wifi文件和SSH。

         ▲在SD卡中新建文件,命名为wpa_supplicant.conf,输入如下内容并保存:

country=CN
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
ssid="xxxxxxx"
psk="xxxxxxxx"
key_mgmt=WPA-PSK
priority=1
}

          其中的ssid为指定树莓派要连接的wifi名称,psk为密码,key_mgmt为加密方式。

       ▲在SD卡中新建文件夹,命名为ssh,内容为空。

(5)将SD卡插入RPI,连接电源线。

打开电脑浏览器,登录无线路由器默认终端配置地址(路由器标签上注明,本例中是“192.168.0.1”),找到RPI的IP(本例中是“192.168.0.106”)。

用电脑打开PuTTY,选择“SSH”,IP地址处填入RPI的IP。

第一次登陆会显示警告信息,选择“是”。

“login as:”处输入“pi”,默认密码是“raspberry”,登陆成功。


(6)root
树莓派Raspbian系统密码是多少?树莓派Raspbian系统默认登录用户名为pi,该账户默认密码是raspberry(可在raspi-config中修改)。树莓派的Raspbian系统root用户默认是禁用状态,且没有密码,所以要先设置个密码,然后开启才能正常使用。


?使用pi账户进行登陆命令行,执行命令:【sudo passwd root】设置root用户密码,然后在执行【sudo passwd --unlock root】开启root账户,在使用【su root】测试是否生效!

重新锁定root账户可执行命令:sudo passwd --lock root

 

二、树莓派内核编译

在树莓派的系统中,提供了很多的现成的驱动程序和资源,尽管这样,还是远远不能适用于大部分情况下的设计使用,所以在使用某些设备时,需要自行编写或者修改一些驱动,以适用于想要控制的设备。

1.开发环境和准备

(1)我的开发环境为ubuntu 16.04。

(2)连接树莓派查询系统版本 (命令: uname -a)windows环境下使用SSH远程登陆树莓派查询;

Raspberry Pi 内核编译

如上图可知,我的Raspber Pi系统为Linux raspberrypi 4.14.79+版本。这一点很重要,将决定需要编译的内核版本。

2.获取内核源码,交叉编译工具链和固件

(1)获取Raspber Pi系统内核源码

树莓派官方将树莓派相关的大部分资源都放在了GitHub上,所以只需再GitHub的相应板块找到即可,链接地址为:https://github.com/raspberrypi    如下图:

Raspberry Pi 内核编译

 

所以直接在Linux栏目中就能找到相关的内核源码了。

链接地址:https://github.com/raspberrypi/linux/tree/rpi-4.14.y

如下图:

Raspberry Pi 内核编译

如上图,即为4.14版本的内核源码了,选择Download ZIP下载压缩包即可,下载成功后再解压。

(2)获取交叉编译工具链

同样的在GitHub的RaspberryPi板块也提供了tools工具资源,链接地址:https://github.com/raspberrypi/tools/tree/master/arm-bcm2708     如下图:Raspberry Pi 内核编译

 

如上图可见tools再板块上的路径,再路径下找到相应交叉编译工具链,可知树莓派官方提供了3种交叉编译工具链(最下方的是同一个工具链,只是针对32bit系统和64bit系统做了区分),先将其克隆下来。

命令: git clone https://github.com/raspberrypi/tools

 

(3)获取固件

同样的是再GitHub的Raspberripi板块获取,如下图: Raspberry Pi 内核编译

 

如上图所示,即为相应的固件了,直接克隆下来即可。

命令:git clone https://github.com/raspberrypi/firmware

 

3.获取当前树莓派系统的配置文件

这里很有必要说明是,在raspberrypi系统的3.x版本以前,树莓派系统默认存在/proc/config.gz文件,但是更新到4.x版本之后,/proc/config.gz文件默认不存在了,所以我们需要先获取到这个文件。

执行命令:sudo modprobe configs

执行以上命令之后,会在/proc/目录下生成config.gz文件。然后将此文件从树莓派系统内拷贝到我们的PC平台(有很多种方法,比如U盘,NFS系统文件共享,TCP,samba等等)。

然后在需要编译的内核的顶层目录下执行命令:

命令:zcat config.gz > .config

目的是生成.config配置文件

Raspberry Pi 内核编译

4.编译前的准备

(1)确定树莓派系统内的编译器版本。

在putty上使用命令 cat /proc/version查询树莓派系统的编译器的 版本号。如下图:
Raspberry Pi 内核编译

如上图所知,gcc编译器的版本号为4.9.3版本,并且更新时间为2018年3月4日。

(2)选择编译工具链的版本,因为下载到的交叉编译工具链有三个版本,所以应该选择其中一个,但是考虑到版本的匹配问题(如果编译器的版本和原有系统的版本不一样的话,有可能会出现一些莫名奇妙的问题,特别是在开发驱动时)。下面查看各个编译器的版本。

arm-bcm2708hardfp-linux-gnueabi编译器:切换到tools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin/目录下,

使用命令:./arm-bcm2708hardfp-linux-gnueabi-gcc –v

 Raspberry Pi 内核编译

如上图可见此编译器为4.7.1版本,并且也能看到更新的时间。但是版本比现有系统的版本要低了。

arm-bcm2708-linux-gnueabi编译器:切换到tools/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/目录下,

使用命令:./arm-bcm2708-linux-gnueabi-gcc –v
Raspberry Pi 内核编译

如上图可见,此编译器也为4.7.1版本,只是更新时间不同。

gcc-linaro-arm-linux-gnueabihf-raspbian编译器:切换到tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/目录下,

使用命令:./arm-linux-gnueabihf-gcc –v
Raspberry Pi 内核编译

如上图可见,此编译其为4.8.3版本,并且更新时间为20140106.并且适用于32bitPC平台。

再看gcc-linaro-arm-linux-gnueabihf-raspbian-x64 编译器:切换到tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/目录,使用命令:./arm-linux-gnueabihf-gcc –v
Raspberry Pi 内核编译

如上图,可知此版本的编译器和莓派系统的编译器版本是最相近的一个版本,所以理当使用它进行编译。不过呢这是64bit PC平台的编译器,如果是32为平台的电脑,使用gcc-linaro-arm-linux-gnueabihf-raspbian编译器即可。

(3)安装编译工具链

将工具链添加到Makefile中。

切换到所编译内核的顶层目录,并打开目录下的Makefile文件,修改如下图:本例为: vi Makefile +313 
Raspberry Pi 内核编译直接添加了绝对路径的交叉编译工具链

5.开始编译

(1)执行命令:树莓派copy过来的.config文件

Raspberry Pi 内核编译

2)执行命令: KERNEL=kernel7

(3)执行命令:make zImage modules dtbs

这句就是真正的编译了,等等完成吧!如果电脑满足要求的话,可以再make的后面加上-j2,-j4,-j6,-j8等等,表示使用多少个线程进行编译,可以提高编译速度,编译是一个漫长的过程。编译成功后,在路径arch/arm/boot/下会生成zImage镜像文件。
Raspberry Pi 内核编译

zImage 是 Compressed kernel image 文件,它是一种可执行的镜像文件,但是对于树莓派系统的构建而言,这还不是我们最终想要的,所以还需要将其转换为kernel.img文件。

(4)安装编译的模块驱动

执行命令:mkdir modules

执行命令:sudo make INSTALL_MOD_PATH=modules modules_install

在源码顶层目录下的modules会生成相关的驱动库。

(5)镜像转换

kernel.img镜像是通过工具将zImage转换而来的!而工具存在于前文所下载的工具包里。工具名为mkimage,切换到工具目录(具体情况根据自己存放的目录路径确定,找到工具即可),如下图:
Raspberry Pi 内核编译

然后执行命令:./imagetool-uncompressed.py ../../../kernel/linux/arch/arm/boot/zImage

注:命令的执行,视自己的存放路径而言,注意路径即可。

命令执行成功后,会在当前目录下生成kernel.img文件,如下图:

Raspberry Pi 内核编译

如上图生成的kernel.img文件即为所需要的树莓派内核所需要的镜像文件了。

6.备份firmware

(1)创建备份目录

命令:mkdir backup

(2)备份

当插入SD卡后,立即就被识别了,可以将SD卡设备挂载到某目录上进行访问,也可以直接访问。默认在/media/python/目录下(madia目录为PC平台下根目录下的子目录,python为当前登陆用名子的目录)会看到两个目录,此即为SD卡的两个分区(分别是fat32属性的分区和ext4属性的分区),如下图:
Raspberry Pi 内核编译

如上图可知,boot目录为fat32分区的目录,另一个为ext4分区的目录。而我们要备份的是boot目录,因为ext4分区的目录其实就是作为树莓派再运行是的跟文件系统。

执行命令:cd /media/python/boot/ 切换到目录,

执行命令:sudo cp *.elf *.bin ~/raspberrypi/backup/

执行命令:ls ~/raspberrypi/backup/ 查询是否备份成功,

执行命令: sudo rm *.elf *.bin

因为kernel可以通过在/boot/config.txt中进行设定,所以可以先不拷贝出来。

7.升级RPi的kernel、Firmware和lib

(1)修改前面生成的kernel.img文件的名称。

因为我前面打包编译好的zImage内核镜像时,直接打包成了kernel.img这个名称,为了区别于SD卡的内核名称,现在为它重命名,如下图:
Raspberry Pi 内核编译

如上图,改名为kernel_new.img。

(2)将新内核镜像拷贝到SD卡的fat32分区,即在这里是拷贝到名为boot的分区。

执行命令:sudo cp kernel_new.img /media/python/boot/

(3)修改树莓派系统的配置文件。

在SD卡的FAT32分区,存在一个名为config.txt的文件。

在/media/python/boot目录下执行命令:sudo vim config.txt

Raspberry Pi 内核编译

在config.txt文件的前面添加“kernel=kernel_new.img”这行,如果原来有的话,就修改一下。这样系统就会引导到我们刚刚拷入的kernel_new.img镜像;或者是直接将目录中的kernel.img通过命令rm删除,然后将kernel_new.img改名为kernel.img。

(4).解压前面下载的Firmware固件压缩包

执行命令:unzip firmware-master.zip

执行命令:cd firmware-master/boot/

(5)升级firmware固件

执行命令:sudo cp bootcode.bin fixup.dat fixup_cd.dat start.elf /media/python/boot/

执行命令:cd ../hardfp/opt/

Raspberry Pi 内核编译

现在开始操作第二分区,即xt4分区,再我这里它的名为“rootfs”,不过名字不是最重要的。

执行命令:sudo cp -r vc/ /media/python/rootfs/opt/

命令含义是,将新固件的vc库复制到树莓派系统的根文件系统下的opt子目录***意,这里如果使用的是arm-bcm2708-linux-gnueabi编译器,非硬浮点,那么在拷贝vc时,应该拷贝的是firmware-master/opt/目录下的vc。

(6)升级模块驱动lib。

切换到前面在Linux内核源码目录下创建的module目录下。

执行命令:cd ../../../linux/modules/ 这是我的路径,可根据自己的路径进行调整。

将modules目录下的lib目录copy到树莓派根文件系统下,

执行命令:sudo cp -r lib/ /media/python/rootfs/

8.享用新的kernel

将SD卡插回树莓派!就可以看到其可以正常启动了。那么代表这树莓派raspberrypi操作系统内核源码的编译成功。这样,后面就可以*的添加各种驱动了。