飞腾E2000 uboot引导系统启动

文摘   科技   2023-10-03 23:09   河北  

飞腾基于 VPX、COMe、Mini-ITX 等主流标准板卡接口协议设计了多款 E2000 行业开发板,用于提升研发效率。E2000实际使用中会有采用uboot来引导系统启动的情况。

本文以飞腾E2000D电力开发板为例,简单介绍下E2000使用uboot引导启动系统的整个过程。这个启动过程不严谨的分解,由uboot、环境变量、设备树、内核、文件系统组成。下面我们逐项说明。

一、uboot

首先,uboot是广义上的称呼,飞腾的uboot固件由多个部分组成的。

固件生成过程大体分成三个步骤,

1.编译系统固件。根据选用的系统固件(SFW)编译UEFI或U-Boot的源码,生成PHYTIUM.fd或u-boot.bin,将其重命名为bl33_new.bin,做为备用。

2.低速引脚复用配置。通过 E2000 LSD复用工具进行低速引脚复用配置,生成文件pad_set.bin,做为备用。

3.打包。通过 PBF 打包工具,配置板级参数和高速引脚复用,最后生成文件 fip-all.bin,该文件可直接烧录到FLASH中,用于启动。

Uboot固件的制作,基本可以参考原桌面CPU的操作过程和环境。

链接:飞腾CPU BIOS固件生成教程

与桌面CPU操作的区别是E2000有低速引脚,需要使用专用的配置工具生成pad_set.bin文件,并且最后一并打包到固件中。

二、环境变量

uboot的环境变量设置完全可以参考网上的资料,这里飞腾没有任何特殊的地方。主要需要确定的就是设备树、内核和文件系统在板卡存储设备(sata、nvme、sd等)中的位置和加载地址。既然要设置这些文件的位置,那么我们就不得不介绍存储设备里文件的制作。所以环境变量我们先放一放,我们先看后面,设备树、内核和文件系统。

三、设备树、内核和文件系统

设备树、内核和文件系统最终是要存到存储设备中的,那么我们首先就要准备好文件,其次处理好存储设备,最后就是把准备好的文件存放到存储设备中。

3.1 文件准备

我们以汉为的E2000D电力开发板为例来讲解。

我们要准备三个文件,设备树、内核、文件系统。分别为:e2000d-power-board.dtb、Image、rootfs.tar.xz。

设备树、内核都是二进制文件,这个不用动。文件系统是使用buildroot方式做的压缩包。如何使用buildroot做文件系统,看飞腾的gitee。

链接:https://gitee.com/phytium_embedded/phytium-linux-buildroot

3.2 nvme盘分区、格式化

3.2.1 硬件接法

这个汉为E2000D电力开发板是使用nvme作为存储介质的。我们要对这个nvme盘进行处理。

有两种方式,一就是找一个nvme转pcie的转接板,将nvme盘接入一个能开机的飞腾板子上。二就是使用nvme转USB的转接板,接入windows电脑里的虚拟机,在linux虚拟机里操作。总而言之,这个nvme盘要在linux系统下进行操作。

3.2.2 分区

当我们nvme盘接入了linux系统后,我们使用fdisk命令先确定好nvme盘系统下的盘符。我这里nvme盘接入linux系统后名字叫nvme0n1。

我们先进行分区(下文是将nvme盘按两个分区进行的操作,但是对于本文的引导系统启动操作来说,分成一个区就可以。分两个区也是为了更多的展示细节)。

先分区nvme,命令

  1. #fdisk /dev/nvme0n1

n是新建分区,p主分区,1代表分区1,First sector就是新分区的第一个扇区,默认就是顺序第一个空扇区;Last sector是新分区的最后一个扇区,默认是整个磁盘最后一个扇区,+2g代表在first sector上+2g,也就是分区大小2GB。如果在操作过程中直接回车,则执行的是default的值。

最后输入w写入分区信息。

再执行fdisk命令进行查看,就可以看到nvme的两个分区了nvme0n1p1和nvme0n1p2。

3.2.3 格式化

对nvme0n1p1和nvme0n1p2两个分区进行格式化。

格式化成ext4格式,命令为:

  1. #mkfs.ext4 /dev/nvme0n1p1

  2. #mkfs.ext4 /dev/nvme0n1p2

3.3 系统盘文件制作

我们在linux系统中新建mnt目录里新建mnvme的目录,用于实体nvme盘的挂载。

命令:

  1. #mkdir /mnt/mnvme

  2. #mount /dev/nvme0n1p2 /mnt/mnvme

  3. ###将nvme的第2个分区挂载到mnt目录中的mnvme中

之后我们把3.1中准备的设备树、内核、文件系统。复制到mnt目录中的mnvme中。(我把这三个文件放到了linux系统的桌面上,所以下面命令都是从“/home/ft/桌面/”进行复制的)

  1. #cp /home/ft/桌面/e2000d-power-board.dtb /mnt/mnvme

  2. #cp /home/ft/桌面/Image /mnt/mnvme

  3. #cp /home/ft/桌面/rootfs.tar.xz /mnt/mnvme

因为设备树和内核都是二进制文件,因此不需要进行额外的处理。根文件系统是tar.xz的压缩包,我们需要对其进行解压。

  1. #cd /mnt/mnvme

  2. #tar xvf rootfs.tar.xz

最后,要记得进行一次同步操作,保证我们nvme盘内的文件与挂载的/mnt/mnvme目录内的文件一致。

  1. #sync

最后我们卸载mnvme目录就好了。

  1. #umount /mnt/mnvme

四、环境变量

将uboot固件烧写到flash,做好的nvme盘安装到板卡上后。给E2000D电力开发板加电启动,我们进入uboot的命令行。

