文档说明:只记录关键地方;
试验环境: linux debian 11
基础软件: qemu 6.2
目标:编译linux riscv64 内核 并用qemu-riscv64启动
环境准备
#!/bin/bash
set -exu
__DIR__=$(
cd "$(dirname "$0")"
pwd
)
cd ${__DIR__}
test ! -f /etc/apt/source.list.save && cp /etc/apt/sources.list /etc/apt/sources.list.save
sed -i "[email protected]@mirrors.ustc.edu.cn@g" /etc/apt/sources.list
sed -i "[email protected]@mirrors.ustc.edu.cn@g" /etc/apt/sources.list
apt update -y && apt install -y git curl python3 python3-pip python3-dev
apt install -y libssl-dev ca-certificates make cmake gcc g++ zip
apt install -y tcpdump nmap traceroute net-tools dnsutils iproute2 procps iputils-ping rsync
apt install -y qemu qemu-system qemu-system-riscv64
apt install -y gcc-riscv64-linux-gnu binutils-riscv64-linux-gnu
apt install -y sudo
apt install -y flex bison bc libncurses5-dev libncursesw5-dev cpio
下载linux
#!/bin/bash
set -exu
__DIR__=$(cd "$(dirname "$0")";pwd)
cd ${__DIR__}
test -d linux/.git && git -C linux pull --depth=1 --progress --rebase=true
test -d linux/.git || git clone https://mirrors.tuna.tsinghua.edu.cn/git/linux.git --depth=1 --progress
if [ ! -d busybox ] ;then
{
git clone -b master https://github.com/mirror/busybox.git --depth=1 --progress
} else {
git -C busybox pull origin master --progress --depth=1 --rebase=true
}
fi
prepare-riscv64-image.sh
#!/bin/env bash
set -eux
__DIR__=$(cd "$(dirname "$0")";pwd)
cd ${__DIR__}
export DEBIAN_FRONTEND=noninteractive
cpu_numbers=`grep "processor" /proc/cpuinfo | sort -u | wc -l`
build_target_dir=`readlink -f ${__DIR__}/build/`
echo build_target_dir
build_dir=`readlink -f ${__DIR__}/../`
qemu-system-riscv64 --version
riscv64-linux-gnu-gcc --version
riscv64-linux-gnu-gcc -v
cd ${build_dir}/linux
test -f arch/riscv64/boot/Image && rm -rf arch/riscv64/boot/Image
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- defconfig
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- Image -j $cpu_numbers
cd ${build_dir}/busybox
test -d _install && rm -rf _install
# 参考
# 参考 https://zhuanlan.zhihu.com/p/258394849
# 打开配置菜单后进入第一行的 "Settings",
# 在"Build Options"节中,选中 “Build static binary (no shared libs)”,设置好后退出保存配置。
test -f ${build_dir}/busybox/.config && make oldconfig
test -f ${build_dir}/busybox/.config || make menuconfig
make -j $cpu_numbers && make install
cd ${build_dir}/busybox/_install
mkdir dev etc lib sys proc tmp var home root mnt
mkdir -p /sys/dev
cd dev
sudo mknod console c 5 1
sudo mknod null c 1 3
sudo mknod tty1 c 4 1
sudo mknod tty2 c 4 2
sudo mknod tty3 c 4 3
sudo mknod tty4 c 4 4
cd ${build_dir}/busybox/_install
cd etc
cat <<EOF | tee profile
#!/bin/sh
export HOSTNAME=dev
export USER=root
export HOME=/home
export PS1="[$USER@$HOSTNAME \W]\# "
PATH=/bin:/sbin:/usr/bin:/usr/sbin
LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
export PATH LD_LIBRARY_PATH
EOF
cd ${build_dir}/busybox/_install
cd etc
cat <<EOF | tee inittab
#this is run first except when booting in single-user mode.
::sysinit:/etc/init.d/rcS
#/bin/sh invocations on selected ttys
#Start an "askfirst" shell on the console(whatever that may be)
#::askfirst:-/bin/sh
::respawn:-/bin/sh
#Stuff to do when restarting the init process
::restart:/sbin/init
#Stuff to do before rebooting
::ctrlaltdel:/sbin/reboot
EOF
cat <<EOF | tee fstab
#device mount-point type options dump fsck order
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
EOF
cd ${build_dir}/busybox/_install
cd etc
mkdir -p init.d
cd init.d
touch rcS
cat <<EOF | tee rcS
#!/bin/sh
#This is the first script called by init process
/bin/mount -a
mdev -s
ip addr add 127.0.0.1/8 dev lo
ip link set lo up
#ip link set eth0 down
#ip link set eth0 up
busybox --help
#udhcpc eth0
EOF
chmod +x rcS
cd ${build_dir}/busybox/_install
#cp -p /usr/riscv64-linux-gnu/lib/* ./lib
cd ${build_dir}/busybox/_install
mkdir -p usr/share/udhcpc/
cp ../examples/udhcp/simple.script usr/share/udhcpc/default.script
chmod 755 usr/share/udhcpc/default.script
test -d ${__DIR__}/build || mkdir -p ${__DIR__}/build
test -f ${build_dir}/rootfs.cpio.gz && rm -rf ${build_dir}/rootfs.cpio.gz
find . | cpio -o -H newc |gzip > ${__DIR__}/build/rootfs.cpio.gz
cp -f ${build_dir}/linux/arch/riscv/boot/Image ${__DIR__}/build/Image
cd ${__DIR__}
start-qemu-riscv64.sh
#!/bin/env bash
set -eux
__DIR__=$(cd "$(dirname "$0")";pwd)
cd ${__DIR__}
qemu-system-riscv64 -M help
qemu-system-riscv64 -cpu help
qemu-system-riscv64 -device help
qemu-system-riscv64 -netdev help
#qemu-system-riscv64 -nic model=help
#qemu-system-riscv64 -M virt -nic model=help
pwd
ls -lh ${__DIR__}/build/
qemu-system-riscv64 \
-machine virt \
-m size=1024M \
-cpu rv64 \
-kernel ${__DIR__}/build/Image \
-initrd ${__DIR__}/build/rootfs.cpio.gz \
-append "console=ttyS0 rdinit=/linuxrc" \
-nographic \
-nic user,model=virtio-net-pci \
-device virtio-net-device,netdev=net0 \
-netdev user,id=net0,hostfwd=tcp::10000-:22
关闭qemu
#!/bin/env bash
set -eux
__DIR__=$(cd "$(dirname "$0")";pwd)
cd ${__DIR__}
pid=$(ps -ef | grep 'qa-config/qemu/qemu-riscv64/' | grep -v 'grep' | awk '{print $2}')
kill -15 $pid