arm32/64 on qemu

1 base on arm

  • info
    • arm-linux-gnueabihf-gcc (Linaro GCC 7.5-2019.12) 7.5.0
    • linux-5.10
    • busybox-1.34.1
    • QEMU emulator version 6.2.0

linux

  • 编译

    • make distclean; make clean

    • make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- vexpress_defconfig

    • make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig

        • Kernel hacking > printk and dmesg options
          • Show timing information on printks #打印时间
          • Enable dynamic printk() support #打开动态debug机制
        • Device Drivers > Generic Driver Options
          • Support for uevent helper #支持热插拔
    • make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4

  • 验证

    • qemu-system-arm -M vexpress-a9 -m 128M -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic
    • qemu-system-arm -M vexpress-a15 -m 128M -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dtb -nographic

文件系统 init.c

//init.c
#include <stdio.h>

void main()
{
    
    
	printf("\033[1;36m Hello qemu!\033[m\n");  //打印一串亮青色的字体
	while(1);
}

采用静态库编译: arm-linux-gnueabihf-gcc -static -o init init.c

linux2.6 内核支持两种格式的 initrd(虚拟文件系统),一种是 linux2.4 内核那种传统格式的文件系统镜像 image-initrd,其核心文件就是 /linuxrc

另外一种格式的 initrd 是 cpio 格式的,这种格式的 initrd 使用 cpio 工具生成,其核心文件不再是 /linuxrc,而是 /init,本文将这种 initrd 称为 cpio-initrd。

将init制作成cpio镜像

  • echo init | cpio -o --format=newc > initramfs

验证

  • qemu-system-arm -M vexpress-a9 -m 128M -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic -initrd …/initramfs
  • qemu-system-arm -M vexpress-a15 -m 128M -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dtb -nographic -initrd …/initramfs
  • 停止qemu:ctrl + a,x(组合键ctrl+a,之后再按x)

busybox

使用静态库方式编译

编译

  • make distclean; make clean

  • make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- defconfig

  • make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig

    • Settings —>

      • [*] Build static binary (no shared libs) #使用静态库
  • make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4

  • make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- install

    • 生成结果位于:当前根目录下的_install文件夹下
    • 备注:默认安装到根目录下的_install,若想更改,可以通过menuconfig里面的选项更改