我们可以print看一下当前的环境变量(首先提示,这个默认的环境变量是启动不起来的)。

E2000#printarch=armbaudrate=115200board=e2000board_name=e2000boot_os=bootm kernel_addr -:- ft_fdt_addrbootargs=earlycon=pl011,0x2800d000 root=/dev/sda2 rwbootcmd=run distro_bootcmdbootdelay=2cpu=armv8distro_bootcmd=run load_kernel; run load_initrd; run load_fdt; run boot_oseth0addr=00:11:22:33:44:55eth1addr=10:22:33:44:55:66eth2addr=10:11:22:33:44:55eth3addr=00:22:33:44:55:66ethaddr=00:11:22:33:44:55fdt_addr=0x381BC000fdtcontroladdr=fa43c860ft_fdt_addr=0x90000000ft_fdt_name=boot/dtb/e2000.dtbgatewayip=202.197.67.1initrd_addr=0x95000000ipaddr=202.197.67.2kernel_addr=0x90100000load_fdt=ext4load scsi 0:2 ft_fdt_addr ft_fdt_nameload_initrd=ext4load scsi 0:2 $initrd_addr initrd.img-4.19.0.e2000load_kernel=ext4load scsi 0:2 $kernel_addr boot/uImage-2004loadaddr=0x90000000netdev=eth0netmask=255.255.255.0serverip=202.197.67.3stderr=uart@2800d000stdin=uart@2800d000stdout=uart@2800d000vendor=phytiumEnvironment size: 930/4092 bytes

bootcmd=run distrobootcmd,也就是执行bootcmd就是run distrobootcmd,run就是执行distrobootcmd,那么我们再看distrobootcmd是要执行什么。distrobootcmd=run loadkernel; run loadinitrd; run loadfdt; run bootos,那就是首先执行loadkernel,再执行 loadinitrd,再执行loadfdt,再执行boot_os……就这样逐步的拆解,最后落实到最终的指令上。

通过上面的解析,我们也大概了解了整个的启动参数,并且也看出其中有一些参数的问题,比如现在是nvme盘,但是环境变量是sata盘,同时ext4load的文件和我们在“三、设备树、内核和文件系统”中做到nvme盘中的文件不一致。那么我就要对这些与自己板卡不符合的内容进行修改。

还是针对汉为E2000D电力开发板,我们需要执行如下命令:

#setenv bootargs 'console=ttyAMA1,115200 audit=0 earlycon=pl011,0x2800d000 root=/dev/nvme0n1p2 rw' #确定调试串口信息,确定根文件在/dev/nvme0n1p2中
#setenv load_kernel 'ext4load nvme 0:2 0x90100000 Image' #使用ext4load命令加载nvme盘0第2个分区中的Image内核到内存地址0x90100000中
#setenv load_fdt 'ext4load nvme 0:2 0x90000000 e2000d-power-board.dtb' #使用ext4load命令加载nvme盘0第2个分区中的dtb设备树到内存地址0x90000000中
#setenv boot_os 'booti 0x90100000 -:- 0x90000000' #使用booti命令,从内存地址进行系统加载启动
#saveenv #保存环境变量

最后可以用于启动的完整环境变量为:

E2000#printarch=armbaudrate=115200board=e2000board_name=e2000boot_os=booti 0x90100000 -:- 0x90000000bootargs=console=ttyAMA1,115200 audit=0 earlycon=pl011,0x2800d000 root=/dev/nvme0n1p2 rwbootcmd=run distro_bootcmdbootdelay=2cpu=armv8distro_bootcmd=run load_kernel; run load_initrd; run load_fdt; run boot_oseth0addr=00:11:22:33:44:55eth1addr=10:22:33:44:55:66eth2addr=10:11:22:33:44:55eth3addr=00:22:33:44:55:66ethaddr=00:11:22:33:44:55fdt_addr=0x381BC000fdtcontroladdr=fa43d860ft_fdt_addr=0x90000000ft_fdt_name=boot/dtb/e2000.dtbgatewayip=202.197.67.1initrd_addr=0x95000000ipaddr=202.197.67.2kernel_addr=0x90100000load_fdt=ext4load nvme 0:2 0x90000000 e2000d-power-board.dtbload_initrd=ext4load scsi 0:2 $initrd_addr initrd.img-4.19.0.e2000load_kernel=ext4load nvme 0:2 0x90100000 Imageloadaddr=0x90000000netdev=eth0netmask=255.255.255.0serverip=202.197.67.3stderr=uart@2800d000stdin=uart@2800d000stdout=uart@2800d000vendor=phytium
Environment size: 957/4092 bytes

仔细分析上面的环境变量。其加载的设备树、内核、文件系统,都是我们前面做好的,再nvme盘中的,并且将文件加载到了指定的内存地址位置。那么到最后booti命令,我们从内存执行就可以了。

五、总结

前面我们也说了,不严谨的分解,整个启动过程由uboot、环境变量、设备树、内核、文件系统组成。上面的步骤中,我们做完了所有的文件。Uboot已经做好了并且已经启动了,环境变量指定了启动加载的设备树、内核、文件系统的位置和文件。整个流程中,uboot和系统文件通过环境变量有机的结合到了一起,最终实现了uboot引导系统启动的整个流程。



期文章

交流群:
PSPA:
硬件:
固件:
调试:

欢迎飞腾爱好者加入微信交流群。 群内大家可以在群内交流遇到的问题,分享自己的调试心得。 希望大家共建飞腾友谊!


乌拉大喵喵
建立了飞腾爱好者技术交流群,公众号文章扫码进群,或私信加vx进群。
 最新文章