目录
10.rk3399_loader_v1.27.126.bin
0.前言
作为一个刚刚接触Linux的小白,我手中恰好有一块Firefly RK3399开发板。之前,我成功移植uboot和根文件系统,现在移植linux 5.2.8,来更深入地了解嵌入式系统的制作流程。
移植linux 5.2.8,我主要参考了 @大奥特曼打小怪兽博主所撰写的精彩帖子。对于RK3399芯片的相关原理,我也会在这些博主的文章中深入学习。他们的文章不仅内容丰富,而且具有很高的参考价值。
在此,我主要是想记录下自己的学习过程,以便日后回顾,同时也希望这些记录能对其他学习者提供一定的参考和帮助。
主要参考帖子的链接:
Rockchip RK3399 - 移植linux 5.2.8 - 大奥特曼打小怪兽 - 博客园 (cnblogs.com)
1.源码下载
下载linux-5.2.8
版本并解压,执行如下命令:
wget http://ftp.sjtu.edu.cn/sites/ftp.kernel.org/pub/linux/kernel/v5.x/linux-5.2.8.tar.gz
tar -xvf linux-5.2.8.tar.gz
配置Makefile,修改顶层的Makefile,打开Makefile文件,找到下面语句:
ARCH ?= $(SUBARCH)
修改为:
ARCH ?= arm64
CROSS_COMPILE ?= aarch64-none-linux-gnu-
其中,ARCH是指定目标平台为 arm64 , CROSS_COMPILE 是指定交叉编译器,这里指定的是系统默认的交叉编译器,如要使用其它的,则要把编译器的全路径在这里写出。
2.内核defconfig配置
单板的默认配置文件在arch/arm64/configs目录下:
make defconfig
错误1:
在修改顶层的Makefile时,在arm后面多打了一个空格导致
ARCH ?= arm64
CROSS_COMPILE ?= arm-linux-gnueabihf-
错误2:
sudo apt-get install bison
该错误的原因是缺少某些需要的库,需要安装一下需要的库就行了
错误3:
sudo visudo /etc/sudoers
当你使用sudo去执行一个程序时,处于安全的考虑,这个程序将在一个新的、最小化的环境中执行,也就是说,诸如PATH这样的环境变量,在sudo命令下已经被重置成默认状态了。所以当一个刚初始化的PATH变量中不包含你所要运行的程序所在的目录,用sudo去执行,你就会得到"command not found"的错误提示。
要想改变PATH在sudo会话中的初始值,用文本编辑器打开/etc/sudoers文件,找到"secure_path"一行,当你执行sudo 命令时,"secure_path"中包含的路径将被当做默认PATH变量使用。
添加所需要的路径(如aarch64-linux-gnu-gcc交叉编译器所在路径)到"secure_path"下,问题就将迎刃而解。
Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/arm/arm-gnu-toolchain-13.2.Rel1-x86_64-aarch64-none-linux-gnu/bin
在移植uboot时,编译TF-A获取bl31.elf发生错误,这个问题应该可以按照这个解决了。
3.内核裁切
通过make menuconfig配置内核支持的功能:
make menuconfig
问题1:
由于自己的窗口界面太小,放大自己的窗口就可以正确显示了
3.1支持NFS
文件系统
使用NFS
作为根文件系统,因为文件系统在宿主机中,这样在修改文件系统就非常方便,主要用于开发阶段使用。
File systems --->
[*] Network File Systems --->
<*> NFS client support
<*> NFS client support for NFS version 2
<*> NFS client support for NFS version 3
<*> NFS client support for NFS version 4
[*] Root file system on NFS
3.2配置uevent helper
配置Support for uevent helper
;
Device Drivers --->
Generic Driver Options --->
[*] Support for uevent helper
(/sbin/mdev) path to uevent helper (NEW)
该选项的作用是启用uevent helper
程序的支持。uevent
是内核与用户空间之间通信的一种方式,当内核检测到新的设备时,会生成一个uevent
来通知用户空间,使得用户空间能够及时响应设备插拔事件,并做出相应的处理。其中, uevent helper
程序就是在接收到uevent
后执行的用户空间程序,用来完成设备的热插拔处理。
在内核中,CONFIG_UEVENT_HELPER=y
的设定可以确保uevent helper
程序能够被编译到内核中,从而能够正常地接收并响应uevent
事件。
path to uevent helper
配置为/sbin/mdev
;即指定uevent helper
程序为/sbin/mdev
。
3.3支持RAM
块设备
如果我们需要使用ramdisk
根文件系统,就需要配置RAM
块设备驱动,否者不用配置这个。
ram disk
顾名思义,内存磁盘。我们平常接触的一些存储介质,如:Nor Flash
、Nand Flash
、eMMC
、ufs、以及机械硬盘固态硬盘等,都是用来存储数据的,同理内存也是可以当成磁盘来存储数据的,唯一不同的就是ram
是掉电不保存的,而前面提到的那些存储介质掉电都是保存数据的。
我们都知道,在linux
中,上面介绍的Flash
这些存储介质,都是需要有对应的驱动,注册成块设备。并向上层提供接口。如Nor
、Nand
等都抽象成mtdblock
块设备。
同理,linux
中的ram disk
意思就是拿出ram
中的一部分大小,用对应的驱动注册层块设备,提供给上层调用。一般的ram disk
注册成的块设备,在文件系统中设备节点体现为/dev/ramx
。
我们需要配置内核支持ramdisk
:
General setup --->
[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
这里的意思是配置内核初始化时,去寻找initramfs
和initrd
,initrd
就是我们的ramdisk
文件系统,至于initramfs
,是一个可以编译进内核的根文件映像。
Device Drivers --->
[*] Block devices --->
<*> RAM block device support
(1) Default number of RAM disks
(327680) Default RAM disk size (kbytes)
勾选第一项RAM block device support
,才会出来第二项和第三项的选项;
- 第一项的意思是内核支持
ram disk
块设备驱动; - 第二项是注册的块设备数量,内核默认是
16
,我这里就写了1
,内核启动后会有/dev/ram0
块设备节点,配置16
则会有/dev/ram0~ram15
; - 第三项的意思是
ram disk
占得最大内存,这里我写的是320M
,一般来说可以写的再小点。实际在使用/dev/ramx
设备时,并不是一下子就占系统64M
内存,而是根据实际使用情况而分配的;
3.4支持ext4
文件系统
由于后面我们会制作ext4
类型的根文件系统,因此需要勾选对ext4
文件系统格式的支持,内核默认已经勾选了。
File systems --->
-*- The Extended 4 (ext4) filesystem
[*] Ext4 POSIX Access Control Lists
[ ] Ext4 Security Labels
[ ] Ext4 debugging support
3.5配置DRM
驱动
DRM
,全称Direct Rending Manger
。是目前Linux
主流的图形显示框架。配置这个的目的是为了在移植了带有桌面的ubuntu
根文件系统后,通过显示器来显示ubuntu
桌面;
Device Drivers --->
Graphics support --->
[*] Direct Rendering Manager (XFree86 4.1.0 and higher DRI support) --->
[*] DRM Support for Rockchip
3.6 配置有线网卡驱动
RK3399
内置了以太网控制器,所以只要搭配一颗以太网PHY
芯片就可以实现以太网功能。这里我使用的NanoPC-T4
开发板搭载的以太网PHY
芯片型号为RTL8211E-VB-CG
,是Realtek
瑞昱推出的一款高集成的网络接收PHY
芯片,它符合10Base-T
,100Base-TX
和1000Base-T IEEE802.3
标准,该芯片在网络通信中属于物理层,用于MAC
与PHY
之间的数据通信。
10/100M
以太网PHY
和MAC
之间的接口主要有MII
和RMII
,而10/100/1000M
以太网PHY
和MAC
之间的接口主要有RGMII
。而RK3399
对RMII
、RGMII
接口均支持,也就是说RK3399
支持100M
网卡、1000M
网卡。
因此我们需要配置:
Device Drivers --->
[*] Network device support --->
[*] Ethernet driver support --->
[*] STMicroelectronics 10/100/1000/EQOS Ethernet driver
[*] STMMAC Platform bus support
[*] Rockchip dwmac support
3.7屏蔽开机logo
屏蔽内核启动开机logo
:
Device Drivers --->
Graphics support --->
[] Bootup logo --->
3.8配置支持SquashFS文件系统
File systems --->
-*- Miscellaneous filesystems
<*> SquashFS 4.0 - Squashed file system support
[*] Squashfs XATTR support
[*] Include support for ZLIB compressed file systems
[*] Include support for LZ4 compressed file systems
[*] Include support for LZO compressed file systems
[*] Include support for XZ compressed file systems
配置这个的目的是后面移植的ubuntu根文件系统需要使用。
保存配置
保存配置为rk3399_defconfig
存档:
mv rk3399_defconfig ./arch/arm64/configs/
重新配置内核:
make rk3399_defconfig
4.编译内核
在linux内核根目录下执行如下命令:
make -j8
错误1:
发现是由于缺少libssl-dev,其中的libraries, header files and manpages,是openssl的一部分。
sudo apt-get install libssl-dev
make -j8
编译完成,在arch/arm64/boot/文件夹下生成Image镜像文件,以及设备树dst/rockchip/xxx.dtb文件。
5.编译dts
如果需要单独编译设备树,在linux
内核根目录执行如下命令:
make arch/arm64/boot/dts/rockchip/rk3399-firefly.dts dtbs V=1
即可把arch/arm64/boot/dts/rockchip
里的dts
文件编译成dtb
文件。
6.内核镜像文件介绍
linux
内核常用的镜像文件格式有以下几种:
vmlinux
:linux
内核编译出来的原始的内核文件,elf
格式。该文件包含了符号表、重定位等信息,可以用来调试,但不能直接引导linux
系统启动;可以使用arm-linx-readelf -h vmlinux
查看文件信息;Image
:linux
内核编译时,使用arm-linux-objcopy
处理vmlinux
后生成的二进制文件。该文件是raw binary
二进制文件,bin
文件是将elf
文件中的代码段,数据段,还有一些自定义的段抽取出来做成的一个内存的镜像,可直接引导linux
系统启动;Image.gz
:使用gzip
压缩Image
后得到的压缩文件;zImage
:首先将Image.gz
文件开头嵌入gzip
解压缩代码,然后编译得到elf
格式文件arch/arm/boot/compressed/vmlinux
,最后使用arm-linux-objcopy
命令对其处理生成的linux
内核镜像;uImage
:uImage
又分为两种Legacy uImage
和FIT uImage
。以Legacy uImage
为例,其在zImage
前面增加一个64
字节的头,描述镜像文件类型,加载位置,大小等信息,比如我们熟悉的Mini2440
使用的就是这种;
下图展示了不同类型的linux镜像生成过程:
7.启动命令
7.1boot_fit
启动方式
boot_fit
启动方式使用的内核镜像为FIT uImage。
需要更改支持从fit
启动,进行如下配置:
(1) 取消CONFIG_ROCKCHIP_RESOURCE_IMAGE
配置,不使用Rockchip resource
镜像; 配置ROCKCHIP_FIT_IMAGE
,即使用fit
镜像;
ARM architecture --->
[ ] Enable support for rockchip resource image
[*] Enable support for FIT image
(2) 配置CONFIG_CMD_BOOT_FIT
,CONFIG_CMD_BOOT_FIT
依赖ROCKCHIP_FIT_IMAGE
:
Command line interface --->
Device access commands --->
-*- boot_fit
7.2distro boot
启动方式
distro boot
启动机制会从我们的eMMC
中boot
分区加载内核镜像,然后启动内核,因此需要确保GPT
分区表没有问题,不然uboot
是无法找到boot
分区的内核镜像的。
而根路径的挂载是由内核完成的,内核通过启动命令中配置的root=PARTUUID=B921B045-1D
找到根文件系统所在的分区(块设备号为179:5
、即/dev/mmcblk0p5
),然后将根路径挂载到/dev/mmcblk0p5
设备节点。
8.distro boot
启动内核镜像制作
Rockchp
官方uboot
给出的使用教程就是使用distro boot
方式启动内核,其需要我们制作一个包含内核镜像和设备树的启动分区。
创建一个名为boot
的文件夹:
mkdir boot
然后,将设备树二进制文件复制到该文件夹中,这里我们和uboot
移植一样,选择设备树文件rk3399-firefly.dtb
:
cp arch/arm64/boot/dts/rockchip/rk3399-firefly.dtb boot/rk3399.dtb
接着,将内核镜像复制到该文件夹中:
cp arch/arm64/boot/Image boot/
为了实现distro
引导,我们需要在启动分区中添加extlinux
引导程序以及相应的配置文件。
我们需要创建一个名为extlinux
的文件夹,在其中创建一个名为extlinux.conf的文件:
mkdir boot/extlinux
touch boot/extlinux/extlinux.conf
在所有这些文件都准备好之后,boot
文件夹结构如下:
boot
├── extlinux
│ └── extlinux.conf
├── Image
└── rk3399-evb.dtb
在extlinux.conf
文件中编写配置信息,指定内核镜像和设备树的路径,以及其它启动参数。配置文件内容如下:
label rockchip-kernel-5.2.8
kernel /Image
fdt /rk3399.dtb
append earlycon=uart8250,mmio32,0xff1a0000 console=ttyS2,1500000n8 root=PARTUUID=B921B045-1D rw rootwait rootfstype=ext4 init=/sbin/init
使用genext2fs
工具可以生成一个ext2
文件系统镜像文件。在使用genext2fs
命令时,需要指定生成文件系统的大小、块大小、inode
大小等参数,以及输出的镜像文件名称和所在路径。
执行以下命令,将boot
文件夹中的文件和目录打包成一个ext2
文件系统镜像:
sudo apt-get install genext2fs
genext2fs -b 32768 -B $((64*1024*1024/32768)) -d boot/ -i 8192 -U boot.img
ll boot.img
9.FIT uImage
镜像制作
因为mkimage
是根据its
文件中的描述来打包镜像生成itb
文件(FIT uImage
),所以首先需要制作一个its
文件,在its
文件中描述需要被打包的镜像,主要是kernel
镜像,dtb
文件,ramdisk
镜像。
我们创建一个kernel.its
文件,内容如下:
/*
* Simple U-Boot uImage source file containing a single kernel and FDT blob
*/
/dts-v1/;
/ {
description = "Simple image with single Linux kernel and FDT blob";
#address-cells = <1>;
images {
kernel {
description = "Vanilla Linux kernel";
data = /incbin/("arch/arm64/boot/Image.gz");
type = "kernel";
arch = "arm64";
os = "linux";
compression = "gzip";
load = <0x280000>;
entry = <0x280000>;
hash-1 {
algo = "crc32";
};
hash-2 {
algo = "sha1";
};
};
fdt {
description = "Flattened Device Tree blob";
data = /incbin/("arch/arm64/boot/dts/rockchip/rk3399-evb.dtb");
type = "flat_dt";
arch = "arm64";
compression = "none";
load = <0x8300000>;
entry = <0x8300000>;
hash-1 {
algo = "crc32";
};
hash-2 {
algo = "sha1";
};
};
ramdisk {
description = "Ramdisk for project-x";
data = /incbin/("ramdisk.gz");
type = "ramdisk";
arch = "arm64";
os = "linux";
load = <00000000>;
entry = <00000000>;
compression = "gzip";
hash-1 {
algo = "crc32";
};
};
};
configurations {
default = "conf-1";
conf-1 {
description = "Boot Linux kernel with FDT blob";
kernel = "kernel";
fdt = "fdt";
ramdisk = "ramdisk";
};
};
};
在Firefly RK3399 - busybox 1.36.0制作根文件系统-CSDN博客制作的ramdist根文件系统镜像放在内核根目录上。
FIT image
文件的编译过程很简单,这里我们需要将uboot
路径下的mkimage
工具拷贝过来,然后在命令行使用mkimage
工具编译即可:
./mkimage -f kernel.its -E kernel.itb
需要注意的是这里一定要指定-E
参数,不然image data file
就会被放到FIT结构里面。
10.rk3399_loader_v1.27.126.bin
由于SoC进入到MASKROM模式后,目标板子会运行Rockusb驱动程序。在MASKROM模式下,需要使用到DDR,因此需要下载固件进行DDR的初始化。
Rockchip rkbin项目提供了ddr.bin、usbplug.bin、miniloader.bin这三个包:
- ddr.bin:等价于我们之前说的TPL,用于初始化DDR;
- usbplug.bin:Rockusb驱动程序,用于将程序通过usb下载到eMMC;
- miniloader.bin:Rockchip修改的一个bootloader,等价于我们之前说的SPL,用于加载uboot;
我们可以在Rockchip的github上下载到Rockchip rkbin项目,如下所示:
git clone https://github.com/rockchip-linux/rkbin.git --depth 1
在rkbin目录下执行如下命令,可以将ddr.bin、usbplug.bin、miniloader.bin这三个包合并:
cd rkbin/
tools/boot_merger /work/sambashare/rk3399/rkbin/RKBOOT/RK3399MINIALL.ini
ll rk3399_loader_v1.27.126.bin
得到rk3399_loader_v1.27.126.bin。
10.烧录
10.1烧录boot.img
我们按照之前的流程得到了如下文件
idbloader.img
u-boot.itb
boot.img
kernel.itb
busybox_ext4_rootfs.img
rk3399_loader_v1.27.126.bin
我手中这块开发板基于emmc启动,按照RK官方要求将
rk3399_loader_v1.27.126.bin烧录到0x0扇区
idbloader.img烧录到emmc的0x40扇区
u-boot.itb烧录到0x4000扇区
boot.img烧录到0x8000扇区
busybox_ext4_rootfs.img烧录到0x40000扇区
烧录方法有两种,一种是基于RK的官方烧录工具AndroidTool.exe,另外一种是在开发板上直接烧写emmc。官方AndroidTool.exe是基于recovery模式实现的,板子带有recovery按键,可以使用这种方式。我用基于AndroidTool.exe烧录:
按住recovery按键上电,板子会进入recovery模式,点击执行,开始烧录。
设置GPT
分区表,重启开发板,在倒计时执行完之前,按CTRL+C
即可进入uboot
命令行。使用以下命令将分区信息写入GPT
分区表:
=> gpt write mmc 0 $partitions
Writing GPT: success!
验证GPT
分区表,使用以下命令验证GPT
分区表是否成功写入:
=> gpt verify mmc 0 $partitions
Verify GPT: success!
boot
命令启动内核,我们在uboot
命令行输入boot
命令,将会进行内核的启动,输出内容比较多:
=> boot
Card did not respond to voltage select! : -110
** Booting bootflow 'mmc@fe330000.bootdev.part_4' with extlinux
1: rockchip-kernel-5.2.8
Retrieving file: /Image
append: earlycon=uart8250,mmio32,0xff1a0000 console=ttyS2,1500000n8 root=PARTUUID=B921B045-1D rw rootwait rootfstype=ext4 init=/sbin/init
Retrieving file: /rk3399.dtb
## Flattened Device Tree blob at 01f00000
Booting using the fdt blob at 0x1f00000
Working FDT set to 1f00000
Loading Device Tree to 000000007cef1000, end 000000007cf01bd2 ... OK
Working FDT set to 7cef1000
Starting kernel ...
[ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[ 0.000000] Linux version 5.2.8 (root@lyx-virtual-machine) (gcc version 13.2.1 20231009 (Arm GNU Toolchain 13.2.rel1 (Build arm-13.7))) #1 SMP PREEMPT Wed Apr 24 00:35:05 CST 2024
[ 0.000000] Machine model: Firefly-RK3399 Board
[ 0.000000] earlycon: uart8250 at MMIO32 0x00000000ff1a0000 (options '')
[ 0.000000] printk: bootconsole [uart8250] enabled
[ 0.000000] efi: Getting EFI parameters from FDT:
[ 0.000000] efi: UEFI not found.
[ 0.000000] cma: Reserved 32 MiB at 0x000000007e000000
[ 0.000000] NUMA: No NUMA configuration found
[ 0.000000] NUMA: Faking a node at [mem 0x0000000000200000-0x000000007fffffff]
[ 0.000000] NUMA: NODE_DATA [mem 0x7dbb0840-0x7dbb1fff]
[ 0.000000] Zone ranges:
[ 0.000000] DMA32 [mem 0x0000000000200000-0x000000007fffffff]
[ 0.000000] Normal empty
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000000200000-0x000000007fffffff]
[ 0.000000] Initmem setup node 0 [mem 0x0000000000200000-0x000000007fffffff]
[ 0.000000] psci: probing for conduit method from DT.
[ 0.000000] psci: PSCIv1.0 detected in firmware.
[ 0.000000] psci: Using standard PSCI v0.2 function IDs
[ 0.000000] psci: MIGRATE_INFO_TYPE not supported.
[ 0.000000] psci: SMC Calling Convention v1.0
[ 0.000000] percpu: Embedded 23 pages/cpu s57048 r8192 d28968 u94208
[ 0.000000] Detected VIPT I-cache on CPU0
[ 0.000000] CPU features: detected: ARM erratum 845719
[ 0.000000] CPU features: detected: GIC system register CPU interface
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 515592
[ 0.000000] Policy zone: DMA32
[ 0.000000] Kernel command line: earlycon=uart8250,mmio32,0xff1a0000 console=ttyS2,1500000n8 root=PARTUUID=B921B045-1D rw rootwait rootfstype=ext4 init=/sbin/init
[ 0.000000] Memory: 2001632K/2095104K available (11900K kernel code, 1776K rwdata, 6116K rodata, 1472K init, 446K bss, 60704K reserved, 32768K cma-reserved)
[ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=6, Nodes=1
[ 0.000000] rcu: Preemptible hierarchical RCU implementation.
[ 0.000000] rcu: RCU restricting CPUs from NR_CPUS=256 to nr_cpu_ids=6.
[ 0.000000] Tasks RCU enabled.
[ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
[ 0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=6
[ 0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[ 0.000000] GICv3: GIC: Using split EOI/Deactivate mode
[ 0.000000] GICv3: Distributor has no Range Selector support
[ 0.000000] GICv3: no VLPI support, no direct LPI support
[ 0.000000] GICv3: CPU0: found redistributor 0 region 0:0x00000000fef00000
[ 0.000000] ITS [mem 0xfee20000-0xfee3ffff]
[ 0.000000] ITS@0x00000000fee20000: allocated 65536 Devices @7d480000 (flat, esz 8, psz 64K, shr 0)
[ 0.000000] ITS: using cache flushing for cmd queue
[ 0.000000] GICv3: using LPI property table @0x000000007d440000
[ 0.000000] GIC: using cache flushing for LPI property table
[ 0.000000] GICv3: CPU0: using allocated LPI pending table @0x000000007d450000
[ 0.000000] GICv3: GIC: PPI partition interrupt-partition-0[0] { /cpus/cpu@0[0] /cpus/cpu@1[1] /cpus/cpu@2[2] /cpus/cpu@3[3] }
[ 0.000000] GICv3: GIC: PPI partition interrupt-partition-1[1] { /cpus/cpu@100[4] /cpus/cpu@101[5] }
[ 0.000000] random: get_random_bytes called from start_kernel+0x2ac/0x444 with crng_init=0
[ 0.000000] rockchip_mmc_get_phase: invalid clk rate
[ 0.000000] rockchip_mmc_get_phase: invalid clk rate
[ 0.000000] rockchip_mmc_get_phase: invalid clk rate
[ 0.000000] rockchip_mmc_get_phase: invalid clk rate
[ 0.000000] arch_timer: cp15 timer(s) running at 24.00MHz (phys).
[ 0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x588fe9dc0, max_idle_ns: 440795202592 ns
[ 0.000007] sched_clock: 56 bits at 24MHz, resolution 41ns, wraps every 4398046511097ns
[ 0.011045] Console: colour dummy device 80x25
[ 0.016048] Calibrating delay loop (skipped), value calculated using timer frequency.. 48.00 BogoMIPS (lpj=96000)
[ 0.027336] pid_max: default: 32768 minimum: 301
[ 0.032517] LSM: Security Framework initializing
[ 0.038706] Dentry cache hash table entries: 262144 (order: 9, 2097152 bytes)
[ 0.047107] Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes)
[ 0.054905] Mount-cache hash table entries: 4096 (order: 3, 32768 bytes)
[ 0.062293] Mountpoint-cache hash table entries: 4096 (order: 3, 32768 bytes)
[ 0.094257] ASID allocator initialised with 32768 entries
[ 0.108234] rcu: Hierarchical SRCU implementation.
[ 0.121636] Platform MSI: interrupt-controller@fee20000 domain created
[ 0.129196] PCI/MSI: /interrupt-controller@fee00000/interrupt-controller@fee20000 domain created
[ 0.143684] EFI services will not be available.
[ 0.156704] smp: Bringing up secondary CPUs ...
[ 0.193911] Detected VIPT I-cache on CPU1
[ 0.193947] GICv3: CPU1: found redistributor 1 region 0:0x00000000fef20000
[ 0.193963] GICv3: CPU1: using allocated LPI pending table @0x000000007d460000
[ 0.194007] CPU1: Booted secondary processor 0x0000000001 [0x410fd034]
[ 0.225980] Detected VIPT I-cache on CPU2
[ 0.226007] GICv3: CPU2: found redistributor 2 region 0:0x00000000fef40000
[ 0.226021] GICv3: CPU2: using allocated LPI pending table @0x000000007d470000
[ 0.226052] CPU2: Booted secondary processor 0x0000000002 [0x410fd034]
[ 0.258076] Detected VIPT I-cache on CPU3
[ 0.258102] GICv3: CPU3: found redistributor 3 region 0:0x00000000fef60000
[ 0.258115] GICv3: CPU3: using allocated LPI pending table @0x000000007d500000
[ 0.258144] CPU3: Booted secondary processor 0x0000000003 [0x410fd034]
[ 1.299486] CPU4: failed to come online
[ 1.384857] CPU4: failed in unknown state : 0x0
[ 2.455357] CPU5: failed to come online
[ 2.459578] CPU5: failed in unknown state : 0x0
[ 2.464629] smp: Brought up 1 node, 4 CPUs
[ 2.469154] SMP: Total of 4 processors activated.
[ 2.474332] CPU features: detected: 32-bit EL0 Support
[ 2.480002] CPU features: detected: CRC32 instructions
[ 2.486393] CPU: All CPU(s) started at EL2
[ 2.490940] alternatives: patching kernel code
[ 2.498162] devtmpfs: initialized
[ 2.517020] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[ 2.527784] futex hash table entries: 2048 (order: 5, 131072 bytes)
[ 2.536615] pinctrl core: initialized pinctrl subsystem
[ 2.545048] DMI not present or invalid.
[ 2.549994] NET: Registered protocol family 16
[ 2.555627] audit: initializing netlink subsys (disabled)
[ 2.561724] audit: type=2000 audit(2.460:1): state=initialized audit_enabled=0 res=1
[ 2.570291] cpuidle: using governor menu
[ 2.575087] hw-breakpoint: found 6 breakpoint and 4 watchpoint registers.
[ 2.584251] DMA: preallocated 256 KiB pool for atomic allocations
[ 2.594465] Serial: AMBA PL011 UART driver
[ 2.661689] HugeTLB registered 1.00 GiB page size, pre-allocated 0 pages
[ 2.669087] HugeTLB registered 32.0 MiB page size, pre-allocated 0 pages
[ 2.676459] HugeTLB registered 2.00 MiB page size, pre-allocated 0 pages
[ 2.683827] HugeTLB registered 64.0 KiB page size, pre-allocated 0 pages
[ 2.693864] cryptd: max_cpu_qlen set to 1000
[ 2.704996] ACPI: Interpreter disabled.
[ 2.713144] vcc3v3_pcie: supplied by dc_12v
[ 2.718974] vcc_sys: supplied by dc_12v
[ 2.727020] vgaarb: loaded
[ 2.730430] SCSI subsystem initialized
[ 2.735319] usbcore: registered new interface driver usbfs
[ 2.741514] usbcore: registered new interface driver hub
[ 2.747481] usbcore: registered new device driver usb
[ 2.755109] pps_core: LinuxPPS API ver. 1 registered
[ 2.760805] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 2.770913] PTP clock support registered
[ 2.775582] EDAC MC: Ver: 3.0.0
[ 2.781498] FPGA manager framework
[ 2.785461] Advanced Linux Sound Architecture Driver Initialized.
[ 2.793097] clocksource: Switched to clocksource arch_sys_counter
[ 2.800068] VFS: Disk quotas dquot_6.6.0
[ 2.804458] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
[ 2.812334] pnp: PnP ACPI: disabled
[ 2.826221] NET: Registered protocol family 2
[ 2.831509] tcp_listen_portaddr_hash hash table entries: 1024 (order: 2, 16384 bytes)
[ 2.840234] TCP established hash table entries: 16384 (order: 5, 131072 bytes)
[ 2.848455] TCP bind hash table entries: 16384 (order: 6, 262144 bytes)
[ 2.856095] TCP: Hash tables configured (established 16384 bind 16384)
[ 2.863413] UDP hash table entries: 1024 (order: 3, 32768 bytes)
[ 2.870109] UDP-Lite hash table entries: 1024 (order: 3, 32768 bytes)
[ 2.877518] NET: Registered protocol family 1
[ 2.882814] RPC: Registered named UNIX socket transport module.
[ 2.890192] RPC: Registered udp transport module.
[ 2.895371] RPC: Registered tcp transport module.
[ 2.900712] RPC: Registered tcp NFSv4.1 backchannel transport module.
[ 2.907804] PCI: CLS 0 bytes, default 64
[ 2.913011] hw perfevents: enabled with armv8_cortex_a53 PMU driver, 7 counters available
[ 2.922166] hw perfevents: /pmu_a72: failed to probe PMU!
[ 2.928124] hw perfevents: /pmu_a72: failed to register PMU devices!
[ 2.935634] kvm [1]: IPA Size Limit: 40bits
[ 2.941235] kvm [1]: vgic-v2@fff20000
[ 2.945365] kvm [1]: GIC system register CPU interface enabled
[ 2.951901] kvm [1]: vgic interrupt IRQ10
[ 2.956470] kvm [1]: Hyp mode initialized successfully
[ 2.971362] Initialise system trusted keyrings
[ 2.976430] workingset: timestamp_bits=44 max_order=19 bucket_order=0
[ 2.994760] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[ 3.002270] NFS: Registering the id_resolver key type
[ 3.007862] Key type id_resolver registered
[ 3.012465] Key type id_legacy registered
[ 3.016887] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
[ 3.024482] 9p: Installing v9fs 9p2000 file system support
[ 3.032594] Key type asymmetric registered
[ 3.037111] Asymmetric key parser 'x509' registered
[ 3.042538] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 245)
[ 3.050675] io scheduler mq-deadline registered
[ 3.055657] io scheduler kyber registered
[ 3.068509] vcc5v0_host: supplied by vcc_sys
[ 3.095971] EINJ: ACPI disabled.
[ 3.112143] dma-pl330 ff6d0000.dma-controller: Loaded driver for PL330 DMAC-241330
[ 3.120499] dma-pl330 ff6d0000.dma-controller: DBUFF-32x8bytes Num_Chans-6 Num_Peri-12 Num_Events-12
[ 3.132835] dma-pl330 ff6e0000.dma-controller: Loaded driver for PL330 DMAC-241330
[ 3.141200] dma-pl330 ff6e0000.dma-controller: DBUFF-128x8bytes Num_Chans-8 Num_Peri-20 Num_Events-16
[ 3.160314] pwm-regulator: supplied by regulator-dummy
[ 3.166281] vcc3v3_sys: supplied by vcc_sys
[ 3.178571] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
[ 3.188792] ff180000.serial: ttyS0 at MMIO 0xff180000 (irq = 38, base_baud = 1500000) is a 16550A
[ 3.199654] ff1a0000.serial: ttyS2 at MMIO 0xff1a0000 (irq = 39, base_baud = 1500000) is a 16550A
▒^<9▒#▒▒▒▒▒h▒▒▒▒▒▒Q▒▒cm▒▒▒\▒▒▒▒▒▒ػ▒▒▒▒i뭽▒Y▒▒ؿ▒"▒ؾ▒▒▒▒\▒▒▒8▒▒2L▒^▒▒▒▒s▒▒M>ˬ▒▒▒▒f▒▒▒b▒▒vgp▒▒▒▒Xӽ\o▒D▒▒▒▒tw▒|▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒.'▒▒▒D▒▒8▒hf▒▒▒nu▒'▒8▒▒▒▒▒▒▒▒f▒▒▒mp▒▒x{▒|vl՟ͦ▒▒vS▒8▒▒▒▒]▒ݾ▒▒&▒▒.▒▒y▒▒▒!▒▒▒▒▒▒▒n▒W▒▒4▒▒݇▒▒k▒l}<ߔ▒x▒y▒X|]▒▒▒▒▒۵l▒▒}▒_▒▒▒▒▒▒?K▒▒S▒▒▒J▒▒▒▒▒▒▒▒h▒4▒▒▒^▒l{Z▒▒V▒▒▒▒m▒▒}▒L▒▒▒|▒▒▒▒▒▒▒▒▒▒<▒▒▒▒▒v▒▒▒h▒▒▒▒▒~o▒▒▒x?▒▒▒▒▒\^▒▒▒▒'▒▒▒▒▒▒}▒▒▒Ej7▒▒▒▒9j#Ѻ▒ٟO▒▒|▒w~▒▒▒▒▒n▒▒]▒▒)▒▒Z▒▒▒▒Z▒▒▒▒_▒▒▒5(▒y▒▒]▒▒l▒▒▒▒|▒o▒▒n▒▒X▒▒▒▒a▒?▒▒|▒▒~▒▒
▒▒▒(^▒▒▒▒ͷۿ▒▒▒▒ivM▒▒}▒Ͽ?▒▒▒▒~▒▒▒▒?▒▒▒7▒▒▒▒▒7▒W▒▒&.hu▒i▒▒▒▒7▒▒ܛK▒▒
▒▒u▒▒
▒▒$▒4n▒[ͽL▒㸿▒▒▒1▒7▒[▒▒L▒▒w▒=▒n{▒O▒▒▒l▒v>g▒▒▒▒4▒؟▒
▒▒▒^▒▒▒▒n'▒o▒j▒8▒▒h▒k%▒z▒▒X▒▒▒˸p▒▒▒}:▒▒▒▒▒▒▒▒▒▒▒▒▒▒:▒
后面乱码是因为uboot和内核设置的串口波特率不一样导致乱码,不影响正常启动。
10.1.1linux
命令测试
10.1.1.1
查看块设备
查看eMMC
块设备文件:
[root@zy:/]# ls /dev/mmc* -l
brw-rw---- 1 0 0 179, 0 Jan 1 00:00 /dev/mmcblk2
brw-rw---- 1 0 0 179, 32 Jan 1 00:00 /dev/mmcblk2boot0
brw-rw---- 1 0 0 179, 64 Jan 1 00:00 /dev/mmcblk2boot1
brw-rw---- 1 0 0 179, 1 Jan 1 00:00 /dev/mmcblk2p1
brw-rw---- 1 0 0 179, 2 Jan 1 00:00 /dev/mmcblk2p2
brw-rw---- 1 0 0 179, 3 Jan 1 00:00 /dev/mmcblk2p3
brw-rw---- 1 0 0 179, 4 Jan 1 00:00 /dev/mmcblk2p4
brw-rw---- 1 0 0 179, 5 Jan 1 00:00 /dev/mmcblk2p5
crw-rw---- 1 0 0 237, 0 Jan 1 00:00 /dev/mmcblk2rpmb
这里一共有8个块设备节点和1个字符设备节点;其中:
/dev/mmcblk2
表示的是eMMC
这个设备,其主设备号为179
,次设备号为0;mmcblk2boot0
和mmcblk2boot1
对应两个Boot Area Partition
;每一个Boot Area Partition
大小都是4MB
;mmcblk2rpmb
则为RPMB Partition
;大小为4MB
;mcblk2px
为User Data Area
划分出来的SW Partitions
;实际上就是通过解析GPT
分区表创建的分区,分区编号依次为1,2,3,4,5
;
使用cat /proc/partitions
,可以查看全部分区信息:
[root@zy:/]# cat /proc/partitions
major minor #blocks name
179 0 15267840 mmcblk2
179 1 4000 mmcblk2p1
179 2 4096 mmcblk2p2
179 3 4096 mmcblk2p3
179 4 114688 mmcblk2p4
179 5 15136751 mmcblk2p5
其中blocks
表示分区的容量,每个blocks
是1KB
。这里:
mmcblk2p1
对应loader1
分区;mmcblk2p2
对应loader2
分区;mmcblk2p3
对应trust
分区;mmcblk2p4
对应boot
分区;mmcblk2p5
对应rootfs
分区;
10.1.1.2
查看磁盘空间
这里我们可以通过df -hT
查看磁盘空间信息;
[root@zy:/]# df -hT
Filesystem Type Size Used Available Use% Mounted on
/dev/root ext4 108.6M 101.8M 0 100% /
devtmpfs devtmpfs 977.4M 0 977.4M 0% /dev
tmpfs tmpfs 994.1M 0 994.1M 0% /tmp
显示内容参数说明:
Filesystem
:文件系统;Type
:文件系统类型;Size
: 分区大小;Used
: 已使用容量;Avail
: 还可以使用的容量;Use%
: 已用百分比;Mounted on
: 挂载点;
这里我们可以看到根目录挂载在/dev/root
设备节点上,文件系统格式是ext4
,然后通过查看/dev/root
链接关系,看到/dev/root
其实就是/dev/mmcblk2p5
,也就是eMMC
设备的rootfs
分区;
[root@zy:/]# readlink /dev/root
mmcblk2p5
10.1.1.3fdisk
分区命令
使用fdisk -l
查看磁盘分区情况:
[root@zy:/]# fdisk -l
Disk /dev/mmcblk2: 15 GB, 15634268160 bytes, 30535680 sectors
1908480 cylinders, 1 heads, 16 sectors/track
Units: sectors of 1 * 512 = 512 bytes
Device Boot StartCHS EndCHS StartLBA EndLBA Sectors Size Id Type
/dev/mmcblk2p1 0,0,0 0,0,0 1 30535679 30535679 14.5G ee EFI GPT
这里fdisk -l
只识别到了eMMC
设备的1号分区/dev/mmcblk2p1
,并没有识别到/dev/mmcblk2p2~5
分区,由于fdisk
不支持GPT
,所以才导致无法识别GPT
分区表。
10.1.1.4
parted
分区命令
对于GPT
格式的分区,fdisk
工具是无能为力的,同时,fdisk
工具对分区是有大小限制的,它只能划分小于2T
的磁盘。
但是现在的磁盘空间很多都已经是远远大于2T
,此时就需要另外一个磁盘管理工具parted
来完成大于2T
的磁盘分区工作。
但是不幸的是buxybox
并不支持parted
命令,这里我也懒得去整了,后面我们直接移植ubuntu
根文件系统,然后通过resize2fs
指令进行扩容。
10.2烧录kernel.itb
rk3399_loader_v1.27.126.bin烧录到0x0扇区
idbloader.img烧录到emmc的0x40扇区
u-boot.itb烧录到0x4000扇区
kernel.itb烧录到0x8000扇区
busybox_ext4_rootfs.img烧录到0x40000扇区
设置GPT
分区表,重启开发板,在倒计时执行完之前,按CTRL+C
即可进入uboot
命令行。使用以下命令将分区信息写入GPT
分区表:
=> gpt write mmc 0 $partitions
Writing GPT: success!
验证GPT
分区表,使用以下命令验证GPT
分区表是否成功写入:
=> gpt verify mmc 0 $partitions
Verify GPT: success!
设置启动命令参数:
=> setenv bootargs earlycon=uart8250,mmio32,0xff1a0000 console=ttyS2,1500000n8 root=PARTUUID=B921B045-1D rw rootwait rootfstype=ext4 init=/sbin/init
=> saveenv
Saving Environment to MMC... Writing to MMC(0)... OK
=> print bootargs
bootargs=earlycon=uart8250,mmio32,0xff1a0000 console=ttyS2,1500000n8 root=PARTUUID=B921B045-1D rw rootwait rootfstype=ext4 init=/sbin/init
boot_fit
命令启动内核,我们在uboot
命令行输入boot_fit
命令,输出内容:
=> boot_fit
Unknown command 'boot_fit' - try 'help'
应该是没有配置支持从fit
启动,在uboot上我没有找到选项设置,没有配置,所以没有找到boot_fit这个命令,希望有大佬指导下。