四、FVP启动linux

目录

  • [1 实验目的及环境](#1 实验目的及环境)
    • [1.1 实验目的](#1.1 实验目的)
    • [1.2 实验环境](#1.2 实验环境)
  • [2 相关镜像编译](#2 相关镜像编译)
    • [2.1 TF-A镜像编译](#2.1 TF-A镜像编译)
    • [2.2 U-Boot镜像编译](#2.2 U-Boot镜像编译)
    • [2.3 Linux Kernel镜像编译](#2.3 Linux Kernel镜像编译)
    • [2.4 构建跟文件系统](#2.4 构建跟文件系统)
  • [3 启动linux内核](#3 启动linux内核)
    • [3.1 启动脚本构建](#3.1 启动脚本构建)
    • [3.2 启动Linux内核](#3.2 启动Linux内核)

1 实验目的及环境

1.1 实验目的

通过FVP加载TF-A,用uboot作为TF-A的BL33,然后使用uboot加载linux内核。

1.2 实验环境

1.2.1 拉取代码

需要拉去的代码为:Linux源码、TF-A源码、Uboot源码。

1.2.2搭建交叉编译环境

(1)安装依赖

复制代码
sudo apt-get update
sudo apt-get install -y \
  gcc-aarch64-linux-gnu make git flex bison bc \
  libssl-dev device-tree-compiler dwarves \
  libncurses-dev python3

(2)设置环境变量

复制代码
export CROSS_COMPILE=aarch64-linux-gnu-
export ARCH=arm64

2 相关镜像编译

2.1 TF-A镜像编译

(1)获取源码

复制代码
git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
cd trusted-firmware-a

(2)编译镜像

编译生成BL1、BL2、BL31并生成FIP包,指定Uboot作为BL33。

复制代码
make PLAT=fvp DEBUG=1 RESET_TO_BL31=1 \
     BL33=/abs/path/to/u-boot.bin \
     all fip

注:这里的RESET_TO_BL31=1指的是直接从BL31启动,因为我们是在fvp环境中启动,BL1、BL2这些和具体硬件平台相关的代码并不需要,同时能够加快启动速度。

2.2 U-Boot镜像编译

(1)获取源码

复制代码
git clone https://source.denx.de/u-boot/u-boot.git
cd u-boot

(2)配置FVP为默认板子

复制代码
make CROSS_COMPILE=aarch64-linux-gnu- vexpress_fvp_defconfig

(3)编译

复制代码
make CROSS_COMPILE=aarch64-linux-gnu-

:这部分的内容还有一些需要修改,具体参照3.3小节。

2.3 Linux Kernel镜像编译

(1)获取源码

复制代码
git clone --depth=1 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux

(2)配置

复制代码
make defconfig

(3)增加FVP虚拟接口的支持

复制代码
cat > fvp.fragment <<'EOF'
CONFIG_SERIAL_AMBA_PL011=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_MMIO=y
CONFIG_VIRTIO_BLK=y
CONFIG_VIRTIO_NET=y
CONFIG_EXT4_FS=y
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_BLK_DEV_INITRD=y
EOF

(4)将fvp.fragment文件中的内容合并到.config

复制代码
./scripts/kconfig/merge_config.sh .config fvp.fragment

(5)编译

复制代码
make Image dtbs modules

注:arch/arm64/boot/Image 、arch/arm64/boot/dts/arm/fvp-base-revc.dtb

2.4 构建跟文件系统

(1)获取源码

复制代码
git clone https://busybox.net/git/busybox.git
cd busybox

(2)配置&静态编译

复制代码
make defconfig
sed -i 's/# CONFIG_STATIC is not set/CONFIG_STATIC=y/' .config
make -j$(nproc)
make CONFIG_PREFIX=/tmp/initramfs install

(3)准备目录

复制代码
mkdir -p /tmp/initramfs/{dev,proc,sys}

(4)设备节点

复制代码
sudo mknod -m 600 /tmp/initramfs/dev/console c 5 1
sudo mknod -m 666 /tmp/initramfs/dev/null    c 1 3

(5)最小可用/init

复制代码
cat > /tmp/initramfs/init <<'EOF'
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
mount -t devtmpfs devtmpfs /dev 2>/dev/null || true
echo "Hello from initramfs"
exec /bin/sh
EOF
chmod +x /tmp/initramfs/init

(6)打包

复制代码
cd /tmp/initramfs
find . -print0 | cpio --null -ov --format=newc | gzip -9 > /tmp/rootfs.cpio.gz

3 启动linux内核

3.1 启动脚本构建

通过脚本启动fvp,加载TF-A并启动Linux,具体脚本如下:

复制代码
#!/bin/bash
set -e

FVP_BIN=/home/pengfei/Base_RevC_AEMvA_pkg/models/Linux64_GCC-9.3/FVP_Base_RevC-2xAEMvA
TF_A_BUILD=/home/pengfei/code/tf-a/build/fvp/debug
LINUX_BUILD=/home/pengfei/code/linux/arch/arm64/boot
INITRAMFS=/tmp

$FVP_BIN \
  -C pctl.startup=0.0.0.0 \
  -C bp.secure_memory=0 \
  -C bp.ve_sysregs.exit_on_shutdown=1 \
  -C cluster0.NUM_CORES=4 -C cluster1.NUM_CORES=4 \
  -C bp.secureflashloader.fname=$TF_A_BUILD/bl1.bin \
  -C bp.flashloader0.fname=$TF_A_BUILD/fip.bin \
  --data cluster0.cpu0=$LINUX_BUILD/Image@0x80080000 \
  --data cluster0.cpu0=$LINUX_BUILD/dts/arm/fvp-base-revc.dtb@0x84000000 \
  --data cluster0.cpu0=/tmp/rootfs.cpio.gz@0x86000000

3.2 启动Linux内核

这里需要注意一下,如果用fvp的启动起来的uboot,不能粘贴复制,比较麻烦,所以我们直接修改uboot的源码,具体的修改位置为:

复制代码
u-boot/include/configs/vexpress_aemv8.h


#define CFG_EXTRA_ENV_SETTINGS	\
		"kernel_addr_r=" __stringify(VEXPRESS_KERNEL_ADDR) "\0"	       \
		"ramdisk_addr_r=" __stringify(VEXPRESS_RAMDISK_ADDR) "\0"      \
		"pxefile_addr_r=" __stringify(VEXPRESS_PXEFILE_ADDR) "\0"      \
		"fdt_addr_r=" __stringify(VEXPRESS_FDT_ADDR) "\0"	       \
		"scriptaddr=" __stringify(VEXPRESS_SCRIPT_ADDR) "\0"	       \
		EXTRA_ENV_NAMES	\					       
		BOOTENV \
		"kernel_addr_r=0x80080000\0" \
		"fdt_addr_r=0x84000000\0" \
		"ramdisk_addr_r=0x86000000\0" \
		/* ---- our overrides ---- */      \
        "boot_targets=\0"                                              \
        "bootargs=console=ttyAMA0 earlycon=pl011,0x1c090000 rdinit=/init\0" \
        "ramdisk_size=0x0011F256\0"                                    \
        "bootcmd=booti ${kernel_addr_r} ${ramdisk_addr_r}:${ramdisk_size} ${fdt_addr_r}\0"

注:ramdisk_size这个是你构建的跟文件系统的大小的十六进制。另外每次修改uboot的文件都需要重新编译uboot,同时还需要重新编译TF-A。

相关推荐
路溪非溪7 小时前
Linux的gpio子系统
linux·运维·服务器
范紫涵-19期-工职大7 小时前
虚拟机之CentOS、网络设置的有趣问题
linux·网络·centos
wdfk_prog8 小时前
[Linux]学习笔记系列 -- lib/dump_stack.c 栈回溯打印(Stack Trace Dumping) 内核调试与错误诊断的基石
linux·运维·服务器·c语言·笔记·学习
weixin_471525788 小时前
【ARMday02】
单片机·嵌入式硬件
bantinghy8 小时前
RPC内核细节(转载)
linux·服务器·网络·网络协议·rpc
雨季西柚8 小时前
Docker网络模式解析
linux·运维·kubernetes
久绊A8 小时前
CUPP针对性字典安全防范
linux·kail
特种加菲猫8 小时前
并发编程的守护者:信号量与日志策略模式解析
linux·笔记·策略模式
运维成长记9 小时前
linux 100个问答81~101 主要是k8s相关
linux·运维·服务器