【OrangePi Zero2的系统移植】嵌入式Linux系统的组成、编译u-boot、编译内核、Linux根文件系统

一、嵌入式Linux系统的组成
二、编译u-boot
三、编译内核
四、Linux根文件系统

一、嵌入式Linux系统的组成

嵌入式Linux系统和PC完整的操作系统的对比如下:
在这里插入图片描述

  1. BIOS和UEFI的作用
    a. 进行硬件自检,检测内存,CPU,显卡,硬盘等设备的状态和配置。
    b. 设置启动顺序,选择从哪个设备加载引导程序,如硬盘,U盘等。
    c. 加载引导程序,如bootmgr,grub2等,然后由引导程序加载操作系统,如Windows,Linux等。
    d. UEFI是BIOS的一种升级替代方案。UEFI本身已经相当于一个微型操作系统。

  2. grub2和bootmgr:
    a. grub2是GNU项目开发的一种通用的引导加载器,它可以引导多种不同的操作系统,包括
    Linux,Windows,FreeBSD等。
    b. bootmgr是Windows版本的引导加载器,它只能引导Windows系统或者其他使用MBR分区表的
    系统。
    b. grub2和bootmgr都可以通过chainloader命令来加载对方的引导文件,从而实现多重引导。
    c. 加载引导程序,如bootmgr,grub2等,然后由引导程序加载操作系统,如Windows,Linux
    等。

  3. U-boot
    a.uboot是一种用于嵌入式系统的引导加载器,它可以支持多种硬件平台和架构,如ARM,MIPS,
    PowerPC等.
    b. uboot可以提供BIOS和grub2的功能,它可以初始化硬件设备,设置启动顺序,加载引导文件,
    启动操作系统,或者进入命令行模式

二、编译u-boot

1、 u-boot简介

uboot是一种通用的引导加载程序,它可以用于多种嵌入式系统,支持多种操作系统,如Linux, Android,
NetBSD等。uboot的主要作用是将操作系统内核从存储设备(如Flash, SD卡等)加载到内存中,并执行
内核代码。

2、 XIP设备

XIP设备是指一种可以直接在存储器中执行程序代码的设备,而不需要将代码复制到内存中。XIP的全称
是eXecute In Place,即芯片内执行。像片内的SRAM, NOR Flash, BROM等。

3、 为什么需要u-boot

因为嵌入式系统的硬件资源有限,CPU上电后只能执行一小段内置的代码(BROM System),这段代码
不足以完成内存初始化,文件系统访问,网络通信等复杂的任务。因此,需要一个中间层的程序,来完
成这些工作,并引导操作系统启动。

4、 u-boot启动流程

开机Uboot的运行流程一般是这样的:
在这里插入图片描述
以下官网有对U-Boot SPL大小限制的说明:
https://linux-sunxi.org/BROM
在这里插入图片描述
另《Allwinner_H616_Datasheet_v1.0.pdf》(3.1 Memory Mapping)章节对BROM大小的说明。
执行顺序

  1. 当H616芯片上电或复位后,brom会自动执行,它会根据芯片的引脚电平或寄存器设置,确定启动
    模式,如从nand flash,spi flash,sd卡,usb等设备中启动。
  2. brom会根据启动模式,选择相应的设备驱动,初始化SD卡设备控制器,设置设备参数,如时钟频
    率,总线宽度,电压等级等
  3. brom会从启动设备的特定扇区中,读取第一级引导程序,如spl将其加载到芯片的内部sram中,并
    跳转到其入口点执行
  4. spl会继续初始化一些硬件设备,如ddr,pll,gpio等,然后从启动设备的特定分区中,读取第二级
    引导程序,如uboot proper,将其加载到ddr中,并跳转到其入口点执行,
  5. uboot会继续初始化一些硬件设备,如网卡,lcd,从SD卡中读取内核文件,启动操作系统。

5、 u-boot编译流程

