本文参考https://www.zhihu.com/question/66594120/answer/3016043997
为编译过程的记录,每台机器环境不一,可能遇到的问题各不相同。
1. 环境建立
1.1 建立ubuntu虚拟机
为了简单起见,采用VMwareWorkstation 17 Pro(版本17.0.0 build-20800274),Linux采用ubuntu-20.04-desktop-amd64( 2.52 GB)。
* 内存:4G
* 处理器:2
* 硬盘 :40G (不要再少了,编译完成以后37G,剩余不了多少)
安装完成以后,版本信息如下:
xu1@ubuntu:~/test$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04 LTS
Release: 20.04
Codename: focal
xu1@ubuntu:~/test$ uname -a
Linux ubuntu 5.15.0-83-generic #92~20.04.1-Ubuntu SMP Mon Aug 21 14:00:49 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
1.2 预备工作环境
默认安装后,设置root密码
sudo passwd root
进入home目录
为了更加纯洁,创建工作目录
xu1@ubuntu:~$ cd ~
xu1@ubuntu:~$ mkdir test
xu1@ubuntu:~$ chmod 777 test
xu1@ubuntu:~$ ls
Desktop Documents Downloads Music Pictures Public Templates test Videos
xu1@ubuntu:~$
下面的下载文件,均以此目录为基准。
1.3 下载交叉编译工具链
可以在https://toolchains.bootlin.com/下载交叉编译工具链。需要对指令集架构和libc进行选择,这里使用riscv 64和glibc,点击Download stable即可下载。
xu1@ubuntu:~/test$ tar -xvf riscv64-lp64d--glibc--stable-2023.08-1.tar.bz2
将交叉编译工具链路径添加到PATH环境变量中,并设置相关的交叉编译环境变量:
xu1@ubuntu:~/test$ export PATH=/home/xu1/test/riscv64-lp64d--glibc--stable-2023.08-1/bin:$PATH
xu1@ubuntu:~/test$ export ARCH=riscv
xu1@ubuntu:~/test$ export CROSS_COMPILE=riscv64-linux-
检查一下:
xu1@ubuntu:~/test$ echo $PATH
/home/xu1/test/riscv64-lp64d--glibc--stable-2023.08-1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
2. 编译内核
2.1 编译内核准备工作
安装所需要的依赖:
sudo apt install make
sudo apt install gcc
sudo apt install flex
sudo apt install ncurses-dev
sudo apt install g++
2.2 编译内核
你可以在http://ftp.sjtu.edu.cn/sites/ftp.kernel.org/pub/linux/kernel下载到想要的内核。经过验证,不同的内核版本编译的命运截然不同。采用5.19.6比较方便,而采用5.8.0版本,则出现一大堆不可控的错误;更高的版本暂时没有去试过,情况未知。
tar -xf linux-5.19.6.tar.gz
cd linux-5.19.6/
make defconfig
make -j8
*这个地方采用默认的编译开关,不作配置改变。编译完成后,最后生成的Kernel文件在linux/arch/riscv/boot/Image中。
xu1@ubuntu:~/test/linux-5.19.6/arch/riscv/boot$ ls -all
total 15240
drwxrwxr-x 3 xu1 xu1 4096 Sep 8 00:42 .
drwxrwxr-x 12 xu1 xu1 4096 Sep 8 00:40 ..
drwxrwxr-x 6 xu1 xu1 4096 Aug 31 2022 dts
-rw-rw-r-- 1 xu1 xu1 92 Aug 31 2022 .gitignore
-rwxrwxr-x 1 xu1 xu1 17688064 Sep 8 00:42 Image
-rw-rw-r-- 1 xu1 xu1 147 Sep 8 00:42 .Image.cmd
-rw-rw-r-- 1 xu1 xu1 5378974 Sep 8 00:42 Image.gz
-rw-rw-r-- 1 xu1 xu1 101 Sep 8 00:42 .Image.gz.cmd
-rwxrwxr-x 1 xu1 xu1 961 Aug 31 2022 install.sh
-rw-rw-r-- 1 xu1 xu1 206 Aug 31 2022 loader.lds.S
-rw-rw-r-- 1 xu1 xu1 143 Aug 31 2022 loader.S
-rw-rw-r-- 1 xu1 xu1 1612 Aug 31 2022 Makefile
3. 使用buildroot制作根文件系统
下载buildroot-2023.02.4.tar.gz到test目录,然后进行解压和配置:
cd ~/test
tar -xvf buildroot-2023.02.4.tar.gz
cd buildroot-2023.02.4/
make qemu_riscv64_virt_defconfig
make menuconfig
此处需要指定外部的工具链,注意Toolchain path需要修改为工具链的绝对地址。
并且需要指定配套支持的版本:
(这个在/home/xu1/test/riscv64-lp64d–glibc–stable-2023.08-1/summary.csv中可以查看和参考)
选中SSP和C++,RPC不能选(至少在我这个机器环境下如此)
内核无需再次编译,此处取消:
保存以后,进行编译:
make -j8
编译完成后,可以在output/images中看到编译的固件
xu1@ubuntu:~/test/buildroot-2023.02.4/output/images$ ls
fw_dynamic.bin fw_jump.bin rootfs.ext2 start-qemu.sh
fw_dynamic.elf fw_jump.elf rootfs.tar
其中:
- rootfs.ext2 是根文件系统,
- start-qemu.sh 是启动qemu的脚本,
- fw_*是OpenSBI支持的固件
- fw_dynamic固件:带有动态信息的固件
- fw_jump固件:指定下一引导阶段的跳转地址,不直接包含下一阶段的二进制代码
- fw_payload固件:包含下一引导阶段有效负载的二进制代码,通常这个有效负载是bootloader或者操作系统镜像
4. 编译QEMU
先需要安装包括ninja的一系列支持:
sudo apt-get install ninja-build
ninja --version
sudo apt-get install libglib2.0-dev
sudo apt-get install libpixman-1-dev
sudo apt-get install bison
然后执行下载和编译, 在这里采用较高的版本8.0,7.0也是可以的。
wget https://download.qemu.org/qemu-8.0.0.tar.xz
tar xvJf qemu-8.0.0.tar.xz
cd qemu-8.0.0
./configure
make -j8
sudo make install
注意:
有时会出现ERROR: glib-2.48 gthread-2.0 is required to compile QEMU错误信息,可以参考https://www.cnblogs.com/jackron/p/14332830.html解决。安装完包以后,再次执行./configure更容易排除这个错误。
5. 在QEMU中启动内核
在/home/xu1/test/buildroot-2023.02.4/output/images目录底下可以发现start-qemu.sh文件,需要对其进行编辑,即修改Image为Image的实际地址
#!/bin/sh
(
BINARIES_DIR="${0%/*}/"
cd ${BINARIES_DIR}
if [ "${1}" = "serial-only" ]; then
EXTRA_ARGS='-nographic'
else
EXTRA_ARGS=''
fi
export PATH="/home/xu1/test/buildroot-2023.02.4/output/host/bin:${PATH}"
exec qemu-system-riscv64 -M virt -bios fw_jump.elf -kernel /home/xu1/test/linux-5.19.6/arch/riscv/boot/Image -append "rootwait root=/dev/vda ro" -drive file=rootfs.ext2,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -netdev user,id=net0 -device virtio-net-device,netdev=net0 -nographic ${EXTRA_ARGS}
)
#上面的关键点在于: /home/xu1/test/linux-5.19.6/arch/riscv/boot/Image
运行脚本
xu1@ubuntu:~/test/buildroot-2023.02.4/output/images$ ./start-qemu.sh
运行如下:
OpenSBI v1.2
____ _____ ____ _____
/ __ \ / ____| _ \_ _|
| | | |_ __ ___ _ __ | (___ | |_) || |
| | | | '_ \ / _ \ '_ \ \___ \| _ < | |
| |__| | |_) | __/ | | |____) | |_) || |_
\____/| .__/ \___|_| |_|_____/|____/_____|
| |
|_|
Platform Name : riscv-virtio,qemu
Platform Features : medeleg
Platform HART Count : 1
Platform IPI Device : aclint-mswi
Platform Timer Device : aclint-mtimer @ 10000000Hz
Platform Console Device : uart8250
Platform HSM Device : ---
Platform PMU Device : ---
Platform Reboot Device : sifive_test
Platform Shutdown Device : sifive_test
Firmware Base : 0x80000000
Firmware Size : 212 KB
Runtime SBI Version : 1.0
.......
Starting syslogd: OK
Starting klogd: OK
Running sysctl: OK
Seeding 256 bits without crediting
Saving 256 bits of creditable seed for next boot
Starting network: udhcpc: started, v1.36.1
udhcpc: broadcasting discover
udhcpc: broadcasting select for 10.0.2.15, server 10.0.2.2
udhcpc: lease of 10.0.2.15 obtained from 10.0.2.2, lease time 86400
deleting routers
adding dns 10.0.2.3
OK
Welcome to Buildroot
buildroot login:
.......
cat /proc/version
Linux version 5.19.6 (xu1@ubuntu) (riscv64-linux-gcc.br_real (Buildroot 2021.11-8547-g7e65a1a) 12.3.0, GNU ld (GNU Binutils) 2.40) #1 SMP Wed Sep 6 23:15:55 PDT 2023
退出此虚拟机:
# poweroff
Stopping network: OK
Seeding 256 bits and crediting
Saving 256 bits of creditable seed for next boot
Stopping klogd: OK
Stopping syslogd: OK
umount: devtmpfs busy - remounted read-only
[ 345.671140] EXT4-fs (vda): re-mounted. Quota mode: disabled.
The system is going down NOW!
Sent SIGTERM to all processes
Sent SIGKILL to all processes
Requesting system poweroff
[ 347.693373] reboot: Power down
xu1@ubuntu:~/test/buildroot-2023.02.4/output/images$
至此完成。