文件系统镜像

  • 根目录构建

    • mkdir -p rootfs/{
              
              dev,etc/init.d,lib,proc,sys}   #创建根目录
      
      cp -raf busybox-1.34.1/_install/* rootfs        #拷贝busybox命令到根目录
      
      sudo mknod -m 666 rootfs/dev/tty1 c 4 1         #创建4个tty端终设备
      sudo mknod -m 666 rootfs/dev/tty2 c 4 2
      sudo mknod -m 666 rootfs/dev/tty3 c 4 3
      sudo mknod -m 666 rootfs/dev/tty4 c 4 4
      sudo mknod -m 666 rootfs/dev/console c 5 1      #创建console字符设备
      sudo mknod -m 666 rootfs/dev/null c 1 3         #创建null 字符设备
      
      # vim rootfs/etc/init.d/rcS   #输入如下内容
      #!/bin/bash
      mount -t proc proc /proc
      mount -t sysfs sysfs /sys
      /sbin/mdev -s
      echo /sbin/mdev > /proc/sys/kernel/hotplug      #支持热插拔
      #
      sudo chmod +x rootfs/etc/init.d/rcS
      
  • 制作启动镜像

    • 注意:一定要在rootfs目录下执行,否则会失败
    • cd rootfs;find ./ | cpio -o --format=newc > …/rootfs.img #制作成cpio镜像

验证

  • 启动

    • qemu-system-arm -M vexpress-a9 -m 128M -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -append “root=/dev/ram rdinit=sbin/init console=ttyAMA0” -nographic -initrd …/rootfs.img
    • qemu-system-arm -M vexpress-a15 -m 128M -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dtb -append “root=/dev/ram rdinit=sbin/init console=ttyAMA0” -nographic -initrd …/rootfs.img
  • 执行demo

    • code:https://gitee.com/tianzong2019/bookcode/blob/drv/6.chardev/example
    • 编译后执行,若需要手动创建节点,可通过如下实现
      • 加载设备
        • insmod mdrv.ko
        • mknod /dev/miscdev c 10 2
          • /dev/miscdev 设备节点名称
          • c b和c 分别表示块设备和字符设备
          • 10 MAJOR表示主设备号
          • 2 MINOR表示次设备号
          • 使用手动mknod则需要配置静态的主次设备号
      • 卸载设备
        • rmmod mdrv.ko
        • rm -rf /dev/miscdev
  • 综合脚本

    • #!/bin/bash
      
      cur=${1:-`pwd`}
      busybox=${cur}/busybox-1.34.1
      linux=${cur}/linux-5.10
      rootfs=${cur}/rootfs
      app=${cur}/app
      rootfsimg=${cur}/cpio-rootfs.img
      rcs=${rootfs}/etc/init.d/rcS
      
      #[[ ! -d ${app} ]] && mkdir ${app}
      [[ -d ${rootfs} ]] && rm -rf ${rootfs}
      mkdir -p ${rootfs}/{
              
              dev,etc/init.d,lib,proc,sys}   #创建根目录
      
      cp -raf ${busybox}/_install/* ${rootfs}            #拷贝busybox命令到根目录
      #cp -raf ${app} ${rootfs} 
      
      sudo mknod -m 666 ${rootfs}/dev/tty1 c 4 1         #创建4个tty端终设备
      sudo mknod -m 666 ${rootfs}/dev/tty2 c 4 2
      sudo mknod -m 666 ${rootfs}/dev/tty3 c 4 3
      sudo mknod -m 666 ${rootfs}/dev/tty4 c 4 4
      sudo mknod -m 666 ${rootfs}/dev/console c 5 1      #创建console字符设备
      sudo mknod -m 666 ${rootfs}/dev/null c 1 3         #创建null 字符设备
      
      echo "#!/bin/sh" >> ${rcs}
      echo "mount -t proc proc /proc" >> ${rcs}
      echo "mount -t sysfs sysfs /sys" >> ${rcs}
      echo "/sbin/mdev -s" >> ${rcs}
      echo "echo /sbin/mdev > /proc/sys/kernel/hotplug" >> ${rcs}
      echo "mount -t debugfs none /sys/kernel/debug" >> ${rcs}
      
      sudo chmod 777 ${rcs}
      
      #一定要在rootfs目录下执行,否则会失败
      cd ${rootfs}; find ./ | cpio -o --format=newc > ${rootfsimg}   #制作成cpio镜像
      
      cd ${cur};rm -rf ${rootfs}
      
      qemu-system-arm -M vexpress-a9 -m 128M \
      	-kernel ${linux}/arch/arm/boot/zImage \
      	-dtb ${linux}/arch/arm/boot/dts/vexpress-v2p-ca9.dtb \
      	-append "root=/dev/ram rdinit=sbin/init console=ttyAMA0" \
      	-nographic -initrd ${rootfsimg}
      

2 base on arm64

  • info
    • aarch64-linux-gnu-gcc (Linaro GCC 7.2-2017.11) 7.2.1 20171011
    • linux-5.10
    • busybox-1.34.1
    • QEMU emulator version 6.2.0

linux

  • 编译

    • make distclean; make clean

    • make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig

    • make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig

        • Kernel hacking > printk and dmesg options
          • Show timing information on printks #打印时间
          • Enable dynamic printk() support #打开动态debug机制
        • Device Drivers > Generic Driver Options
          • Support for uevent helper #支持热插拔
        • File systems > Network File Systems #用于qemu共享文件夹
          • 9P POSIX Access Control Lists
          • 9P Security Labels
    • make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)

  • 验证

    • qemu-system-aarch64 -smp 4 -M virt -cpu cortex-a57 -m 2048M -kernel linux-5.10/arch/arm64/boot/Image -nographic -append “console=ttyAMA0”

busybox

使用动态库方式编译

  • 编译

    • make distclean; make clean

    • 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) #去掉静态库勾选
    • make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j4

    • make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- install

      • 生成结果位于:当前根目录下的_install文件夹下
      • 备注:默认安装到根目录下的_install,若想更改,可以通过menuconfig里面的选项更改
  • 动态库依赖

    • 我们选择动态编译后,没有添加任何库文件就运行,显然是会出错的。那么如何查看busybox可执行文件里使用的库呢。Readelf这个工具提供了解决办法。使用如下命令,参数d表示将文件中所有的动态部分予以显示。

    • aarch64-linux-gnu-readelf -d busybox

      • aldrich@tyrone:~/codeSpace/qemu.arm64/busybox-1.34.1/_install/bin$ aarch64-linux-gnu-readelf -d busybox 
        
        Dynamic section at offset 0xfcde8 contains 26 entries:
          Tag        Type                         Name/Value
         0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
         0x0000000000000001 (NEEDED)             Shared library: [libresolv.so.2]
         0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
         0x000000000000000c (INIT)               0x4067e8
         ...
        
    • 上面显示用到的动态库有3个:libm.so.6、libresolv.so.2、libc.so.6,依次查看动态库所在位置及其链接

      • $ locate libm.so.6
        /lib/x86_64-linux-gnu/libm.so.6
        /usr/local/lib/gcc-linaro-7.2.1-2017.11-x86_64_aarch64-linux-gnu/aarch64-linux-gnu/libc/lib/libm.so.6
        $ 
        $ ll /usr/local/lib/gcc-linaro-7.2.1-2017.11-x86_64_aarch64-linux-gnu/aarch64-linux-gnu/libc/lib/libm.so.6
        xxx 07:36 /usr/local/lib/gcc-linaro-7.2.1-2017.11-x86_64_aarch64-linux-gnu/aarch64-linux-gnu/libc/lib/libm.so.6 -> libm-2.25.so*
        
      • 因为busybox用在arm平台,所以只看aarch64-linux-gnu下面的库,把这2个拷贝到busybox的_install目录下,其他2个依次操作

      • 除了这3组动态库,也需要共享库加载器,加载器一般是ld-xxx.so,在交叉编译器gcc-linaro-7.2.1下面去搜索

        • $ find . -name "*ld*"
          ./ld-2.25.so
          ./ld-linux-aarch64.so.1
          
        • 再拷贝这2个库到busybox的_install目录下,即可运行正常

      • 其实,最省心的是把aarch64-linux-gnu/libc/lib文件夹直接拷贝到_install目录下

启动方式

cpio

#!/bin/bash

cur=${1:-`pwd`}
busybox=${cur}/busybox-1.34.1
linux=${cur}/linux-5.10
rootfs=${cur}/rootfs
app=${cur}/app
rootfsimg=${cur}/cpio-rootfs.img
rcs=${rootfs}/etc/init.d/rcS

# [[ ! -d ${app} ]] && mkdir ${app}
[[ -d ${rootfs} ]] && rm -rf ${rootfs}
mkdir -p ${rootfs}/{
    
    dev,etc/init.d,lib,proc,sys}   #创建根目录

cp -raf ${busybox}/_install/* ${rootfs}            #拷贝busybox命令到根目录
# cp -raf ${app} ${rootfs}

sudo mknod -m 666 ${rootfs}/dev/tty1 c 4 1         #创建4个tty端终设备
sudo mknod -m 666 ${rootfs}/dev/tty2 c 4 2
sudo mknod -m 666 ${rootfs}/dev/tty3 c 4 3
sudo mknod -m 666 ${rootfs}/dev/tty4 c 4 4
sudo mknod -m 666 ${rootfs}/dev/console c 5 1      #创建console字符设备
sudo mknod -m 666 ${rootfs}/dev/null c 1 3         #创建null 字符设备

echo "#!/bin/sh" >> ${rcs}
echo "mount -t proc proc /proc" >> ${rcs}
echo "mount -t sysfs sysfs /sys" >> ${rcs}
echo "/sbin/mdev -s" >> ${rcs}
echo "echo /sbin/mdev > /proc/sys/kernel/hotplug" >> ${rcs}
echo "mount -t debugfs none /sys/kernel/debug" >> ${rcs}

sudo chmod 777 ${rcs}

#一定要在rootfs目录下执行,否则会失败
cd ${rootfs}; find ./ | cpio -o --format=newc > ${rootfsimg}   #制作成cpio镜像

cd ${cur};rm -rf ${rootfs}

qemu-system-aarch64 -M virt -cpu cortex-a57 -smp 4 -m 2048M \
	-kernel ${linux}/arch/arm64/boot/Image \
	-append "root=/dev/ram rdinit=sbin/init  console=ttyAMA0 loglevel=9" \
	-nographic -initrd ${rootfsimg}

hda

#!/bin/bash

cur=${1:-`pwd`}
busybox=${cur}/busybox-1.34.1
linux=${cur}/linux-5.10
rootfs=${cur}/rootfs
rootfsimg=${cur}/hda-rootfs_ext4.img

dd if=/dev/zero of=${rootfsimg} bs=1M count=64 oflag=direct
mkfs.ext4 ${rootfsimg}

[[ -d rootfs ]] && rm -rf ${rootfs}
mkdir ${rootfs}

sudo mount ${rootfsimg} ${rootfs}
sudo cp -raf ${busybox}/_install/* ${rootfs}

sudo mkdir -p ${rootfs}/{
    
    proc,sys,tmp,root,var,mnt,dev}
sudo mknod ${rootfs}/dev/tty1 c 4 1
sudo mknod ${rootfs}/dev/tty2 c 4 2
sudo mknod ${rootfs}/dev/tty3 c 4 3
sudo mknod ${rootfs}/dev/tty4 c 4 4
sudo mknod ${rootfs}/dev/console c 5 1
sudo mknod ${rootfs}/dev/null c 1 3

sudo cp -r ${busybox}/examples/bootfloppy/etc/ ${rootfs}

sudo umount ${rootfs};rm -rf ${rootfs}

qemu-system-aarch64 -M virt -cpu cortex-a57 -smp 4 -m 2048M \
	-kernel ${linux}/arch/arm64/boot/Image \
	-append "root=/dev/vda console=ttyAMA0 rootfstype=ext4 init=/linuxrc rw" \
	-nographic -hda ${rootfsimg}

SD

9p share

#!/bin/bash

cur=${1:-`pwd`}
busybox=${cur}/busybox-1.34.1
linux=${cur}/linux-5.10
rootfs=${cur}/rootfs
rootfsimg=${cur}/hda-rootfs_ext4.img
shdir=${cur}/sharedir
rcs=${busybox}/examples/bootfloppy/etc/init.d/rcS

dd if=/dev/zero of=${rootfsimg} bs=1M count=64 oflag=direct
mkfs.ext4 ${rootfsimg}

[[ ! -d ${shdir} ]] && mkdir ${shdir}
[[ -d rootfs ]] && rm -rf ${rootfs}
mkdir ${rootfs}

sudo mount ${rootfsimg} ${rootfs}
sudo cp -raf ${busybox}/_install/* ${rootfs}

sudo mkdir -p ${rootfs}/{
    
    proc,sys,tmp,root,var,mnt,dev}
sudo mknod ${rootfs}/dev/tty1 c 4 1
sudo mknod ${rootfs}/dev/tty2 c 4 2
sudo mknod ${rootfs}/dev/tty3 c 4 3
sudo mknod ${rootfs}/dev/tty4 c 4 4
sudo mknod ${rootfs}/dev/console c 5 1
sudo mknod ${rootfs}/dev/null c 1 3
# 自动挂载共享目录
echo "mount -t 9p -o trans=virtio,version=9p2000.L hostshare /mnt" >> ${rcs}

sudo cp -r ${busybox}/examples/bootfloppy/etc/ ${rootfs}
sudo umount ${rootfs};rm -rf ${rootfs}

qemu-system-aarch64 -M virt -cpu cortex-a57 -smp 4 -m 2048M \
	-kernel ${linux}/arch/arm64/boot/Image \
	-append "root=/dev/vda console=ttyAMA0 rootfstype=ext4 init=/linuxrc rw" \
	-nographic -hda ${rootfsimg}  \
	-fsdev local,security_model=passthrough,id=fsdev0,path=${shdir} \
	-device virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=hostshare

根据以上配置执行完qemu后,进入系统手动执行,即可把共享文件夹挂载到/mnt目录

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

3 qemu network

配置虚拟网桥,参考附录里面的《A.2 qemu虚拟网桥》。以“9p share”为例,测试qemu网络功能

  • 9p share环境:qemu + arm64 + linux + busybox

  • 示例网桥以“enp0s3”进行桥接

    • IP:10.0.2.15
    • netmask:255.255.255.0
    • broadcast:10.0.2.255
    • gateway:10.0.2.2
  • 在启动脚本中添加网络功能

    • 以下可二选一,第2种相当于多建立了一个网卡,推荐第一周方法
    • -nic tap,id=n0,ifname=tap0,script=no,downscript=no
    • -net nic,macaddr=4e:71:7d:86:5c:40 -nic tap,id=n0,ifname=tap0,script=no,downscript=no
  • 脚本如下

  • #!/bin/bash
    
    cur=${1:-`pwd`}
    busybox=${cur}/busybox-1.34.1
    linux=${cur}/linux-5.10
    rootfs=${cur}/rootfs
    rootfsimg=${cur}/hda-rootfs_ext4.img
    shdir=${cur}/sharedir
    
    dd if=/dev/zero of=${rootfsimg} bs=1M count=64 oflag=direct
    mkfs.ext4 ${rootfsimg}
    
    [[ ! -d ${shdir} ]] && mkdir ${shdir}
    [[ -d rootfs ]] && rm -rf ${rootfs}
    mkdir ${rootfs}
    
    sudo mount ${rootfsimg} ${rootfs}
    sudo cp -raf ${busybox}/_install/* ${rootfs}
    
    sudo mkdir -p ${rootfs}/{
          
          proc,sys,tmp,root,var,mnt,dev/pts,usr/share/udhcpc}
    sudo mknod ${rootfs}/dev/tty1 c 4 1
    sudo mknod ${rootfs}/dev/tty2 c 4 2
    sudo mknod ${rootfs}/dev/tty3 c 4 3
    sudo mknod ${rootfs}/dev/tty4 c 4 4
    sudo mknod ${rootfs}/dev/console c 5 1
    sudo mknod ${rootfs}/dev/null c 1 3
    
    sudo cp -r ${busybox}/examples/bootfloppy/etc/ ${rootfs}
    sudo cp -r ${busybox}/examples/udhcp/simple.script ${rootfs}/usr/share/udhcp/default.script
    # 自动挂载共享目录
    sudo chmod 777 ${rootfs}/etc/init.d/rcS
    sudo echo "mount -t 9p -o trans=virtio,version=9p2000.L hostshare /mnt" >> ${rootfs}/etc/init.d/rcS
    sudo echo "ifconfig eth0 up" >> ${rootfs}/etc/init.d/rcS
    
    sudo umount ${rootfs};rm -rf ${rootfs}
    
    qemu-system-aarch64 -M virt -cpu cortex-a57 -smp 4 -m 2048M \
    	-kernel ${linux}/arch/arm64/boot/Image \
    	-append "root=/dev/vda console=ttyAMA0 rootfstype=ext4 init=/linuxrc rw" \
    	-nographic -hda ${rootfsimg}  \
    	-nic tap,id=n0,ifname=tap0,script=no,downscript=no \
    	-fsdev local,security_model=passthrough,id=fsdev0,path=${shdir} \
    	-device virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=hostshare
    
  • 直接用uboot启动也有网络,uboot会自动获取IP

    • qemu-system-arm -M vexpress-a9 -m 512M -kernel u-boot -nographic -nic tap,id=n0,ifname=tap0,script=no,downscript=no

4 buildroot on arm64

buildroot编译配置

  • toolchain
    • Toolchain type (External toolchain) —>
    • Toolchain origin (Pre-installed toolchain)
    • (/usr/local/lib/gcc-linaro-7.2.1-2017.11-x86_64_aarch64-linux-gnu) Toolchain path
    • (aarch64-linux-gnu) Toolchain prefix
    • External toolchain gcc version (7.x) —>
    • External toolchain kernel headers series (4.10.x) —> 交叉编译器gcc用到的linux头文件,可以先不配,编译报错时会提示
    • External toolchain C library (glibc/eglibc) —>
  • System configuration
    • /dev management (Dynamic using devtmpfs + mdev) —>
    • [*] Enable root login with password
    • (12345) Root password
    • Search (telnet) > Networking
  • 网络
    • [*] libtelnet
    • [*] libssh
    • [*] libssh2

启动脚本前先执行创建虚拟网卡指令(A.2 qemu虚拟网桥)

启动脚本如下,start-qemu.sh

#!/bin/sh
(
BINARIES_DIR="${0%/*}/"
cd ${BINARIES_DIR}

if [ "${1}" = "serial-only" ]; then
    EXTRA_ARGS='-nographic'
else
    EXTRA_ARGS=''
fi

EXTRA_ARGS='-nographic'

cur=${1:-`pwd`}
image=${cur}/kernel/arch/arm64/boot/Image
rootfs=${cur}/buildroot-2022.02/output/images/rootfs.ext4


export PATH="/home/aldrich/codeSpace/qemu.arm64/buildroot-2022.02/output/host/bin:${
     
     PATH}"
exec qemu-system-aarch64 -M virt -cpu cortex-a53 -nographic -smp 1 -kernel ${image} \
		-append "rootwait root=/dev/vda console=ttyAMA0" \
		-net nic,model=virtio -net tap,ifname=tap0,script=no,downscript=no \
		-drive file=${rootfs},if=none,format=raw,id=hd0 \
		-device virtio-blk-device,drive=hd0  ${EXTRA_ARGS}
)

附录

A.1 qemu编译安装

  • info
    • qemu-6.2.0.tar.xz
    • Ubuntu server 18.04
  • 编译
    • 依赖:sudo apt-get install -y ninja-build libglib2.0-dev libpixman-1-dev libcap-dev libcap-ng-dev libattr1 libattr1-dev libgtk2.0-dev
    • mkdir outs; cd qemu-6.2.0/
    • ./configure --prefix=/home/aldrich/codespace/qemu.arm64/outs --enable-virtfs
      • –prefix 配置编译完成时输出文件目录
      • –static enable static build
      • –enable-vnc enable VNC
    • make -j $(nproc)
    • make install
  • 输出
    • 编译后配置环境变量,vim ~/.bashrc
      • export PATH=$PATH:/usr/local/lib/qemu6/bin

A.2 qemu虚拟网桥

使用qemu时有时候需要启用虚拟网桥,配置脚本如下,重启失效

#!/bin/bash
#
# sudo apt install -y uml-utilities bridge-utils
#    bridge-utils   虚拟网桥工具
#    uml-utilities  UML(User-mode linux)工具
#
# 要桥接的宿主机网卡:enp0s3
netcard=enp0s3

if [[ $1 = "on" ]]; then
	#先关闭eth0接口
	sudo ifconfig ${netcard} down
	#创建虚拟网桥
	sudo brctl addbr br0
	#在br0中添加一个接口${netcard}
	sudo brctl addif br0 ${netcard}
	#只有一个网桥,所以关闭生成树协议
	sudo brctl stp br0 off
	#设置br0的转发延迟
	sudo brctl setfd br0 1
	#设置br0的hello时间
	sudo brctl sethello br0 1
	#创建一个tap0接口,只允许当前用户访问
	sudo tunctl -t tap0 -u `whoami`
	#在虚拟网桥中增加一个tap0接口
	sudo brctl addif br0 tap0
	#打开br0接口
	sudo ifconfig br0 0.0.0.0 promisc up
	#打开${netcard}接口
	sudo ifconfig ${netcard} 0.0.0.0 promisc up
	#打开tap0接口
	sudo ifconfig tap0 0.0.0.0 promisc up
	#从dhcp服务器获得br0的IP地址
	sudo dhclient br0
	#没有dhcp时,也可配置静态IP并路由
	# sudo ifconfig br0 192.168.0.133 netmask 255.255.255.0
	# sudo route add -net 0.0.0.0 netmask 0.0.0.0 gw 192.168.0.254
	#查看虚拟网桥列表
	#sudo brctl show br0
	#查看br0的各接口信息
	#sudo brctl showstp br0
	#ifconfig -a
else
	#从虚拟网桥中删除tap0
	sudo brctl delif br0 tap0
	#删除tap0接口
	sudo tunctl -d tap0
	#从虚拟网桥中删除${netcard}
	sudo brctl delif br0 ${netcard}
	#关闭br0
	sudo ifconfig br0 down
	#删除br0
	sudo brctl delbr br0
	#开启${netcard}
	sudo ifconfig ${netcard} up
	#检测是否自动给${netcard}分配IP,若没有则自动获取
	sudo dhclient -v ${netcard}
fi

A.3 tmp

#!/bin/bash

cur=${1:-`pwd`}
busybox=${cur}/busybox-1.34.1
linux=${cur}/kernel-4.14.112
rootfs=${cur}/rootfs
rootfsimg=${cur}/hda-rootfs_ext4.img
shdir=${cur}/sharedir
gcclib=/usr/local/lib/gcc-linaro-7.2.1-2017.11-x86_64_aarch64-linux-gnu/aarch64-linux-gnu/libc/lib

dd if=/dev/zero of=${rootfsimg} bs=1M count=128 oflag=direct
mkfs.ext4 ${rootfsimg}

[[ ! -d ${shdir} ]] && mkdir ${shdir}
[[ -d rootfs ]] && rm -rf ${rootfs}
mkdir ${rootfs}

sudo mount ${rootfsimg} ${rootfs}
sudo cp -raf ${busybox}/_install/* ${rootfs}

sudo mkdir -p ${rootfs}/{
    
    proc,sys,tmp,root,var,mnt,dev/pts,etc/udhcpc,lib}
sudo mknod ${rootfs}/dev/tty1 c 4 1
sudo mknod ${rootfs}/dev/tty2 c 4 2
sudo mknod ${rootfs}/dev/tty3 c 4 3
sudo mknod ${rootfs}/dev/tty4 c 4 4
sudo mknod ${rootfs}/dev/console c 5 1
sudo mknod ${rootfs}/dev/null c 1 3

sudo cp -r ${busybox}/examples/bootfloppy/etc/ ${rootfs}
sudo cp -r ${busybox}/examples/udhcp/simple.script ${rootfs}/etc/udhcpc/default.script
#busybox动态库
sudo cp -f ${gcclib}/libm.so.6 ${rootfs}/lib
sudo cp -f ${gcclib}/libm-2.25.so ${rootfs}/lib
sudo cp -f ${gcclib}/libc.so.6 ${rootfs}/lib
sudo cp -f ${gcclib}/libc-2.25.so ${rootfs}/lib
sudo cp -f ${gcclib}/libresolv.so.2 ${rootfs}/lib
sudo cp -f ${gcclib}/libresolv-2.25.so ${rootfs}/lib
sudo cp -f ${gcclib}/ld-linux-aarch64.so.1 ${rootfs}/lib
sudo cp -f ${gcclib}/ld-2.25.so ${rootfs}/lib
# 自动挂载共享目录
sudo chmod 777 ${rootfs}/etc/init.d/rcS
sudo echo "mount -t 9p -o trans=virtio,version=9p2000.L hostshare /mnt" >> ${rootfs}/etc/init.d/rcS
sudo echo "ifconfig eth0 up" >> ${rootfs}/etc/init.d/rcS
sudo echo "ifconfig eth0 10.0.2.155 netmask 255.255.255.0;route add default gw 10.0.2.2" >> ${rootfs}/etc/init.d/rcS
#
sudo chmod 777 ${rootfs}/etc/profile
sudo echo "alias remount=\"cd;umount /tmp;mount -t nfs 10.0.2.15:/home/aldrich/codeSpace/qemu.arm64/app/yadichuli /tmp -o nolock;export LD_LIBRARY_PATH=/tmp/user/lib;cd /tmp/outs\"" >> ${rootfs}/etc/profile

sudo umount ${rootfs};
rm -rf ${rootfs}

qemu-system-aarch64 -M virt -cpu cortex-a57 -smp 4 -m 2048M \
	-kernel ${linux}/arch/arm64/boot/Image \
	-append "root=/dev/vda console=ttyAMA0 rootfstype=ext4 init=/linuxrc rw" \
	-nographic -hda ${rootfsimg}  \
	-nic tap,id=n0,ifname=tap0,script=no,downscript=no \
	-fsdev local,security_model=passthrough,id=fsdev0,path=${shdir} \
	-device virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=hostshare

–end

猜你喜欢

转载自blog.csdn.net/tianzong2019/article/details/121481792