根据官方的编译方式,详见(《OrangePi_Zero2_H616用户手册v4.0》 6.3 编译u-boot)

  1. 运行 build.sh 脚本, 记得加 sudo 权限
test@test:~/orangepi-build$ sudo ./build.sh
  1. 选择 U-boot package, 然后回车
    在这里插入图片描述
  2. 接着选择开发板的型号
    在这里插入图片描述
  3. 重复编译 u-boot 时, 使用下面的命令无需通过图形界面选择, 可以直接开始编译 u-boot
sudo ./build.sh BOARD=orangepizero2 BRANCH=next BUILD_OPT=u-boot
  1. 查看编译生成的 u-boot deb 包
test@test:~/orangepi-build$ ls output/debs/u-boot/linux-u-boot-currentorangepizero2_3.1.0_arm64.deb
  1. 然后登录到H616开发板, 卸载已安装的 u-boot 的 deb 包
dpkg -l | grep linux-u-boot #查看u-boot包名称
sudo apt purge -y linux-u-boot-orangepizero2-current 
#卸载上面查找到的u-boot包名称,有可能是linux-u-boot-orangepizero2-next
  1. 再安装刚才上传的新的 u-boot 的 deb 包
sudo dpkg -i linux-u-boot-next-orangepizero2_3.1.0_arm64.deb
sudo nand-sata-install #一路回车
sudo reoobt -f

上述官方编译u-boot的方法可以用以下步骤代替:

1、清理u-boot:

sudo chown test:test v2021.10-sunxi -R 
#修改所属用户为当前用户(根据实际用户名修改),保证当前用户下权限没有问题
cd v2021.10-sunxi
make distclean

2、配置u-boot,生成.config配置文件:

make -j6 orangepi_zero2_defconfig CROSS_COMPILE="aarch64-none-linux-gnu-"

3、编译uboot, 生成u-boot-sunxi-with-spl.bin

make -j6 CROSS_COMPILE="aarch64-none-linux-gnu-"

4、将生成的u-boot-sunxi-with-spl.bin 拷贝到开发板上,参考官网对BROM的启动及SD卡数据组成的说

明,官网地址如下:
https://linux-sunxi.org/Bootable_SD_card#SD_Card_Layout
在这里插入图片描述
然后执行如下命令:

dd if=/dev/zero of=/dev/mmcblk1 bs=1k count=1023 seek=1 status=noxfer 
#格式化1k到1M为止的数据
dd if=u-boot-sunxi-with-spl.bin of=/dev/mmcblk1 bs=1k seek=8 conv=fsync

三、编译内核

1、 Linux内核的主要功能

Linux操作系统框架如下:
在这里插入图片描述
Linux内核的主要功能:进程管理、内存管理、驱动、系统调用

Linux的目录结构如下:
在这里插入图片描述
a. arch/:这个目录包含了不同架构处理器的代码,如x86,arm,mips等。每个架构都有自己的子目
录,如arch/x86/,arch/arm/等。在每个架构的子目录中,又有一些子目录和文件,如boot/,lib/,
mm/,include/等,分别包含了特定平台的启动代码,库函数,内存管理,头文件

b. block/:这个目录包含了块设备的代码,如硬盘,光驱等。block/目录中主要包含了块设备的基本框
架和I/O调度算法,以及一些通用的块设备驱动

c. crypto/:这个目录包含了加密算法的代码,如AES,SHA1,MD5等

d. drivers/:这个目录包含了设备驱动程序的代码,如键盘,鼠标,网卡,声卡,摄像头等。drivers/目
录中的代码按照设备的类别进行分类,如char/,block/,input/,i2c/,spi/,pci/,usb/等

e. fs/:这个目录包含了文件系统的代码,如ext4,fat,ntfs,nfs,cifs等。fs/目录中的代码按照文件系
统的类型进行分类,如ext4/,fat/,ntfs/等。在fs/目录中,还有一些通用的文件和子目录,如
mount.h,dentry.c,proc/,sysfs/等,它们用于实现文件系统的基本功能和接口

