Single

H618 Kernel移植记录

前言

这个系列是记录一下自己做BSP,我准备先让系统启动起来,最后再调驱动。
前面尝试着编译了u-boot,接下来就是编译kernel了

下载并编译kernel

和u-boot一样,kernel用opi现成的:
https://github.com/orangepi-xunlong/linux-orangepi的orange-pi-6.1-sun50iw9分支

cd BPI-H618-BSP
git clone -c http.proxy="http://10.10.10.105:2345" -b orange-pi-6.1-sun50iw9 https://github.com/orangepi-xunlong/linux-orangepi Kernel

复制一份dts,dtb(这里挖个坑,这里dtb不知道怎么生成的先复制现成的吧)
2023-08-08更新:找到在哪里生成的了在dts所在的Makefile文件内编辑,复制一份dts文件,

//2023-08-08更新:这个不要cp ~/Qubot-H618-BSP/Kernel/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero3.dtb ~/Qubot-H618-BSP/Kernel/arch/arm64/boot/dts/allwinner/sun50i-h616-qubot-m2h.dtb
cp ~/Qubot-H618-BSP/Kernel/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero3.dts ~/Qubot-H618-BSP/Kernel/arch/arm64/boot/dts/allwinner/sun50i-h616-qubot-m2h.dts

修改~/Qubot-H618-BSP/Kernel/arch/arm64/boot/dts/allwinner/Makefile,把里面的opi的改成自己的dts名字,注意结尾时dtb,因为这里是生成dtb文件

dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-qubot-m2h.dtb

配置,使用默认defconfig就可以了,H618是arm64,听说arm64的配置更简单,以前arm架构的每个芯片都一个配置,但是在arm64里面好像不用

ARM64架构下的源码目录和ARM架构下的源码目录有很大不同,在ARM目录下各个半导体厂商都会编写自己芯片的默认配置文件保存在arch/arm/configs目录下面,但是在ARM64架构下只有一个默认配置文件,因为ARM64是较新的架构,所以这种目录安排也体现了这几年Linux内核的发展风格逐渐趋于简约. defconfig将必要的模块编译进入到内核中,其他不必须的模块编译成模块. (如过在商业应用的时候还是需要编写自己的配置文件来定制自己的内核)

进到kernel,并配置版型

cd Kernel
make ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu- defconfig

编译

make ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu-

执行内核的编译和链接过程,并且在arch/arm64/boot目录下生成Image文件这个文件就是内核的二进制镜像文件. 内核的make过程将各个.o和.a文件链接后产生的文件是vmLinux,这个文件因为是链接后的第一产物所以还保留这ELF格式的各种段, 和在上篇的u-boot源码编译链接后在源码根目录下产生的名为u-boot的文件一样都是ELF格式. 但是因为无论是u-boot还是Linux内核都是直面底层硬件的软件程序, 而ELF格式的可执行文件需要在操作系统提供的虚拟化环境下才能被解释和运行,故make过程最后还需将vmLinux的代码段(.text)段单独抽离出来生成Image, 在编译ARM时生成的zImage又是Image经过gzip压缩后的结果. 启动zImage需要uboot的bootz的支持. 将这个Image拷贝到上篇制作的SD卡中的fat32文件系统中, 再将/arch/arm64/boot/dts/allwiner/中的zero2文件拷贝到那里.

从 TF 卡启动 SPL、U-Boot、Kernel

制作启动盘

首先格式化并创建分区

# 进入fdisk
fdisk /dev/sdd
# 删除所有分区
d
# 新建分区 (扇区为单位,前面空开20MB用于存放uboot,制作128MB的分区)
n
p
回车
40960
303104
w

格式化成fat格式

sudo mkfs.fat /dev/sdd1

把uboot写到8KB的位置(换虚拟机了,可能截图路径和这里的不一样)

sudo dd if=./u-boot/u-boot-sunxi-with-spl.bin of=/dev/sdd bs=8K seek=1

一般都会自动挂载,要是没挂载可以手动挂载

sudo mount /dev/sdd1 /mnt/

复制内核以及设备树到挂载的分区

sudo cp ~/BPI-H618-BSP/Kernel/arch/arm64/boot/Image /mnt/
sudo cp ~/BPI-H618-BSP/Kernel/arch/arm64/boot/dts/allwinner/sun50i-h616-qubot-m2h.dtb /mnt/

取消挂载

sudo umount /mnt

从tf卡启动内核

将卡插到板子上,可以看到,还是和上次那样,卡在了u-boot了

这时候不要慌,我们需要手动挂载内核和dtb文件

fatload mmc 0:1 0x40200000 Image
fatload mmc 0:1 0x4fa00000 sun50i-h618-qubot-m2h.dtb


挂载好了之后,可以手动启动了:
设置环境变量:

setenv bootargs 'console=ttyS0,115200 earlycon'
//console=ttyS0,115200:指定控制台输出设备为串行终端 ttyS0,并设置波特率为 115200,用于在启动过程中输出内核和系统消息。
//earlycon:启用早期的控制台输出,在内核初始化早期阶段就开始输出消息。这在一些情况下能够更早地获取系统启动信息。

手动启动:

booti 0x40200000 - 0x4fa00000
//booti: 这是 U-Boot 命令,用于启动 ARM64 内核image。

//0x40200000: 这是内核映像在内存中的加载地址。这是你要求 U-Boot 将内核映像加载到的地址。

//-: 这个减号表示分隔符,表明加载地址和入口地址之间的分隔。

//0x4fa00000: 这是内核的入口地址。一旦内核加载到了加载地址,就会跳转到这个地址开始执行内核代码。

输入完成之后,可以看到,板子成功进入到了kernel,并卡在了rootfs

但是如果这样的话,重启就没了,所以需要设置一下变量

设置串口和波特率
setenv bootargs 'console=ttyS0,115200'
设置加载image和dtb,并从指定位置启动
setenv bootcmd 'fatload mmc 0:1 0x40200000 Image;fatload mmc 0:1 0x4fa00000 sun50i-h618-qubot-m2h.dtb;booti 0x40200000 - 0x4fa00000'
//保存变量
saveenv

保存之后,每次启动都会自动加载kernel了

启动结束,卡在了找不到rootfs

暂无评论

发表评论