【树莓派Linux内核开发】入门实操篇(虚拟机Ubuntu环境搭建+内核源码获取与配置+内核交叉编译+内核镜像挂载)
一、搭建Ubuntu环境
1.ubuntu18.04镜像下载
打开ubuntu18.04镜像传送门,进入到主页
往下滑,找到相应镜像并下载
等待镜像下载完毕即可
2.VMware软件安装
- VMware是一款运行在windows系统上的虚拟机软件,可以虚拟出一台计算机硬件,方便安装各类操作系统
进入VMware官网传送门,来到主页,往下滑,选着适合的版本进行下载
下载完成后,双击打开安装应用
点击下一步
勾选我接受
,继续下一步
选择自己的安装路径
,继续下一步
全部取消勾选
,继续下一步
最后,点击下一步
,开始安装
安装完成
咳咳,最后这部分就交给大家了
MC60H-DWHD5-H80U9-6V85M-8280D
3.安装镜像,创建虚拟机
打开VMware,点击创建新的虚拟机
我这里是选择自定义(看自己需求),然后进入下一步
直接下一步
选择好之前下载好的镜像文件,接着下一步
填写好安装信息,继续下一步(用户名有格式要求,不符合的会有提示)
取好虚拟机名字,选择一个磁盘空间比较大的位置,继续下一步
根据自己电脑配置量力而行(一般都这么操作也问题不大),继续下一步
这里就采用推荐内存了,2G
看情况,我这里选择桥接模式
后边都选推荐
创建虚拟磁盘
默认20G,下一步即可
开始创建
等待创建完毕即可
创建完毕,登录成功
4.虚拟机安装基础软件(安装过程有询问,直接回车或者Y)
4.1 安装vim
输入命令vi hello.c
,发现方向键不好用,系统软件比较古老
arsen@ubuntu:~$ vi hello.c
输入命令 sudo apt-get install vim
进行下载安装
arsen@ubuntu:~$ sudo apt-get install vim
安装完后再次vi hello.c
,发现颜色变了,操作也好使起来了
若发现上不了网,则进行如下操作
打开虚拟机设置,选择桥接模式
检查编辑里的 虚拟网络编辑器
检查里面的桥接模式(这里的ubuntu18的虚拟机已经帮桥接好,没有桥接模式的显示)
4.2 安装gcc(不会就面向百度开发)
编写完测试代码hello.c,发现没有gcc工具进行编译
面向百度后,得到下面命令,该命令将安装一堆新包,包括gcc,g++和make工具
sudo apt install build-essential
安装好后,进行编译,运行成功(应该加个\n的)
4.3 安装ifconfig
输入命令ifconfig
,发现运行失败
面向百度后,输入安装命令
sudo apt install net-tools
一开始遇到了安装失败的问题,后面把报错信息面向百度/CSDN后,得到参考解决方法,先弄两条命令再安装
报错信息:
E: Could not get lock /var/lib/dpkg/lock-frontend - open (11: Resource temporarily unavailable)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), is another process using it?
解决方法:
sudo rm /var/lib/dpkg/lock-frontend
sudo rm /var/lib/dpkg/lock
sudo apt install net-tools
安装成功
5.添加共享文件夹(虚拟机上默认路径是 /mnt/hgfs/share)
点开虚拟机的设置
在选项里,启动并添加
选择本地电脑的文件夹路径,设置好此文件夹在虚拟机中的名字,继续下一步
完成添加,并确定
添加好后,虚拟机上的共享文件夹默认路径是 /mnt/hgfs/share
6.拷贝树莓派Linux内核源码和交叉编译工具链
6.1 下载内核源码和工具链
先到树莓派Linux内核源码地址,选择适合自己树莓派版本的,把源码下载到本地,放到共享文件夹下
版本查询
树莓派上运行 uname -r(演示一下)
uname -r
(我的树莓派是3B+,烧录的镜像是官方的标准镜像,看上面的内核版本我应该下载6.xx的才对,这里下错了,不过问题不大,只是测验,但对应版本的才能进行驱动和运行编译出来的东西)
再下载树莓派交叉编译工具到share共享文件夹
传送门
6.2 解压并配置环境变量
继续操作上面的虚拟机,删除当前目录下的所有文件(没啥用的文件)
rm * -rf
接着,使用命令创建一个SYSTEM文件夹并进入
mkdir SYSTEM
cd SYSTEM
然后,使用 cp 命令,把我们在电脑上下载好的文件拷贝到虚拟机的当前目录
cp /mnt/hgfs/share/linux-rpi-4.19.y.zip .
cp /mnt/hgfs/share/tools-master.zip .
使用uzip命令解压压缩包
(这里显示我没有uzip,而且安装uzip还失败了,报错:E: Unable to locate package uzip)
arsen@ubuntu:~/SYSTEM$ ls
linux-rpi-4.19.y.zip tools-master.zip
arsen@ubuntu:~/SYSTEM$ uzip tools-master.zip
Command 'uzip' not found, but there are 16 similar ones.
arsen@ubuntu:~/SYSTEM$ sudo apt-get install uzip
[sudo] password for arsen:
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package uzip
arsen@ubuntu:~/SYSTEM$
最后,问题解决了,发现是解压命令错了,应该是unzip
不过,如果报错如上:E: Unable to locate package xxx
原因:刚安装,软件源还来不及更新,无法找到包
解决办法:
1.首先尝试update命令
sudo apt-get update2.如果不行则执行upgrade
sudo apt-get upgrade3.最后上面两项都不行则尝试
sudo apt-get install aptitude成功以后使用
sudo aptitude install xxx
先使用unzip
解压交叉编译工具链
unzip tools-master.zip
然后,安装交叉编译工具链,并进行配置使它永久有效
先cd到根目录,再输入命令 vi .bashrc
vi .bashrc
快捷键 shift + g 跳到最后一行
另一边先进入解压后的arm-bcm2708文件夹
cd tools-master/arm-bcm2708
一步步获取交叉编译工具链的绝对路径
pwd 打印出来的:
/home/arsen/SYSTEM/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
echo $PATH 打印出来的:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
arsen@ubuntu:~/SYSTEM/tools-master/arm-bcm2708$ ls
arm-bcm2708hardfp-linux-gnueabi arm-rpi-4.9.3-linux-gnueabihf
arm-bcm2708-linux-gnueabi gcc-linaro-arm-linux-gnueabihf-raspbian
arm-linux-gnueabihf gcc-linaro-arm-linux-gnueabihf-raspbian-x64
arsen@ubuntu:~/SYSTEM/tools-master/arm-bcm2708$ cd gcc-linaro-arm-linux-gnueabihf-raspbian-x64
arsen@ubuntu:~/SYSTEM/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64$ ls
arm-linux-gnueabihf bin lib libexec share
arsen@ubuntu:~/SYSTEM/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64$ cd bin
arsen@ubuntu:~/SYSTEM/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin$ pwd
/home/arsen/SYSTEM/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
arsen@ubuntu:~/SYSTEM/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
arsen@ubuntu:~/SYSTEM/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin$
接着,回到配置窗口,在最后一行加上(第二句的路径是echo $PATH 获取的 + pwd 获取的)
export PATH=$PATH:/home/arsen/SYSTEM/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
#或者下面这句,二选一就行
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/:/home/arsen/SYSTEM/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
配置好后,返回操作目录,使用下面命令进行加载
source .bashrc
检查工具链版本,成功运行则安装完毕
arm-linux-gnueabihf-gcc -v
最后,进入SYSTEM文件夹,对内核源码压缩包进行解压
cd SYSTEM
unzip linux-rpi-4.19.y.zip
解压完毕,准备工作完成
二、树莓派等芯片带操作系统的启动过程
1.x86、Intel、windows等设备的启动过程
启动过程:
- 电源 —> BIOS —> windows内核 —> C,D盘的启动 —> 程序的启动(例如QQ的启动)
2.嵌入式产品(树莓派、mini2440、mini6410、nanopi、海思、RK(瑞芯微) )的启动过程
启动过程:
- 电源 —> BootLoader (引导操作系统启动) —> linux内核 —> 文件系统(根据功能性来组织文件夹,带访问权限)—> 嵌入式产品的启动(例如KTV点歌机,人脸识别打卡机,智能家居主控)
3.安卓操作系统的启动过程
启动过程:
- 电源 —> fastBoot/Bootloader/ —> linux内核 —> 文件系统 —> 虚拟机 —> HOME应用程序 —> 点击某图标打开某app
4.小扩展
C51、STM32(裸机,不带操作系统)的开发流程
- 不带操作系统的裸机开发是C语言直接操控底层寄存器实现相关业务
BootLoader开发:
- 一阶段:让CPU跟内存,FLASH,串口,IIC,IIS,数据段等打交道(汇编和C结合驱动这些设备)
- 二阶段:引导Linux内核启动(纯C操作)
三、树莓派Linux内核源码简单认知
1.linux内核认知
-
linux是开源的,免费的,由其linux开源社区工作者和爱好者共同进行维护
-
linux是一个开源的,支持多架构多平台代码;
如ARM:海思,树莓派,RK,nanoPi,友善之臂;X86;PowerPC,MIPS
-
可移植性非常高
-
linux内核大约由1.3w个C文件组成,1100w行代码左右;
但是linux内核编译出来一般就是几M,一般是4M左右;
因为是支持多平台多架构,所以在编译之前是需要进行配置的,配置成适合的目标平台来用
2.Linux文件系统分区
详细分区传送门
上图Linux文件都是根据功能来放的
- dev: 放的是设备相关,
- lib: 放的是各种动态库和静态库,
- proc: 放的是内核的数据信息,
- home:是用户登录的工作界面,
- opt: 是跟内核底层有关的,
- sbin: 通常是可执行文件或指令,
- bin: 也是指令和可执行文件,
- boot: 是启动要加载的配置等等。
四、树莓派Linux内核源码配置
1.内核源码配置原因
操作树莓派需要进行驱动代码的编写,编写完后,代码运行需要进行驱动代码的编译,而驱动代码的编译需要一个提前编译好的内核,编译内核必须要进行内核源码的配置。
(配置的最终目标会生成 .config文件,该文件指导Makefile去把有用东西组织成内核)
2.内核源码配置方法
Linux内核源码配置,其实就是配置config
-
linux源码中有很多工程:
树莓派1的工程是bcmrpi_defconfig;
树莓派2、3的工程是bcm2709_defconfig树莓派4的工程是bcm2711_defconfig(临时ChatGPT查的)
2.1 cp 厂家.config
厂家linux内核源码,比如说买了树莓派,厂家就会向我们提供树莓派linux内核源码,可以进行参考
使用厂家源码中的工程文件,进行cp 厂家.config
先进入树莓派Linux内核源码文件夹,然后运行下面指令,查看各个架构的工程文件
find . -name *_defconfig
树莓派3的工程文件
使用下面命令获取bcm2709_defconfig的配置到 .config里
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make bcm2709_defconfig
命令解释:
#命令解释
ARCH=arm(指定当前要编译的是arm架构)
CROSS_COMPILE=arm-linux-gnueabihf- (指定编译器是树莓派交叉编译工具链)
KERNEL=kernel7 (指明kernel类型,树莓派1设置为kernel,树莓派2,3设置为kernel7,树莓派4设置为kernel7l)
make bcm2709_defconfig(make为配置命令)
在执行该命令的过程了我遇到了两次报错
第一次报错:
YACC scripts/kconfig/zconf.tab.c
/bin/sh: 1: bison: not found
scripts/Makefile.lib:196: recipe for target ‘scripts/kconfig/zconf.tab.c’ failed
make[1]: *** [scripts/kconfig/zconf.tab.c] Error 127
Makefile:534: recipe for target ‘bcm2709_defconfig’ failed
make: *** [bcm2709_defconfig] Error 2解决方法:
根据报错信息来看,这是由于缺少bison工具导致的错误。bison是用于生成解析器的工具,需要进行安装才能继续进行编译过程。
在树莓派上安装bison的方法可以尝试以下命令:
sudo apt-get install bison
第二次报错:
YACC scripts/kconfig/zconf.tab.c
LEX scripts/kconfig/zconf.lex.c
/bin/sh: 1: flex: not found
scripts/Makefile.lib:188: recipe for target ‘scripts/kconfig/zconf.lex.c’ failed
make[1]: *** [scripts/kconfig/zconf.lex.c] Error 127
Makefile:534: recipe for target ‘bcm2709_defconfig’ failed
make: *** [bcm2709_defconfig] Error 2解决方法:
根据报错信息,这次报错是由于缺少flex工具导致的。flex是用于生成词法分析器的工具,需要进行安装才能继续进行编译过程。
在树莓派上安装flex的方法可以尝试以下命令:
sudo apt-get install flex
2.2 make menuconfig 通过菜单一项项配置(通常是基于厂家的config来配置)
通过make menuconfig 一项项的来配置,通常都是基于厂家的config来进行配置。
通过这样的"裁剪",可以减小内核的体积。
先安装一些必要的库
sudo apt-get install bc
sudo apt-get install libncurses5-dev libncursesw5-dev
sudo apt-get install zlib1g:i386
sudo apt-get install libc6-i386 lib32stdc++6 lib32gcc1 lib32ncurses5
安装好后,运行下面指令,在内核菜单进行配置
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make menuconfig
选项解释
- General setup —>(通用选项)
- [ * ] Enable loadable module support —> 内核模块选项
- [ * ]Enable the block layer —> 块设备逻辑层选项(大文件支持、分区、I/O调度)
- System Type —>(平台选项)
- Bus support —> 总线选项
- Kernel Features —>内核特征
- Boot options —> 引导选项
- CPU Power Management —> CPU电源管理选项
- Floating point emulation —> 浮点运算
- Userspace binary formats —> 用户程序格式
- Power management options —> 电源管理选项
- [*] Networking support —> 网络协议选项
- Device Drivers —> 设备驱动
- Firmware Drivers ---- 驱动固件选项
- File systems —> 文件系统选项
- Kernel hacking —> 内核调试选项
- Security options —> 安全模块选项
选择要配置的文件,使用空格可以切换[ ]里面的模式。
[*]:编译进内核(*代表Y,编译进内核,zImage包含了驱动) [M]:编译成模块(以模块的方式生成驱动文件xxx.ko,系统启动后, 通过命令inmosd xxx.ko来加载驱动,也可以减小一些内核大小) [ ]:表示不需要的部分 空格可切换修改。 修改完毕后,保存退出
2.3 完全自己来(略)
xxxx
五、树莓派 linux 内核源码编译并运行
1.编译
运行下面指令进行编译
编译的时间会比较久(看电脑配置,20~30分钟少不了)
编译过程中如果跑了几分钟没有报错,那就是没问题,等就行了
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make -j4 zImage modules dtbs
命令解释:
#命令解释
ARCH=arm(指定当前要编译的是arm架构)
CROSS_COMPILE=arm-linux-gnueabihf- (指定编译器是树莓派交叉编译工具链)
KERNEL=kernel7 (指明kernel类型,树莓派1设置为kernel,树莓派2,3设置为kernel7,树莓派4设置为kernel7l)
make -j4:指定用多少电脑资源进行编译(j4是四核的意思,这个要每个人根据
自己的电脑的配置以及虚拟机的设置的核数来决定,我之前虚拟机设置的是4核)
zImage:生成内核镜像
modules:要生成驱动模块
dtbs:生成配置文件
编译过程中,我一下子就遇到了一个报错:
scripts/extract-cert.c:21:10: fatal error: openssl/bio.h: No such file or directory
#include <openssl/bio.h>
^~~~~~~~~~~~~~~
compilation terminated.
scripts/Makefile.host:90: recipe for target ‘scripts/extract-cert’ failed
make[1]: *** [scripts/extract-cert] Error 1
make[1]: *** Waiting for unfinished jobs…
UPD include/generated/asm-offsets.h
CALL scripts/checksyscalls.sh
Makefile:1073: recipe for target ‘scripts’ failed
make: *** [scripts] Error 2
解决方法:
根据报错信息来看,这是由于缺少openssl库导致的错误。缺少openssl/bio.h头文件。
在树莓派上安装openssl库的方法可以尝试以下命令:
sudo apt-get install libssl-dev
解决后再运行编译命令就一直跑了,应该没问题了,等待就好
编译完成
编译成功后,会生成vmlinux文件,失败则无此文件
2.将zmage文件打包成树莓派可用的xxx.img镜像文件
生成的zImage文件在/home/arsen/SYSTEM/linux-rpi-4.19.y/arch/arm/boot
路径的boot文件夹下
回到内核源码目录,输入下面命令进行镜像打包(会生成kernel_new.img适合树莓派使用的镜像文件)
./scripts/mkknlimg arch/arm/boot/zImage ./kernel_new.img
3.将树莓派SD卡的U盘映射到虚拟机
将插有树莓派SD卡的U盘插入电脑,通过下面操作,把U盘映射到ubuntu虚拟机(U盘插入过程中,电脑有时会自动识别到并询问是否进行映射,问题不大,可自行百度解决)
输入下面命令,查看内核信息(可以显示系统中各种硬件设备的信息),有设备接入的时候内核会打印出驱动层面的信息
dmesg
看到sb1,sb2,则说明接入成功
sdb1,2分别是树莓派sd卡的两个分区(sd卡在刷树莓派镜像的时候会自动变成两个分区)
- ①一个fat分区,是boot相关的内容,kernel的img文件在此分区。
- ②一个是ext4分区,也就是系统的根目录分区。(
cd /
进入的就是系统的根目录)
4.数据拷贝
4.1 挂载U盘
返回到原先创建SYSTEM目录的地方,再创建data1和data2两个文件夹
运行下面指令,将两个分区挂载到新创建的两个数据文件夹
sudo mount /dev/sdb1 data1
#挂载U盘的sdb1文件分区到当前路径下的data1文件夹,
#该分区为fat分区,是boot相关的内容,kernel的img.
sudo mount /dev/sdb2 data2
#挂载U盘的sdb2文件分区到当前路径下的data2文件夹,
#该分区为ext4分区,也就是系统的根目录分区.
运行完后,两个新建的文件夹就都有数据了,都分别关联到了两个分区
data1为fat分区(boot相关),data2为ext4分区(系统根目录相关)一定要对应好!!!
4.2 安装modules
运行指令安装,因为内核配置时,有一部分是编译成模块的形式配置进来的,安装后hdmi接口、usb、wifi、io口等等的设备才能使用,所以需要这么一步。
回到内核源码文件夹,运行安装命令
# 操作ext4分区需要root权限,sudo
# [ext4]为第二分区(sdb2)虚拟机上挂载的地址(data2的位置),需要根据自己的地址更改
# 更改前
sudo ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make INSTALL_MOD_PATH=[ext4] modules_install
# 更改后,我的,注意将代码的“[ext4]”更改为data2的绝对路径 !!
sudo ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make INSTALL_MOD_PATH=/home/arsen/data2 modules_install
安装完成
4.3 安装并更新kernel.img文件
注意查看原来镜像名字是kernel7.img
ls /home/arsen/data1
在操作过程中,原来的这个kernel7.img会被覆盖,为了防止刷机失败,或者拷贝过程中文件损坏,需要提前用别名备份这个文件。
打开新的终端(ctrl alt t)(方便操作罢了),进入其存放路径(cd /home/data1)
sudo cp kernel7.img kernel7OLD.img
从内核源码目录(linux-rpi-4.19.y
)拷贝kernel_new.img
(是由zImage打包而成)到data1并且命名为kernel7.img
覆盖原来的文件
sudo cp kernel_new.img /home/arsen/data1/kernel7.img
检查拷贝是否有问题,使用命令md5sum
显示文件的唯一编码号,若相同则为同一个文件
- md5sum kernel_new.img
- md5sum /home/arsen/data1/kernel7.img
4.4 拷贝相关配置文件
从内核源码目录linux-rpi-4.19.y
进行拷贝,这些配置文件是为了能够加载驱动以及一些其他的配置
# 修改前,[fat]为第一分区(sdb1)虚拟机上挂载的地址(data1的位置),需要根据自己的地址更改
cp arch/arm/boot/dts/.*dtb* [fat]/
cp arch/arm/boot/dts/overlays/.*dtb* [fat]/overlays/
cp arch/arm/boot/dts/overlays/README [fat]/overlays/
# 按自己需求修改后,README是说明书
cp arch/arm/boot/dts/.*dtb* /home/arsen/data1/
cp arch/arm/boot/dts/overlays/.*dtb* /home/arsen/data1/overlays/
cp arch/arm/boot/dts/overlays/README /home/arsen/data1/overlays/
5.在树莓派上运行编译好的内核镜像
5.1 USB-TTL进行串口打印调试信息,观看启动过程
先点击选择断开连接sd卡,使其重新挂载在windows上
添加USB串口信息,如果之前在做别的项目,例如串口编程时,会把这个配置信息删掉,这时需要添加回来
配置好后,sd卡插回树莓派,USB-TTL连接,用MobaXterm进行串口连接,可以看到启动正常。
此时,可以再输入查看内核版本的命令进行确认(如果和之前不一样,则说明更换成功)
uname -r
uname -a
5.2 SSH连接查看
用指令uname -r/a
查看内核版本,发现内核版本与之前相比,已然发生了变化,说明更换成功
我这边用的是SSH连接,内核更换后,我发现之前的wifi配置信息还是有效的,就直接通过MobaXterm进行SSH连接树莓派了文章来源:https://www.toymoban.com/news/detail-861849.html
文章来源地址https://www.toymoban.com/news/detail-861849.html
到了这里,关于【树莓派Linux内核开发】入门实操篇(虚拟机Ubuntu环境搭建+内核源码获取与配置+内核交叉编译+内核镜像挂载)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!