目录

1. QEMU 编译安装

2. Linux 编译

3. 根文件系统

3.1 手撕版

3.2 busybox


1. QEMU 编译安装

sudo apt-get install git libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev
sudo apt-get install git-email
sudo apt-get install libaio-dev libbluetooth-dev libbrlapi-dev libbz2-dev
sudo apt-get install libcap-dev libcap-ng-dev libcurl4-gnutls-dev libgtk-3-dev
sudo apt-get install libibverbs-dev libjpeg8-dev libncurses5-dev libnuma-dev
sudo apt-get install librbd-dev librdmacm-dev
sudo apt-get install libsasl2-dev libsdl1.2-dev libseccomp-dev libsnappy-dev libssh2-1-dev
sudo apt-get install libvde-dev libvdeplug-dev libvte-2.90-dev libxen-dev liblzo2-dev
sudo apt-get install valgrind xfslibs-dev 
sudo apt-get install libnfs-dev libiscsi-dev
sudo apt-get install ninja-build

../configure --enable-kvm --enable-debug --enable-virtiofsd --target-list="aarch64-softmmu"
make -j8
sudo make install

2. Linux 编译

//install compiler
sudo apt-get install gcc-aarch64-linux-gnu

wget  <https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.13.3.tar.xz>
tar -xvf linux-6.13.3.tar.xz
cd linux-6.13.3/

make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- distclean
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- Image -j8

3. 根文件系统

3.1 手撕版

创建init.c程序作为Linux的init进程,只简单输出hello world:

#include <stdio.h>

int main()
{
    printf("hello world!\\n");
    while(1);

    return 0;
}

编译

aarch64-linux-gnu-gcc -o init init.c -static

搭建rootfs

cd ..
mkdir rootfs
cd rootfs
cp ../init ./

mkdir dev
cd dev
mknod -m 660 console c 5 1
mknod -m 660 null c 1 3
cd ..
find . | cpio -o -H newc | gzip > ../initramfs.cpio.gz
cd ..

qemu-system-aarch64 -machine virt       \
                    -cpu cortex-a53     \
                    -nographic          \
                    -smp 4              \
                    -m 2048             \
                    -kernel linux-6.13.3/arch/arm64/boot/Image                        \
                    -append "root=/dev/ram0 rootfstype=ramfs rw init=/init"           \
                    -initrd initramfs.cpio.gz

添加选项-initrd initramfs.cpio.gz表示指定使用这个文件作为ramfs的内容

添加选项-append "root=/dev/ram0 rootfstype=ramfs rw init=/init"表示了传递给内核的参数

root表示根文件系统的设备为/dev/ram0, 除此之外制定了文件系统的类型是ramfs

init表示系统启动的第一个进程名称,内核会从文件系统中加载该进程去执行

initramfs.cpio.gz,该文件是使用脚本生成的根文件系统

3.2 busybox

下载编译busybox

wget <https://www.busybox.net/downloads/busybox-1.37.0.tar.bz2> --no-check-certificate
tar -xvf busybox-1.37.0.tar.bz2
cd busybox-1.37.0
# 生成默认配置
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig

# 修改配置
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig

Settings → Build static binary (no shared libs):如需静态编译(推荐嵌入式场景)。
Settings → Cross compiler prefix:确保填写 aarch64-linux-gnu-
Settings → SHA1: Use hardware accelerated instructions if possible(N)

make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 -j$(nproc)
make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 install

cd _install
mkdir proc sys tmp dev

# 生成开机后的运行脚本
touch init

# 授予执行权限,不然启动内核时会报错无法执行该脚本
chmod +x init

################### init 文件插入以下代码,这是内核启动后马上会运行的代码 ###################
#!/bin/sh

# 挂载一些必要的文件系统
mount -t proc none /proc # 用于获取下方开机时间数据
mount -t sysfs none /sys
mount -t tmpfs none /tmp
mount -t devtmpfs none /dev

# 显示开机消耗时间
echo ------------------------------------------------------
echo
echo "Hello Linux"
echo "This boot took $(cut -d' ' -f1 /proc/uptime) seconds"
echo
echo ------------------------------------------------------

# 启动命令行程序,允许执行命令,不然开机日志输出完毕后什么都操作不了
exec /bin/sh
######################################

ramfs:

# 生成文件系统包
find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../initramfs.cpio.gz
# -m 指定运行内存大小,可选
# -kernel 指定内核,路径就是上面编译生成的bzImage的路径
# -initrd 指定启动文件
# -append 启动参数init后面的参数就是我们上面制作的启动脚本的文件路径

qemu-system-aarch64 -machine virt       \
                    -cpu cortex-a53     \
                    -nographic          \
                    -smp 4              \
                    -m 2048             \
                    -kernel linux-6.13.3/arch/arm64/boot/Image                        \
                    -append "root=/dev/ram0 rootfstype=ramfs rw init=/init"           \
                    ./busybox-1.37.0/initramfs.cpio.gz 

ext3:

dd if=/dev/zero of=./rootfs.ext3 bs=1M count=256
mkfs.ext3 rootfs.ext3
mkdir img
sudo mount -o loop rootfs.ext3 ./img
sudo cp -r ./busybox-1.37.0/_install/* ./img/
sudo umount img

# 这里注意-append root=/dev/vda

qemu-system-aarch64 -machine virt       \
                    -cpu cortex-a53     \
                    -nographic          \
                    -smp 1              \
                    -m 2048             \
                    -kernel linux/arch/arm64/boot/Image                        \
                    -append "root=/dev/vda rw init=/init console=ttyAMA0 earlycon=pl011,0x9000000"             \
                    -hda ./rootfs.ext3
                    

 4. QEMU与Host文件共享

  1. 启动 QEMU 时启用共享目录

    添加以下参数:

      -fsdev local,id=fsdev0,path=/host/path,security_model=none \
      -device virtio-9p-pci,fsdev=fsdev0,mount_tag=hostshare
    
    
    # 完整命令
    
    qemu-system-aarch64 -machine virt       \
                        -cpu cortex-a53     \
                        -nographic          \
                        -smp 1              \
                        -m 2048             \
                        -kernel linux/arch/arm64/boot/Image                        \
                        -append "root=/dev/vda rw init=/init console=ttyAMA0 earlycon=pl011,0x9000000"             \
                        -hda ./rootfs.ext3 \
                        -fsdev local,id=fsdev0,path=/home/linux/linux/demo/,security_model=none \
    					-device virtio-9p-pci,fsdev=fsdev0,mount_tag=hostshare
    
  2. 在虚拟机内挂载共享目录

    mkdir /mnt/host
    mount -t 9p -o trans=virtio hostshare /mnt/host -o version=9p2000.L
    

 

更多推荐