f. include/:这个目录包含了内核所需的头文件,如linux/,asm/,uapi/等。头文件是用于声明变量,
函数,结构,宏,常量等的文件,它们可以被其他的源文件引用,以便共享和重用代码。include/目录中
的头文件按照不同的层次和用途进行分类,如linux/目录中的头文件是与平台无关的,asm/目录中的头
文件是与平台相关的,uapi/目录中的头文件是用于内核和用户空间的API的

g. init/:这个目录包含了内核初始化的代码,如main.c,version.c,do_mounts.c等。init/目录中的代
码是内核的入口和核心,它们负责调用其他子系统和模块的初始化函数

  • ipc/:这个目录包含了进程间通信的代码,如sem.c,msg.c,shm.c等。进程间通信是指在不同的进程
    之间传递数据和信号的方法,它们可以让进程之间实现协作和同步。ipc/目录中的代码实现了一些常用的
    进程间通信机制,如信号量,消息队列,共享内存等
  • kernel/:这个目录包含了内核的核心代码,如sched/,irq/,time/,fork.c,exit.c,signal.c等。
    kernel/目录中的代码实现了一些内核的基本功能和服务,如进程调度,中断处理,时间管理,进程创
    建,进程终止,信号处理等
  • lib/:这个目录包含了内核需要引用的一些库函数的代码,如string.c,vsprintf.c,crc32.c等
  • mm/:这个目录包含了内存管理的代码
  • net/:这个目录包含了网络协议的代码,和网卡驱动不相关代码、
  • scripts/:这个目录包含了内核编译所需的一些脚本,如Makefile,Kconfig,checkpatch.pl等
  • tools/:这个目录包含了一些和内核交互的工具,如perf/,ftrace/,cpupower/,objtool/等。工具是
    用于分析和调试内核的程序,它们可以让内核的性能和稳定性更加优化和提高

2、 Linux内核编译流程

根据官方的编译方式,详见(《OrangePi_Zero2_H616用户手册v4.0》 6.4 编译Linux内核)

  1. 运行 build.sh 脚本, 记得加 sudo 权限
test@test:~/orangepi-build$ sudo ./build.sh
  1. 选择 Kernel package, 然后回车
    在这里插入图片描述
  2. 然后会提示是否需要显示内核配置界面, 如果不需要修改内核配置, 则选择第一个即可, 如果需
    要修改内核配置, 则选择第二个
    在这里插入图片描述
  3. 接着选择开发板的型号
    在这里插入图片描述
  4. 查看编译生成的内核相关的 deb 包
    a. linux-dtb-next-sun50iw9_3.1.0_arm64.deb 包含有内核使用的 dtb 文件
    b. linux-headers-next-sun50iw9_3.1.0_arm64.deb 包含内核头文件
    c. linux-image-next-sun50iw9_3.0.1_arm64.deb 包含内核镜像和内核模块
test@test:~/orangepi-build$ ls output/debs/linux-*
output/debs/linux-dtb-next-sun50iw9_3.1.0_arm64.deb
output/debs/linux-image-next-sun50iw9_3.1.0_arm64.deb
output/debs/linux-headers-next-sun50iw9_3.1.0_arm64.deb
  1. 重复编译 kernel 时, 使用下面的命令无需通过图形界面选择, 可以直接开始编译kernel
sudo ./build.sh BOARD=orangepizero2 BRANCH=next BUILD_OPT=kernel KERNEL_CONFIGURE=no
  1. 如果对内核做了修改, 可以使用下面的方法来更新开发板 linux 系统的内核和内核模块
scp linux-image-next-sun50iw9_3.1.0_arm64.deb test@192.168.1.28:/home/test/
sudo apt purge -y linux-image-next-sun50iw9 # 也有可能是linux-image-next-sun50iw9
sudo dpkg -i linux-image-next-sun50iw9_3.1.0_arm64.deb
sudo reboot -f

