Qemu是一款开源免费的仿真软件 ,跟VMware station类似,可以仿真一台虚拟的电脑,然后在这个电脑上安装各种操作系统、运行各种应用程序。Qemu和VMware station不同的是,除了可以仿真一台电脑外,它还支持仿真一系列嵌入式开发板(支持ARM、MIPS、RISC-V等各种架构),模拟的开发板支持各种外设:串口、LCD、网卡、USB、SD卡等,可以在这个开发板上运行U-boot+Linux+Rootfs。对于缺少开发板学习嵌入式、研究U-boot、Linux内核的朋友,可以考虑使用qemu 来搭建一块虚拟的开发板,方便快捷、经济实惠
环境搭建
开发环境介绍
名称
版本
工具包
操作系统
Ubuntu2204
Qemu
6.2.0
交叉编译工具链
11.4.0
Linux内核
5.10.186
U-boot
2022.07-rc3
busybox
1.36.1
Ubuntu22.0切换软件源
1 2 3 4 5 6 7 8 9 10 11 sudo cp /etc/apt/sources.list /etc/apt/sources.list.baksudo vi /etc/apt/sources.list deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-security main restricted universe multiverse sudo apt update
配置安装交叉编译环境
1 2 3 sudo apt install -y gcc-arm-linux-gnueabisudo apt install -y g++-arm-linux-gnueabisudo apt install -y build-essential openssh-server vim net-tools flex bison libncurses-dev libssl-dev u-boot-tools
搭建qemu运行环境
1 2 3 4 5 6 7 8 9 10 11 12 sudo apt-get -y install zlib1g-dev sudo apt-get -y install libglib2.0-0sudo apt-get -y install libglib2.0-devsudo apt-get -y install libtoolsudo apt-get -y install libsdl1.2-devsudo apt-get -y install libpixman-1-0sudo apt-get -y install libpixman-1-devsudo apt-get -y install autoconf sudo apt install -y qemu-system
检查环境搭建是否成功
交叉编译工具链
1 2 3 4 5 6 7 8 9 10 sun@ldspdvs:~$ arm-linux-gnueabi-gcc -v Using built-in specs. COLLECT_GCC=arm-linux-gnueabi-gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc-cross/arm-linux-gnueabi/11/lto-wrapper Target: arm-linux-gnueabi Configured with: ../src/configure -v --with-pkgversion='Ubuntu 11.4.0-1ubuntu1~22.04' --with-bugurl=file:///usr/share/doc/gcc-11/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-11 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libitm --disable-libquadmath --disable-libquadmath-support --enable-plugin --with-system-zlib --enable-libphobos-checking=release --without-target-system-zlib --enable-multiarch --disable-sjlj-exceptions --with-specs='%{mfloat-abi=hard:-march=armv7-a -mcpu=generic-armv7-a -mfloat-abi=hard}' --with-arch=armv5t --with-float=soft --disable-werror --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=arm-linux-gnueabi --program-prefix=arm-linux-gnueabi- --includedir=/usr/arm-linux-gnueabi/include --with-build-config=bootstrap-lto-lean --enable-link-serialization=2 Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04) sun@ldspdvs:~$
虚拟开发板QEMU
1 2 3 4 sun@ldspdvs:~$ qemu-system-arm --version QEMU emulator version 6.2.0 (Debian 1:6.2+dfsg-2ubuntu6.16) Copyright (c) 2003-2021 Fabrice Bellard and the QEMU Project developers sun@ldspdvs:~$
编译Linux内核
建立workspace工作空间
1 sudo mkdir -p /home/workspace/objects
获取Linux内核源码
1 2 cd /home/workspacesudo wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.10.186.tar.xz
解压Linux内核源码
1 sudo tar -xvf linux-5.10.186.tar.xz
编译Linux内核源码
进入源码根目录
创建automake_arm32.sh(笔者的电脑是12核CPU所以采用-j12进行编译,读者编译过程中可根据实际情况进行调整)
1 2 3 4 5 6 7 8 9 sun@ldspdvs:/home/workspace/linux-5.10.186$ sudo touch automake_arm32.sh sun@ldspdvs:/home/workspace/linux-5.10.186$ sudo chmod 777 automake_arm32.sh sun@ldspdvs:/home/workspace/linux-5.10.186$ vim automake_arm32.sh make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- vexpress_defconfig O=../objects/vexpress-v2p-ca9 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig O=../objects/vexpress-v2p-ca9 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j12 O=../objects/vexpress-v2p-ca9 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- LOADADDR=0x60003000 uImage -j12 O=../objects/vexpress-v2p-ca9
运行automake_arm32.sh编译
编译过程可能出现以下界面,即menuconfig,目前阶段不关注,按两下Esc退出这个界面继续编译即可
在Qemu试运行Linux内核源码
进入objects目录
1 cd /home/workspace/objects
创建qemu-start-vexpress-a9.sh
1 2 3 4 5 6 7 8 9 10 sun@ldspdvs:/home/workspace/objects$ sudo touch qemu-start-vexpress-a9.sh sun@ldspdvs:/home/workspace/objects$ sudo chmod 777 qemu-start-vexpress-a9.sh sun@ldspdvs:/home/workspace/objects$ vim qemu-start-vexpress-a9.sh qemu-system-arm -M vexpress-a9 \ -m 512M \ -kernel vexpress-v2p-ca9/arch/arm/boot/zImage \ -dtb vexpress-v2p-ca9/arch/arm/boot/dts/vexpress-v2p-ca9.dtb \ -nographic
Linux内核启动过程会打印大量信息,最后因为没挂载根文件系统导致
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.10.186 Hardware name: ARM-Versatile Express [<8010f264>] (unwind_backtrace) from [<8010afb4>] (show_stack+0x10/0x14) [<8010afb4>] (show_stack) from [<80881254>] (dump_stack+0x94/0xa8) [<80881254>] (dump_stack) from [<8087d0b4>] (panic+0x124/0x32c) [<8087d0b4>] (panic) from [<80b017a8>] (mount_block_root+0x1e8/0x26c) [<80b017a8>] (mount_block_root) from [<80b01aec>] (prepare_namespace+0x150/0x18c) [<80b01aec>] (prepare_namespace) from [<80885f8c>] (kernel_init+0x8/0x118) [<80885f8c>] (kernel_init) from [<80100148>] (ret_from_fork+0x14/0x2c) Exception stack(0x810b9fb0 to 0x810b9ff8) 9fa0: 00000000 00000000 00000000 00000000 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000 ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) ]---
挂载根文件系统
根文件系统 首先是内核启动时所mount的第一个文件系统,内核代码映像文件保存在根文件系统中,而系统引导启动程序会在根文件系统挂载之后从中把一些基本的初始化脚本和服务等加载到内存中去运行。本节将介绍如何编译和制作Linux最小系统的根文件系统,并通过sd卡或者nfs挂载根文件系统。
编译、安装根文件系统
下载并解压busybox源码
1 2 3 cd /home/workspacesudo wget https://busybox.net/downloads/busybox-1.36.1.tar.bz2sudo tar -xvf busybox-1.36.1.tar.bz2
自动编译脚本
制作automake_arm32.sh自动编译脚本
1 2 3 4 5 6 7 8 9 10 11 12 cd busybox-1.36.1sun@ldspdvs:/home/workspace/busybox-1.36.1$ sudo touch automake_arm32.sh sun@ldspdvs:/home/workspace/busybox-1.36.1$ sudo chmod 777 automake_arm32.sh sun@ldspdvs:/home/workspace/busybox-1.36.1$ vim automake_arm32.sh make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- clean make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j12 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- CONFIG_PREFIX=../objects/rootfs-arm32 install
编译过程中会出现menuconfig界面,需要将“Settings->Build Options->Build static binary”选上
补充根文件夹系统
busybox编译完成后,只是初步具有了维持linux操作系统基本运行所需的可执行文件,还有设备节点、动态链接库、引导启动相关代码、用户相关信息等,需要根据开发板自身的特性做定制和适配,接下来将适配vexpress-a9开发板补充根文件系统相关内容
进入根文件系统目录
1 cd /home/workspace/objects/rootfs-arm32
创建设备节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 sun@ldspdvs:/home/workspace/objects/rootfs-arm32$ sudo mkdir dev sun@ldspdvs:/home/workspace/objects/rootfs-arm32$ sudo mknod -m 666 dev/tty1 c 4 1 sudo mknod -m 666 dev/tty2 c 4 2sudo mknod -m 666 dev/tty3 c 4 3sudo mknod -m 666 dev/tty4 c 4 4sudo mknod -m 666 dev/console c 5 1sudo mknod -m 666 dev/null c 1 3sun@ldspdvs:/home/workspace/objects/rootfs-arm32$ ll dev 总计 8 drwxr-xr-x 2 root root 4096 1月 21 23:12 ./ drwxr-xr-x 6 root root 4096 1月 21 23:12 ../ crw-rw-rw- 1 root root 5, 1 1月 21 23:12 console crw-rw-rw- 1 root root 1, 3 1月 21 23:12 null crw-rw-rw- 1 root root 4, 1 1月 21 23:12 tty1 crw-rw-rw- 1 root root 4, 2 1月 21 23:12 tty2 crw-rw-rw- 1 root root 4, 3 1月 21 23:12 tty3 crw-rw-rw- 1 root root 4, 4 1月 21 23:12 tty4 sun@ldspdvs:/home/workspace/objects/rootfs-arm32$
安装动态链接库
1 2 sun@ldspdvs:/home/workspace/objects/rootfs-arm32$ sudo mkdir lib sun@ldspdvs:/home/workspace/objects/rootfs-arm32$ sudo cp -d /usr/arm-linux-gnueabi/lib/*.so* ./lib
配置初始化进程rcS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 sudo mkdir -p etc/init.dsudo touch etc/init.d/rcSsudo chmod 777 etc/init.d/rcSvim etc/init.d/rcS PATH=/bin:/sbin:/usr/bin:/usr/sbin export LD_LIBRARY_PATH=/lib:/usr/lib/bin/mount -n -t ramfs ramfs /var /bin/mount -n -t ramfs ramfs /tmp /bin/mount -n -t sysfs none /sys /bin/mount -n -t ramfs none /dev /bin/mkdir /var/tmp /bin/mkdir /var/modules /bin/mkdir /var/run /bin/mkdir /var/log /bin/mkdir -p /dev/pts /bin/mkdir -p /dev/shm /sbin/mdev -s /bin/mount -a echo "-----------------------------------" echo "*****welcome to vexpress board*****" echo "-----------------------------------"
配置文件系统fstab
1 2 3 4 5 6 7 8 9 10 11 12 13 14 sudo touch etc/fstabsudo chmod 777 etc/fstabvim etc/fstab proc /proc proc defaults 0 0 none /dev/pts devpts mode=0622 0 0 mdev /dev ramfs defaults 0 0 sysfs /sys sysfs defaults 0 0 tmpfs /dev/shm tmpfs defaults 0 0 tmpfs /dev tmpfs defaults 0 0 tmpfs /mnt tmpfs defaults 0 0 var /dev tmpfs defaults 0 0 ramfs /dev ramfs defaults 0 0
配置初始化脚本
1 2 3 4 5 6 7 8 9 10 sudo touch etc/inittabsudo chmod 777 etc/inittab vim etc/inittab ::sysinit:/etc/init.d/rcS ::askfirst:-/bin/sh ::restart:/sbin/init ::ctrlaltdel:/sbin/reboot ::shutdown:/bin/umount -a -r
配置环境变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 sudo touch etc/profilesudo chmod 777 etc/profilevim etc/profile USER="root" LOGNAME=$USER export HOSTNAME=`cat /etc/sysconfig/HOSTNAME`export USER=rootexport HOME=rootexport 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
增加主机名
1 2 3 4 5 6 sudo mkdir etc/sysconfigsudo chmod 777 etc/sysconfigvim etc/sysconfig/HOSTNAME vexpress-a9
创建其他文件夹
1 sudo mkdir mnt proc root sys tmp var
查看创建的文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 sun@ldspdvs:/home/workspace/objects/rootfs-arm32$ ll 总计 56 drwxr-xr-x 14 root root 4096 1月 21 23:24 ./ drwxr-xr-x 4 root root 4096 1月 21 23:09 ../ drwxr-xr-x 2 root root 4096 1月 21 23:09 bin/ drwxr-xr-x 2 root root 4096 1月 21 23:12 dev/ drwxr-xr-x 4 root root 4096 1月 21 23:23 etc/ drwxr-xr-x 2 root root 4096 1月 21 23:14 lib/ lrwxrwxrwx 1 root root 11 1月 21 23:09 linuxrc -> bin/busybox* drwxr-xr-x 2 root root 4096 1月 21 23:24 mnt/ drwxr-xr-x 2 root root 4096 1月 21 23:24 proc/ drwxr-xr-x 2 root root 4096 1月 21 23:24 root/ drwxr-xr-x 2 root root 4096 1月 21 23:09 sbin/ drwxr-xr-x 2 root root 4096 1月 21 23:24 sys/ drwxr-xr-x 2 root root 4096 1月 21 23:24 tmp/ drwxr-xr-x 4 root root 4096 1月 21 23:09 usr/ drwxr-xr-x 2 root root 4096 1月 21 23:24 var/ sun@ldspdvs:/home/workspace/objects/rootfs-arm32$
通过SD卡挂载根文件系统
自动打包脚本
编译安装完成后,进入object目录,并制作自动打包脚本makefs-arm32.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 cd /home/workspace/objectssudo mkdir /mnt/rootfssudo chmod 777 /mnt/rootfssudo touch makefs-arm32.shsudo chmod 777 makefs-arm32.shvim makefs-arm32.sh dd if =/dev/zero of=rootfs-arm32.ext3 bs=1M count=64mkfs.ext3 rootfs-arm32.ext3 sudo mount -t ext3 rootfs-arm32.ext3 /mnt/rootfs -o loopsudo cp -rf rootfs-arm32/* /mnt/rootfs/sudo umount /mnt/rootfs/
运行自动打包脚本makefs-arm32.sh ,运行完成后将在objects目录下生成一个rootfs-arm32.ext3文件,将作为外设sd卡加入到开发板上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 sun@ldspdvs:/home/workspace/objects$ ll 总计 20 drwxr-xr-x 4 root root 4096 1月 21 23:31 ./ drwxr-xr-x 5 root root 4096 1月 21 23:04 ../ -rwxrwxrwx 1 root root 202 1月 21 23:32 makefs-arm32.sh* drwxr-xr-x 14 root root 4096 1月 21 23:24 rootfs-arm32/ drwxr-xr-x 21 root root 4096 1月 21 22:57 vexpress-v2p-ca9/ sun@ldspdvs:/home/workspace/objects$ sudo ./makefs-arm32.sh 记录了64+0 的读入 记录了64+0 的写出 67108864字节(67 MB,64 MiB)已复制,0.0487807 s,1.4 GB/s mke2fs 1.46.5 (30-Dec-2021) 丢弃设备块: 完成 创建含有 16384 个块(每块 4k)和 16384 个 inode 的文件系统 正在分配组表: 完成 正在写入 inode表: 完成 创建日志(1024 个块): 完成 写入超级块和文件系统账户统计信息: 已完成 sun@ldspdvs:/home/workspace/objects$ sudo chmod 777 rootfs-arm32.ext3 sun@ldspdvs:/home/workspace/objects$ ll 总计 21108 drwxr-xr-x 4 root root 4096 1月 21 23:34 ./ drwxr-xr-x 5 root root 4096 1月 21 23:04 ../ -rwxrwxrwx 1 root root 202 1月 21 23:32 makefs-arm32.sh* drwxr-xr-x 14 root root 4096 1月 21 23:24 rootfs-arm32/ -rwxrwxrwx 1 root root 67108864 1月 21 23:34 rootfs-arm32.ext3* drwxr-xr-x 21 root root 4096 1月 21 22:57 vexpress-v2p-ca9/ sun@ldspdvs:/home/workspace/objects$
挂载根文件系统
修改qemu-start-vexpress-a9.sh
1 2 3 4 5 6 7 8 9 10 11 sun@ldspdvs:/home/workspace/objects$ vim qemu-start-vexpress-a9.sh qemu-system-arm -M vexpress-a9 \ -m 512M \ -kernel vexpress-v2p-ca9/arch/arm/boot/zImage \ -dtb vexpress-v2p-ca9/arch/arm/boot/dts/vexpress-v2p-ca9.dtb \ -nographic \ -append "root=/dev/mmcblk0 rw console=ttyAMA0" \ -sd rootfs-arm32.ext3
出现下述内容代表启动成功
通过NFS挂载根文件系统
在进行软件调试的过程中,我们经常需与开发板交换文件,或者直接修改板子上的配置文件,如果使用SD卡挂载根文件系统,则每次进行文件交换都需要重启操作系统。为了提高开发效率,我们可以通过NFS共享主机上的根文件系统给开发板,实现在主机上修改完善代码并编译后,直接在开发板上运行,无缝对接。
安装NFS服务器
安装
1 sudo apt install -y nfs-kernel-server
配置
1 2 3 4 5 6 7 8 sudo mkdir -p /sync/rootfssudo chmod 777 /etc/exportssudo vim /etc/exports /sync/rootfs *(rw,sync ,no_root_squash,no_subtree_check)
重启NFS服务器
1 2 sudo /etc/init.d/rpcbind restartsudo /etc/init.d/nfs-kernel-server restart
将安装好的根文件系统拷贝到/sync/rootfs内
1 2 3 cd /home/workspace/objects/rootfs-arm32sudo cp -rf * /sync/rootfs/sudo chmod 777 -R /sync/rootfs
内核NFS兼容问题
为解决Linux内核与NFS服务器的兼容问题,目前有两种方案供读者参考,实在不行可以把两种都用上
位置:File System -> Network File Systems->NFS client support for NFS version 4
设置Ubuntu2204,使之兼容NFS-V2和NFS-V3并增加调试功能
1 2 3 4 5 6 7 8 9 sudo vim /etc/default/nfs-kernel-server RPCSVCGSSDOPTS="--nfs-version 2,3,4 --debug --syslog" sudo /etc/init.d/rpcbind restartsudo /etc/init.d/nfs-kernel-server restart
测试NFS挂载根文件系统
配置主机网桥(其中eth0是Ubuntu系统的网卡 ,根据实际调整)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 sudo apt install -y uml-utilities bridge-utilssudo vim /etc/network/interfaces auto lo iface lo inet loopback auto eth0 auto br0 iface br0 inet dhcp bridge_ports eth0 ==================================================================================== sun@ldspdvs:/home/workspace/objects/rootfs-arm32$ ifconfig ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.58.146 netmask 255.255.255.0 broadcast 192.168.58.255 inet6 fe80::d763:3d05:1073:739c prefixlen 64 scopeid 0x20<link > ether 00:0c:29:f3:7c:aa txqueuelen 1000 (以太网) RX packets 272895 bytes 394360550 (394.3 MB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 14324 bytes 1257519 (1.2 MB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (本地环回) RX packets 464 bytes 44975 (44.9 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 464 bytes 44975 (44.9 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 sun@ldspdvs:/home/workspace/objects/rootfs-arm32$ sudo vim /etc/network/interfaces sun@ldspdvs:/home/workspace/objects/rootfs-arm32$ cat /etc/network/interfaces auto lo iface lo inet loopback auto ens33 auto br0 iface br0 inet dhcp bridge_ports ens33 sun@ldspdvs:/home/workspace/objects/rootfs-arm32$
创建tap0网卡,用于连接qemu虚拟开发板
1 2 sudo tunctl -u root -t tap0sudo ifconfig tap0 172.16.16.10 promisc up
创建qemu-start-vexpress-a9-nfs.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 cd /home/workspace/objectssudo touch qemu-start-vexpress-a9-nfs.shsudo chmod 777 qemu-start-vexpress-a9-nfs.shvim qemu-start-vexpress-a9-nfs.sh sudo qemu-system-arm \ -M vexpress-a9 \ -m 512M \ -kernel vexpress-v2p-ca9/arch/arm/boot/zImage \ -dtb vexpress-v2p-ca9/arch/arm/boot/dts/vexpress-v2p-ca9.dtb \ -net tap,ifname=tap0,script=no,downscript=no \ -net nic,macaddr=00:16:3e:00:00:01 \ -nographic \ -append "root=/dev/nfs rw nfsroot=172.16.16.10:/sync/rootfs,proto=tcp,nfsvers=3,nolock init=/linuxrc console=ttyAMA0 ip=172.16.16.20" \ sun@ldspdvs:/home/workspace/objects$ sudo ./qemu-start-vexpress-a9-nfs.sh
启动成功后如下所示
通过U-boot引导加载内核
编译安装U-boot
下载解压U-boot源码
1 2 3 cd /home/workspacewget https://ftp.denx.de/pub/u-boot/u-boot-2022.07-rc3.tar.bz2 tar -xvf u-boot-2022.07-rc3.tar.bz2
制作automake_arm32.sh
1 2 3 4 5 6 7 8 9 10 cd u-boot-2022.07-rc3vim automake_arm32.sh make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- vexpress_ca9x4_defconfig O=../objects/u-boot-arm make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig O=../objects/u-boot-arm make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j12 O=../objects/u-boot-arm
运行automake_arm32.sh编译安装U-Boot
出现下述内容证明U-Boot编译完毕
配置主机tftp服务器
安装tftp服务器
1 sudo apt-get install tftp-hpa tftpd-hpa xinetd
配置tftp路径文件
1 2 3 4 5 6 7 8 9 10 sudo mkdir -p /sync/tftpsudo chmod 777 /sync/tftpsudo touch /etc/default/tftpd-hpasudo vim /etc/default/tftpd-hpa TFTP_USERNAME="tftp" TFTP_DIRECTORY="/sync/tftp" TFTP_ADDRESS="0.0.0.0:69" TFTP_OPTIONS="-l -c -s"
重启tftp服务器
1 sudo /etc/init.d/tftpd-hpa restart
系统开机自动tftp服务
1 2 3 4 systemctl enable tftpd-hpa.service tftpd-hpa.service is not a native service, redirecting to systemd-sysv-install. Executing: /lib/systemd/systemd-sysv-install enable tftpd-hpa jcrj@SQA-JCRJ-01:~/qemu_arm_a9/workspace/u-boot-2022.07-rc3$
将设备树和Linux内核文件拷贝到tftp目录下
1 2 3 cd /home/workspace/objectssudo cp vexpress-v2p-ca9/arch/arm/boot/dts/vexpress-v2p-ca9.dtb /sync/tftp/sudo cp vexpress-v2p-ca9/arch/arm/boot/uImage /sync/tftp/
虚拟主机网络配置,创建tap0网卡,用于连接qemu虚拟开发板
此处已在测试NFS挂载根文件系统中设置过
1 2 sudo tunctl -u root -t tap0sudo ifconfig tap0 172.16.16.10 promisc up
试运行U-boot
创建qemu-start-uboot-arm32-uboot-manual.sh 脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 cd /home/workspace/objectssudo touch qemu-start-uboot-arm32-uboot-manual.shsudo chmod 777 qemu-start-uboot-arm32-uboot-manual.shvim qemu-start-uboot-arm32-uboot-manual.sh sudo qemu-system-arm \ -M vexpress-a9 \ -m 512M \ -kernel u-boot-arm/u-boot \ -net tap,ifname=tap0,script=no,downscript=no \ -net nic,macaddr=00:16:3e:00:00:01 \ -nographic \
运行脚本
1 ./qemu-start-uboot-arm32.sh
出现以下界面,说明运行成功(注意在Hit any key to stop autoboot出现时按任意键进入命令行)
在U-Boot命令行下输入以下代码,尝试引导内核
1 2 3 4 5 6 7 8 9 setenv bootargs 'root=/dev/nfs rw nfsroot=172.16.16.10:/sync/rootfs,proto=tcp,nfsvers=3,nolock init=/linuxrc console=ttyAMA0 ip=172.16.16.20' setenv ipaddr 172.16.16.20 setenv serverip 172.16.16.10 setenv netmask 255.255.0.0 saveenv tftp 60003000 uImage tftp 60500000 vexpress-v2p-ca9.dtb bootm 60003000 - 60500000
实际
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 jcrj@SQA-JCRJ-01:~/qemu_arm_a9/workspace/objects$ sudo ./qemu-start-uboot-arm32-uboot-manual.sh U-Boot 2022.07-rc3 (Jan 22 2024 - 13:51:57 +0800) DRAM: 512 MiB WARNING: Caches not enabled Core: 19 devices, 10 uclasses, devicetree: embed Flash: 64 MiB MMC: mmci@5000: 0 Loading Environment from Flash... *** Warning - bad CRC, using default environment In: serial Out: serial Err: serial Net: eth0: ethernet@3,02000000 Hit any key to stop autoboot: 0 => setenv bootargs 'root=/dev/nfs rw nfsroot=172.16.16.10:/sync/rootfs,proto=tcp,nfsvers=3,nolock init=/linuxrc console=ttyAMA0 ip=172.16.16.20' => setenv ipaddr 172.16.16.20 => setenv serverip 172.16.16.10 => setenv netmask 255.255.0.0 => saveenv Saving Environment to Flash... Error: start and/or end address not on sector boundary Error: start and/or end address not on sector boundary Failed (1) => => => tftp 60003000 uImage smc911x: detected LAN9118 controller smc911x: phy initialized smc911x: MAC 00:16:3e:00:00:01 Using ethernet@3,02000000 device TFTP from server 172.16.16.10; our IP address is 172.16.16.20 Filename 'uImage' . Load address: 0x60003000 Loading: 27.6 MiB/s done Bytes transferred = 4886088 (4a8e48 hex) smc911x: MAC 00:16:3e:00:00:01 => tftp 60500000 vexpress-v2p-ca9.dtb smc911x: detected LAN9118 controller smc911x: phy initialized smc911x: MAC 00:16:3e:00:00:01 Using ethernet@3,02000000 device TFTP from server 172.16.16.10; our IP address is 172.16.16.20 Filename 'vexpress-v2p-ca9.dtb' . Load address: 0x60500000 Loading: 6.8 MiB/s done Bytes transferred = 14171 (375b hex) smc911x: MAC 00:16:3e:00:00:01 => bootm 60003000 - 60500000 Image Name: Linux-5.10.186 Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 4886024 Bytes = 4.7 MiB Load Address: 60003000 Entry Point: 60003000 Verifying Checksum ... OK Booting using the fdt blob at 0x60500000 Loading Kernel Image Loading Device Tree to 7fb1d000, end 7fb2375a ... OK Starting kernel ... Booting Linux on physical CPU 0x0 Linux version 5.10.186 (jcrj@SQA-JCRJ-01) (arm-linux-gnueabi-gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0, GNU ld (GNU Binutils for Ubuntu) 2.38) CPU: ARMv7 Processor [410fc090] revision 0 (ARMv7), cr=10c5387d CPU: PIPT / VIPT nonaliasing data cache, VIPT nonaliasing instruction cache OF: fdt: Machine model: V2P-CA9 OF: fdt: Ignoring memory block 0x80000000 - 0x80000004 ........ ........ Freeing unused kernel memory: 1024K Run /linuxrc as init process ----------------------------------- *****welcome to vexpress board***** ----------------------------------- device eth0 entered promiscuous mode Please press Enter to activate this console. [root@vexpress-a9:/]#
出现下面界面证明引导成功
固化U-boot环境变量
在试运行过程中,需要输入代码修改U-boot的环境变量,如果每次启动都需要如此,则太过麻烦。真实开发板由于内置了NAND/MMC Flash,修改后的环境变量可以使用saveenv保存下来,但是我们这部分还没有把NAND/MMC相关支持完全做好。因此需要在U-boot源码上做一些修改,将环境变量固化下来。
修改配置文件
1 2 3 4 5 cd /home/workspace/u-boot-2022.07-rc3vim configs/vexpress_ca9x4_defconfig CONFIG_BOOTCOMMAND="tftp 0x60003000 uImage;tftp 0x60500000 vexpress-v2p-ca9.dtb;setenv bootargs 'root=/dev/nfs rw nfsroot=172.16.16.10:/sync/rootfs,proto=tcp,nfsvers=3,nolock init=/linuxrc ip=172.16.16.20 console=ttyAMA0';bootm 0x60003000 - 0x60500000;"
修改后如下所示
修改头文件
// 在vexpress_common.h文件末尾#endif之前添加以下代码:
1 2 3 4 5 6 vim include/configs/vexpress_common.h // 在vexpress_common.h文件末尾#endif之前添加以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 jcrj@SQA-JCRJ-01:~/qemu_arm_a9/workspace/u-boot-2022.07-rc3$ pwd /home/jcrj/qemu_arm_a9/workspace/u-boot-2022.07-rc3 jcrj@SQA-JCRJ-01:~/qemu_arm_a9/workspace/u-boot-2022.07-rc3$ vim include/configs/vexpress_common.h jcrj@SQA-JCRJ-01:~/qemu_arm_a9/workspace/u-boot-2022.07-rc3$ jcrj@SQA-JCRJ-01:~/qemu_arm_a9/workspace/u-boot-2022.07-rc3$ tail -6 include/configs/vexpress_common.h /* Net Settings */ jcrj@SQA-JCRJ-01:~/qemu_arm_a9/workspace/u-boot-2022.07-rc3$
重新编译U-Boot
1 2 cd /home/workspace/u-boot-2022.07-rc3./automake_arm32.sh
编译完成后,进入Objects目录运行U-boot
1 2 cd /home/workspace/objects./qemu-start-uboot-arm32.sh
运行结果应该与手动引导一致
其他辅助优化功能
虚拟开发板连接互联网
修改rootfs根文件系统
进入根文件系统目录
1 cd /home/workspace/objects/rootfs-arm32
开发板指定DNS服务器
1 2 3 4 5 6 touch etc/resolv.confchmod 777 etc/resolv.confvim etc/resolv.conf nameserver 114.114.114.114
开发板初始化规则配置
1 2 3 4 5 vim etc/init.d/rcS ifconfig eth0 172.16.16.20 promisc up route add default gw 172.16.16.10 dev eth0
将修改后的根文件系统拷贝到 /sync/rootfs内
1 2 3 cd /home/workspace/objects/rootfs-arm32sudo cp -rf * /sync/rootfs/sudo chmod 777 -R /sync/rootfs
修改主机配置
虚拟开发板访问互联网,不仅需要修改开发板相关配置文件,同时也需要对主机进行进一步操作,包括开启IP转发、配置静态路由、配置iptable规则等。
主机开启IP转发
主机配置tap虚拟网卡
运行脚本
U-boot+emmc启动
在第四部分《通过U-boot引导加载内核》中,我们发现U-boot的环境变量修改后无法保存,需要修改源代码来固化环境变量,对启动参数的修改造成了不便。因此本节将继续深入探讨如何将U-boot的环境变量存储在emmc内,同时使用emmc存储Linux内核、设备树以及根文件系统,并在此基础上尝试引导启动最小Linux操作系统。
制作emmc镜像文件
本节制作的emmc镜像文件共256MB,分为两个部分,第一部分存放uImage和dtb,大小为32MB,第二部分存放根文件系统,大小为224MB。
创建挂载路径
1 2 sudo mkdir /mnt/rootfssudo mkdir /mnt/uboot
创建自动打包脚本
将/home/workspace/objects下makefs-arm32.sh的内容替换为以下内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 cd /home/workspace/objectsvim makefs-arm32.sh dd if =/dev/zero of=rootfs-arm.ext3 bs=1M count=256 echo "hard disk partition!" sgdisk -n 0:0:+32M -c 0:uboot rootfs-arm.ext3 sgdisk -n 0:0:0 -c 0:rootfs rootfs-arm.ext3 sgdisk -p rootfs-arm.ext3 echo "mount loop device!" LOOPDEV=`losetup -f` echo $LOOPDEV sudo losetup $LOOPDEV rootfs-arm.ext3sudo partprobe $LOOPDEV sudo losetup -lls -l /dev/loop* echo "format disk to ext3" echo ${LOOPDEV} p1echo ${LOOPDEV} p2sudo mkfs.ext3 ${LOOPDEV} p1sudo mkfs.ext3 ${LOOPDEV} p2sudo mount -t ext3 ${LOOPDEV} p1 /mnt/uboot -o loopsudo mount -t ext3 ${LOOPDEV} p2 /mnt/rootfs -o loopsudo cp -rf rootfs-arm32/* /mnt/rootfs/sudo cp vexpress-v2p-ca9/arch/arm/boot/dts/vexpress-v2p-ca9.dtb /mnt/uboot/sudo cp vexpress-v2p-ca9/arch/arm/boot/uImage /mnt/uboot/sudo umount /mnt/rootfs/sudo umount /mnt/uboot/sudo losetup -d $LOOPDEV
运行自动打包脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 jcrj@SQA-JCRJ-01:~/qemu_arm_a9/workspace/objects$ sudo ./makefs-arm32.sh 记录了256+0 的读入 记录了256+0 的写出 268435456字节(268 MB,256 MiB)已复制,0.18134 s,1.5 GB/s hard disk partition! Creating new GPT entries in memory. Setting name! partNum is 0 Warning: The kernel is still using the old partition table. The new table will be used at the next reboot or after you run partprobe(8) or kpartx(8) The operation has completed successfully. Setting name! partNum is 1 Warning: The kernel is still using the old partition table. The new table will be used at the next reboot or after you run partprobe(8) or kpartx(8) The operation has completed successfully. Disk rootfs-arm.ext3: 524288 sectors, 256.0 MiB Sector size (logical): 512 bytes Disk identifier (GUID): 3C81BB8A-E76E-49AF-B920-1DC5B7EF6B72 Partition table holds up to 128 entries Main partition table begins at sector 2 and ends at sector 33 First usable sector is 34, last usable sector is 524254 Partitions will be aligned on 2048-sector boundaries Total free space is 2014 sectors (1007.0 KiB) Number Start (sector) End (sector) Size Code Name 1 2048 67583 32.0 MiB 8300 uboot 2 67584 524254 223.0 MiB 8300 rootfs mount loop device! /dev/loop15 NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE DIO LOG-SEC /dev/loop1 0 0 1 1 /var/lib/snapd/snaps/bare_5.snap 0 512 /dev/loop8 0 0 1 1 /var/lib/snapd/snaps/gnome-42-2204_141.snap 0 512 /dev/loop15 0 0 0 0 /home/jcrj/qemu_arm_a9/workspace/objects/rootfs-arm.ext3 0 512 /dev/loop6 0 0 1 1 /var/lib/snapd/snaps/gnome-3-38-2004_143.snap 0 512 /dev/loop13 0 0 1 1 /var/lib/snapd/snaps/snapd-desktop-integration_83.snap 0 512 /dev/loop4 0 0 1 1 /var/lib/snapd/snaps/core22_858.snap 0 512 /dev/loop11 0 0 1 1 /var/lib/snapd/snaps/snapd_19457.snap 0 512 /dev/loop2 0 0 1 1 /var/lib/snapd/snaps/core20_2105.snap 0 512 /dev/loop0 0 0 1 1 /var/lib/snapd/snaps/core20_1974.snap 0 512 /dev/loop9 0 0 1 1 /var/lib/snapd/snaps/gtk-common-themes_1535.snap 0 512 /dev/loop7 0 0 1 1 /var/lib/snapd/snaps/gnome-42-2204_120.snap 0 512 /dev/loop14 0 0 1 1 /var/lib/snapd/snaps/code_149.snap 0 512 /dev/loop5 0 0 1 1 /var/lib/snapd/snaps/firefox_2987.snap 0 512 /dev/loop12 0 0 1 1 /var/lib/snapd/snaps/snapd_20671.snap 0 512 /dev/loop3 0 0 1 1 /var/lib/snapd/snaps/core22_1033.snap 0 512 /dev/loop10 0 0 1 1 /var/lib/snapd/snaps/snap-store_959.snap 0 512 brw-rw---- 1 root disk 7, 0 1月 22 08:56 /dev/loop0 brw-rw---- 1 root disk 7, 1 1月 22 08:56 /dev/loop1 brw-rw---- 1 root disk 7, 10 1月 22 08:56 /dev/loop10 brw-rw---- 1 root disk 7, 11 1月 22 08:56 /dev/loop11 brw-rw---- 1 root disk 7, 12 1月 22 08:56 /dev/loop12 brw-rw---- 1 root disk 7, 13 1月 22 08:56 /dev/loop13 brw-rw---- 1 root disk 7, 14 1月 22 08:56 /dev/loop14 brw-rw---- 1 root disk 7, 15 1月 22 14:57 /dev/loop15 brw-rw---- 1 root disk 259, 3 1月 22 14:57 /dev/loop15p1 brw-rw---- 1 root disk 259, 4 1月 22 14:57 /dev/loop15p2 brw-rw---- 1 root disk 7, 16 1月 22 14:56 /dev/loop16 brw-rw---- 1 root disk 7, 2 1月 22 08:56 /dev/loop2 brw-rw---- 1 root disk 7, 3 1月 22 08:56 /dev/loop3 brw-rw---- 1 root disk 7, 4 1月 22 08:56 /dev/loop4 brw-rw---- 1 root disk 7, 5 1月 22 08:56 /dev/loop5 brw-rw---- 1 root disk 7, 6 1月 22 08:56 /dev/loop6 brw-rw---- 1 root disk 7, 7 1月 22 08:56 /dev/loop7 brw-rw---- 1 root disk 7, 8 1月 22 08:56 /dev/loop8 brw-rw---- 1 root disk 7, 9 1月 22 08:56 /dev/loop9 crw-rw---- 1 root disk 10, 237 1月 22 08:56 /dev/loop-control format disk to ext3 /dev/loop15p1 /dev/loop15p2 mke2fs 1.46.5 (30-Dec-2021) 丢弃设备块: 完成 创建含有 8192 个块(每块 4k)和 8192 个 inode 的文件系统 正在分配组表: 完成 正在写入 inode表: 完成 创建日志(1024 个块): 完成 写入超级块和文件系统账户统计信息: 已完成 mke2fs 1.46.5 (30-Dec-2021) 丢弃设备块: 完成 创建含有 57083 个块(每块 4k)和 57088 个 inode 的文件系统 文件系统 UUID:3e290f2c-d621-4fd0-bb3a-f25fd0dbcd64 超级块的备份存储于下列块: 32768 正在分配组表: 完成 正在写入 inode表: 完成 创建日志(4096 个块): 完成 写入超级块和文件系统账户统计信息: 已完成 jcrj@SQA-JCRJ-01:~/qemu_arm_a9/workspace/objects$
将生成一个256MB大小的镜像文件rootfs-arm.ext3
修改U-boot环境变量的保存位置
上一小节生成的emmc镜像分为两部分,我们把环境变量存储在第一部分最后256KB的位置,以保证它不会与Linux内核和设备树互相干扰。
重新编译U-boot
1 2 cd /home/workspace/u-boot-2022.07-rc3./automake_arm32.sh
在menuconfig界面设置环境变量存储设备,以及环境变量在设备中的具体位置和大小。由于需要将环境变量存储在emmc镜像的第一个分区的最后256KB位置,所以环境变量的设备号为emmc0,分区号为0,偏移量为0x02000000-0x00040000=0x01FC0000,大小为0x00040000。
menuconfig设置路径为:Environment->Environment in an MMC device
修改后,按两下Esc,保存配置,退出menuconfig,等待U-boot编译完成
加载U-boot修改环境变量
创建自动运行脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 cd /home/workspace/objectssudo touch qemu-start-uboot-arm32-emmc.shsudo chmod 777 qemu-start-uboot-arm32-emmc.shvim qemu-start-uboot-arm32-emmc.sh sudo tunctl -u root -t tap0sudo ifconfig tap0 172.16.16.10 promisc upsudo route add -net 172.16.0.0 netmask 255.255.0.0 dev tap0sudo iptables -t nat -A POSTROUTING -s 172.16.0.0/16 -o eth0 -j MASQUERADEsudo netfilter-persistent savesudo qemu-system-arm \ -M vexpress-a9 \ -m 512M \ -kernel u-boot-arm/u-boot \ -net tap,ifname=tap0,script=no,downscript=no \ -net nic,macaddr=00:16:3e:00:00:01 \ -nographic \ -sd rootfs-arm.ext3
运行脚本,在自动挂载倒计时结束前按任意键进入命令行模式
可以看到此时emmc镜像仍未存储环境变量,加载的是默认变量
在U-boot命令行中输入以下命令设置环境变量
1 2 3 setenv bootargs 'root=/dev/mmcblk0p2 rw console=ttyAMA0,38400n8' setenv bootcmd "load mmc 0:1 0x60003000 uImage;load mmc 0:1 0x60500000 vexpress-v2p-ca9.dtb;bootm 0x60003000 - 0x60500000;" saveenv
保存成功后,重新启动U-boot
问题及解决方案
Ubuntu2204网卡丢失
查看本地IP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 jcrj@SQA-JCRJ-01:~$ ifconfig br-593cc1b66d28: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 172.18.0.1 netmask 255.255.0.0 broadcast 172.18.255.255 ether 02:42:e2:a9:db:58 txqueuelen 0 (以太网) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 inet6 fe80::42:43ff:fef5:b4a2 prefixlen 64 scopeid 0x20<link > ether 02:42:43:f5:b4:a2 txqueuelen 0 (以太网) RX packets 369 bytes 25324 (25.3 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 250 bytes 26842 (26.8 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (本地环回) RX packets 1798 bytes 133078 (133.0 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 1798 bytes 133078 (133.0 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 veth948b02a: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet6 fe80::44a5:58ff:fe17:3f7c prefixlen 64 scopeid 0x20<link > ether 46:a5:58:17:3f:7c txqueuelen 0 (以太网) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 83 bytes 9130 (9.1 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 vethde0c1ce: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet6 fe80::3415:67ff:feac:e7a6 prefixlen 64 scopeid 0x20<link > ether 36:15:67:ac:e7:a6 txqueuelen 0 (以太网) RX packets 27 bytes 1774 (1.7 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 84 bytes 7704 (7.7 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 vethf73e2dc: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet6 fe80::243b:61ff:fea8:8b5b prefixlen 64 scopeid 0x20<link > ether 26:3b:61:a8:8b:5b txqueuelen 0 (以太网) RX packets 13 bytes 1098 (1.0 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 27 bytes 3260 (3.2 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 vethfdaf20c: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet6 fe80::acb4:8fff:fe32:f35a prefixlen 64 scopeid 0x20<link > ether ae:b4:8f:32:f3:5a txqueuelen 0 (以太网) RX packets 13 bytes 1098 (1.0 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 27 bytes 3260 (3.2 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 virbr0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 192.168.122.1 netmask 255.255.255.0 broadcast 192.168.122.255 ether 52:54:00:90:4b:76 txqueuelen 1000 (以太网) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 jcrj@SQA-JCRJ-01:~$
查看本地网卡设备名
可以看到本地网卡设备信息为logical name: eno1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 jcrj@SQA-JCRJ-01:~$ sudo lshw -c network [sudo ] jcrj 的密码: *-network DISABLED description: Ethernet interface product: Ethernet Connection (17) I219-V vendor: Intel Corporation physical id : 1f.6 bus info: pci@0000:00:1f.6 logical name: eno1 version: 11 serial: ec:d6:8a:be:bd:27 capacity: 1Gbit/s width: 32 bits clock: 33MHz capabilities: pm msi bus_master cap_list ethernet physical tp 10bt 10bt-fd 100bt 100bt-fd 1000bt-fd autonegotiation configuration: autonegotiation=on broadcast=yes driver=e1000e driverversion=6.5.0-14-generic firmware=2.3-4 latency=0 link =no multicast=yes port=twisted pair resources: irq:125 memory:80a00000-80a1ffff jcrj@SQA-JCRJ-01:~$
重启网络服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 jcrj@SQA-JCRJ-01:~$ sudo service NetworkManager stop jcrj@SQA-JCRJ-01:~$ sudo rm /etc/NetworkManager/NetworkManager.state rm : 无法删除 '/etc/NetworkManager/NetworkManager.state' : 没有那个文件或目录jcrj@SQA-JCRJ-01:~$ sudo vim /etc/NetworkManager/NetworkManager.conf jcrj@SQA-JCRJ-01:~$ jcrj@SQA-JCRJ-01:~$ cat /etc/NetworkManager/NetworkManager.conf [main] plugins=ifupdown,keyfile [ifupdown] managed=true [device] wifi.scan-rand-mac-address=no jcrj@SQA-JCRJ-01:~$ jcrj@SQA-JCRJ-01:~$ sudo service NetworkManager start jcrj@SQA-JCRJ-01:~$
Tftp使用
基本信息
设备名称
IP
属性
备注
SQA-JCRJ-01
172.16.16.10
server
tap0: flags=4419<UP,BROADCAST,RUNNING,PROMISC,MULTICAST> mtu 1500 inet 172.16.16.10 netmask 255.255.0.0 broadcast 172.16.255.255 inet6 fe80::ec13:32ff:fe7e:70ba prefixlen 64 scopeid 0x20<link> ether ee:13:32:7e:70:ba txqueuelen 1000 (以太网) RX packets 51 bytes 3314 (3.3 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 110 bytes 9805 (9.8 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
vexpress-a9
172.16.16.20
client
eth0 Link encap:Ethernet HWaddr 00:16:3E:00:00:01 inet addr:172.16.16.20 Bcast:172.16.255.255 Mask:255.255.0.0 UP BROADCAST RUNNING PROMISC MULTICAST MTU:1500 Metric:1 RX packets:76 errors:0 dropped:17 overruns:0 frame:0 TX packets:51 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:5668 (5.5 KiB) TX bytes:3314 (3.2 KiB) Interrupt:26
Server -> Client
Server
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 jcrj@SQA-JCRJ-01:/sync/tftp$ cat server-client.txt server to client tftp> ? tftp-hpa 5.2 Commands may be abbreviated. Commands are: connect connect to remote tftp mode set file transfer mode put send file get receive file quit exit tftp verbose toggle verbose mode trace toggle packet tracing literal toggle literal mode, ignore ':' in file name status show current status binary set mode to octet ascii set mode to netascii rexmt set per-packet transmission timeout timeout set total retransmission timeout ? print help information help print help informationtftp> q
Client
tftp -g -r 远程目标文件 远程地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 [root@vexpress-a9:/tmp]#tftp BusyBox v1.36.1 (2024-01-19 17:01:13 CST) multi-call binary. Usage: tftp [OPTIONS] HOST [PORT] Transfer a file from/to tftp server -l FILE Local FILE -r FILE Remote FILE -g Get file -p Put file -b SIZE Transfer blocks in bytes [root@vexpress-a9:/tmp]# [root@vexpress-a9:/tmp]#ls a.txt v.txt [root@vexpress-a9:/tmp]#tftp -g -r server-client.txt 172.16.16.10 server-client.txt 100% |********************************| 17 0:00:00 ETA [root@vexpress-a9:/tmp]#ls a.txt server-client.txt v.txt [root@vexpress-a9:/tmp]#cat server-client.txt server to client [root@vexpress-a9:/tmp]#
Client -> Server
Client
1 2 3 4 5 6 7 8 9 10 [root@vexpress-a9:/tmp]#vim clent-server.txt [root@vexpress-a9:/tmp]#ls a.txt clent-server.txt server-client.txt v.txt [root@vexpress-a9:/tmp]#cat clent-server.txt client server [root@vexpress-a9:/tmp]#tftp -p -r client_server.txt -l client-server.txt 172.16 .16.10 client_server.txt 100% |********************************| 14 0:00:00 ETA [root@vexpress-a9:/tmp]#
Server
1 2 3 4 5 jcrj@SQA-JCRJ-01:/sync/tftp$ ls a.txt client_server.txt server-client.txt uImage vexpress-v2p-ca9.dtb v.txt jcrj@SQA-JCRJ-01:/sync/tftp$ cat client_server.txt client server jcrj@SQA-JCRJ-01:/sync/tftp$
离线安装软件包
官方网址
https://ubuntu.pkgs.org/
GCC
MAKE
SSH