上述官方编译kernel的方法可以用以下步骤代替:

  1. 清理旧配置文件及生成的文件
sudo apt-get install ccache #安装ccahe,用于编译加速
export PATH=$PATH:/home/$(whoami)/orangepi-build/toolchains/gcc-arm-9.2-2019.12-
x86_64-aarch64-none-linux-gnu/bin #导入教程编译环境
make ARCH=arm64 distclean
  1. 配置内核, 更新内核依赖属性和新属性, 生成.config:
cp ../../external/config/kernel/linux-5.16-sun50iw9-current.config .config #拷贝默认配置
make ARCH=arm64 CROSS_COMPILE="aarch64-none-linux-gnu-" olddefconfig #这里执行
make menuconfig 然后exit也是可以的

a. make olddefconfig 的作用是根据已有的 .config 文件生成一个新的 .config 文件,同时更新内核的依
赖属性和新属性。它会使用旧的 .config 文件中的参数作为默认参数,不会询问用户的选择。它会将新添
加的内核选项设置为默认值,也不会提醒用户。它会将旧的 .config 文件重命名为 .config.old 文件,以
备后用.

b. make olddefconfig 的作用和 make oldconfig 类似,但是 make oldconfig 会以交互方式询问用户对
新配置的选择,而 make olddefconfig 不会.

c. make menuconfig 是基于 Ncurses 图形界面去配置 .config 文件,它可以让用户在一个菜单式的界面
中选择和修改内核的各种选项,也可以查看选项的帮助信息,它是一种比较方便和直观的配置方式

  1. 编译内核:
make -j6 ARCH=arm64 'CROSS_COMPILE=ccache aarch64-none-linux-gnu-' 
LOCALVERSION=-sun50iw9 Image modules dtbs
  1. 接下来运行
make modules_install INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$PWD/_install
ARCH=arm64 'CROSS_COMPILE=ccache aarch64-none-linux-gnu-' #安装驱动
make install INSTALL_PATH=$PWD/_install/boot #安装内核

或者直接打包成deb包:

cp external/patch/misc/headers-debian-byteshift.patch /tmp
make -j6 bindeb-pkg KDEB_PKGVERSION=3.1.0 KDEB_COMPRESS=xz BRANCH=next
LOCALVERSION=-sun50iw9 KBUILD_DEBARCH=arm64 ARCH=arm64 DEBFULLNAME="Orange Pi"
CROSS_COMPILE="ccache aarch64-none-linux-gnu-”

a.bindeb-pkg 是指定 make 命令使用 Debian 的格式来打包内核,生成一个 .deb 文件,这样可以方便
地在 Debian 系的系统中安装内核 。

b. KDEB_PKGVERSION=3.1.0 是指定打包的内核的版本号为 3.1.0,这个版本号可以自定义,也可以使用内核的默认版本号 。

c. KDEB_COMPRESS=xz 是指定打包的内核使用 xz 的压缩格式,这样可以减少打包文件的大小,也可以使用其他的压缩格式,如 gzip, bzip2 等 。

d. BRANCH=next 是指定编译的内核的分支为 next

c. LOCALVERSION=-sun50iw9 是指定编译的内核的本地版本为 -sun50iw9

d. KBUILD_DEBARCH=arm64 是指定打包的内核的架构为 arm64,这个架构是用来表示 64 位的 ARM
处理器。

e. ARCH=arm64 是指定编译的内核的架构为 arm64 。

f. DEBFULLNAME=Orange Pi 是指定打包的姓名为 Orange Pi。

四、Linux根文件系统

根文件系统也叫roofs,Linux 根文件系统是指整个文件系统的最顶层,以 “/” 来表示。它是内核启动时
所挂载的第一个文件系统,包含了系统运行所必需的目录和文件:

  1. /bin目录下存放着系统需要的可执行文件比如ls、mv、cp等命令,现在新根文件系统的像ubuntu等
    debian系的rootfs, 基本都是软链接到/usr/bin目录下
  2. /dev目录下面存放着的文件都与设备有关,此目录下的文件都是设备文件。
  3. /etc目录存放Linux下所必须的库文件
  4. /mnt目录, 临时挂载目录,可以在从目录下创建空的子目录
  5. /procsys 目录, Linux虚拟文件系统,由内核生成各类节点
  6. /sbin 一般软链到/usr/sbin下,一般存放一些root权限才能执行的命令
  7. /lib 软链接到/usr/lib目录,用于存放库文件
  8. /usr/ 存放lib bin sbin目录, 另外的share目录里面存放的是共享、只读的程序和数据
  9. /tmp/存放临时文件或目录
  10. /root目录 系统管理员(root)的主文件夹,即是根用户的目录,与此对应,普通用户的目录
    是/home下的某个子目录。
  11. /var目录、与/usr目录相反,/var目录中存放可变的数据,比如log文件\临时文件等。
  12. /home目录,系统默认的用户文件夹,它是可选的,对于每个普通用户,在/home目录下都有一个
    以用户名命名的子目录,里面存放用户相关的配置文件。

根文件系统的编译详见(《OrangePi_Zero2_H616用户手册v4.0》 6.5. 编译 rootfs )

  • 19
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
编译 Linux 内核需要以下步骤: 1. 获取 Linux 内核源代码。你可以从官方网站或 GitHub 上下载最新的内核源代码。 2. 安装交叉编译工具链。如果你的开发环境是 x86 架构的,你需要安装交叉编译工具链来编译适用于 ARM 架构的内核。你可以使用 apt-get 命令或其他包管理器来安装工具链。例如,在 Ubuntu 或 Debian 上,你可以使用以下命令来安装: ``` sudo apt-get install gcc-arm-linux-gnueabihf ``` 3. 配置内核。进入内核源代码目录,使用以下命令来配置内核: ``` make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- orangepi_zero2_defconfig ``` 这将使用默认配置文件来配置内核。 4. 编译内核。使用以下命令来编译内核: ``` make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage dtbs modules ``` 这将编译内核镜像、设备树和内核模块。 5. 安装内核。将编译好的内核镜像和设备树文件复制到 SD 卡的 boot 分区中。例如,在 Ubuntu 或 Debian 上,你可以使用以下命令来安装: ``` sudo cp arch/arm/boot/zImage /media/boot/ sudo cp arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero2.dtb /media/boot/ ``` 6. 配置引导加载程序。编辑 SD 卡的 boot 分区中的 boot.cmd 文件,并添加以下内容: ``` setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p2 rootwait panic=10 fatload mmc 0:1 ${kernel_addr_r} zImage fatload mmc 0:1 ${fdt_addr_r} sun8i-h2-plus-orangepi-zero2.dtb bootz ${kernel_addr_r} - ${fdt_addr_r} ``` 这将配置引导加载程序以加载内核镜像和设备树,并指定内核参数。 7. 生成引导加载程序镜像。使用以下命令来生成引导加载程序镜像: ``` mkimage -C none -A arm -T script -d boot.cmd boot.scr ``` 这将生成一个名为 boot.scr 的文件,它是引导加载程序镜像。 8. 将引导加载程序镜像复制到 SD 卡的 boot 分区中: ``` sudo cp boot.scr /media/boot/ ``` 9. 将 SD 卡插入 Orange Pi Zero 2 开发板,并启动板子。如果一切正常,你应该看到内核启动信息在串口终端中输出。 注意:这只是一个简单的指南,实际的操作可能会因环境和设备而有所不同。请确保你熟悉 Linux 内核编译Orange Pi Zero 2 开发板的使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咖喱年糕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值