[关闭]
@cyysu 2021-12-03T05:43:52.000000Z 字数 10835 阅读 1213

Qemu调试Linux教程

  • 时间:2018年9月14日12:58:09
  • 作者:Kali
  • 邮箱:cyysu.github.io@gmail.com
  • 版本:6.0
  • 描述:qemu模拟A9开发板,并定制自己的根文件系统以及内核等有关教程。

QEMU模拟器系列教程


0.交叉工具准备

  1. sudo apt-get install gcc-arm-linux-gnueabi
  2. 安装好之后和我文件的前缀是不一样的,为arm-linux-gnueabi-

1.下载qemu,源码编译安装

点我直接下载

  1. # 1. 安装依赖
  2. sudo apt install zlib1g-dev
  3. sudo apt install libglib2.0-0 libglib2.0-dev
  4. sudo apt install libsdl1.2-dev
  5. sudo apt install libpixman-1-dev libfdt-dev
  6. # 2. 下载源码
  7. http://ow0q6dddn.bkt.clouddn.com/qemu-2.8.0.tar.xz
  8. # 3. 编译与安装(这里采用默认配置,编译会比较长)
  9. ./configure
  10. make -j8 && sudo make install
  11. 如果嫌以上太长,可以使用如下配置
  12. ./configure --target-list=arm-softmmu --audio-drv-list=

2.下载Linux内核-4.10.2

点我直接下载

  1. # 1. 修改Makefile
  2. ARCH ?= arm
  3. CROSS_COMPILE ?= arm-none-linux-gnueabi-
  4. # 2. 生成.config
  5. mj@DZ:~/linux-4.10.2$ make vexpress_defconfig
  6. # 3. 编译内核
  7. mj@DZ:~/linux-4.10.2$ make -j8 zImage
  8. # 4. 编译内核模块
  9. mj@DZ:~/linux-4.10.2$ make modules -j8
  10. # 5. 编译设备树文件
  11. mj@DZ:~/linux-4.10.2$ make dtbs

3. 试启动Linux内核

  1. mj@DZ:~$ cat start.sh
  2. sudo qemu-system-arm \
  3. -M vexpress-a9 \
  4. -m 512M \
  5. -kernel /home/mj/linux-4.10.2/arch/arm/boot/zImage \
  6. -dtb /home/mj/linux-4.10.2/arch/arm/boot/dts/vexpress-v2p-ca9.dtb \
  7. -nographic \
  8. -append "console=ttyAMA0" \

最后的启动形式如下:(这个时候就需要我们制作自己的根文件系统了)

4. 使用busybox制作根文件系统 - busybox-1.24.2

点我直接进行下载
使用文件打包下载

  1. # 1. 修改Makefile
  2. ARCH ?= arm
  3. CROSS_COMPILE ?= arm-none-linux-gnueabi-
  4. # 2. 预编译
  5. mj@DZ:~/busybox-1.24.2$ make defconfig
  6. # 3. 配置menuconfig
  7. 注意配置成静态库
  8. Busybox Settings --->
  9. Build Options --->
  10. [*] Build BusyBox as a static binary (no shared libs)
  11. # 4. 开始编译
  12. mj@DZ:~/busybox-1.24.2$ make -j8
  13. # 5. 安装
  14. mj@DZ:~/busybox-1.24.2$ make install
  15. # 6. 开始制作
  16. 使用下面的脚本进行一键制作或者下载如下文件
  17. # 7. 继续启动我们的Linux内核
  18. mj@DZ:~$ cat start.sh
  19. sudo qemu-system-arm \
  20. -M vexpress-a9 \
  21. -m 512M \
  22. -kernel /home/mj/linux-4.10.2/arch/arm/boot/zImage \
  23. -dtb /home/mj/linux-4.10.2/arch/arm/boot/dts/vexpress-v2p-ca9.dtb \
  24. -nographic \
  25. -append "root=/dev/mmcblk0 rw console=ttyAMA0" \
  26. -sd /home/mj/rootfs/rootfs.ext3
  27. # 8. 定制一下我们自己的欢迎界面-编辑文件系统中的/etc/init.d/rcS
  28. #!/bin/sh
  29. echo "########################################"
  30. echo "## welcome to MJ Qemu A9 board! ##"
  31. echo "########################################"
  32. # 9. 问题解决
  33. sync.c:(.text.sync_main+0x78): undefined reference to `syncfs'
  34. collect2: ld returned 1 exit status
  35. 去掉menuconfig中如下这个命令中[*]的*
  36. Coreutils --->
  37. [ ] sync
  1. #!/bin/bash
  2. DATE=`date +"%Y-%m-%d"`
  3. echo -e "\033[44;37;5m #=======================================================\033[0m"
  4. echo -e "\033[44;37;5m # Author : MJ_DZ chenyuan \033[0m"
  5. echo -e "\033[44;37;5m # \033[0m"
  6. echo -e "\033[44;37;5m # Email : cyysu.github.io@gmail.com \033[0m"
  7. echo -e "\033[44;37;5m # \033[0m"
  8. echo -e "\033[44;37;5m # Last modified : $DATE \033[0m"
  9. echo -e "\033[44;37;5m # \033[0m"
  10. echo -e "\033[44;37;5m # Filename : mk-sd.sh \033[0m"
  11. echo -e "\033[44;37;5m # \033[0m"
  12. echo -e "\033[44;37;5m # Description : Root file system script \033[0m"
  13. echo -e "\033[44;37;5m #=======================================================\033[0m"
  14. echo -e "\033[32m[info] Begin to delete last files on the disk!\033[0m"
  15. sudo rm -rf rootfs* 2&> /dev/null
  16. echo -e "\033[32m[info] Begin to create directory rootfs rootfs/lib!\033[0m"
  17. sudo mkdir rootfs
  18. sudo mkdir rootfs/lib
  19. echo -e "\033[32m[info] Begin to copy file from busybox to rootfs!\033[0m"
  20. sudo cp ../busybox-1.24.2/_install/* rootfs/ -raf
  21. echo -e "\033[32m[info] Begin to copy file from cross tools to rootfs!\033[0m"
  22. sudo cp -p /opt/arm-2011.03/arm-none-linux-gnueabi/libc/lib/* rootfs/lib
  23. echo -e "\033[32m[info] Begin to create char device !\033[0m"
  24. sudo mkdir -p rootfs/dev/
  25. sudo mknod rootfs/dev/tty1 c 4 1
  26. sudo mknod rootfs/dev/tty2 c 4 2
  27. sudo mknod rootfs/dev/tty3 c 4 3
  28. sudo mknod rootfs/dev/tty4 c 4 4
  29. sudo mknod rootfs/dev/console c 5 1
  30. sudo mknod rootfs/dev/null c 1 3
  31. echo -e "\033[32m[info] Begin to create others directory!\033[0m"
  32. sudo mkdir -p rootfs/proc/
  33. sudo mkdir -p rootfs/sys/
  34. sudo mkdir -p rootfs/tmp/
  35. sudo mkdir -p rootfs/root/
  36. sudo mkdir -p rootfs/var/
  37. sudo mkdir -p rootfs/mnt/
  38. sudo cp -arf etc/ rootfs/
  39. echo -e "\033[32m[info] Begin to make SD image!\033[0m"
  40. sudo dd if=/dev/zero of=rootfs.ext3 bs=1M count=32
  41. sudo mkfs.ext3 rootfs.ext3
  42. echo -e "\033[32m[info] Begin to mount image and copy rootfs to it!\033[0m"
  43. sudo mount -t ext3 rootfs.ext3 /mnt/ -o loop
  44. sudo cp -raf rootfs/* /mnt
  45. sudo umount /mnt/
  46. echo -e "\033[44;37;5m[info] Congratulations on your successful installation!\033[0m"

执行效果如下,蓝色区域是带闪动的效果,使用xshell即可看出
xshell下载链接

动态效果如下

这个时候启动的Linux的效果如下

Ctrl + A,然后 按下 X,就可以退出这个模拟系统
Ctrl + A,然后 按下 X,就可以退出这个模拟系统
Ctrl + A,然后 按下 X,就可以退出这个模拟系统

如果你感觉这个不炫丽,那么装13的配置来了

  1. mj@DZ:~$ cat start-graphic.sh
  2. sudo qemu-system-arm \
  3. -M vexpress-a9 \
  4. -m 512M \
  5. -kernel /home/mj/linux-4.10.2/arch/arm/boot/zImage \
  6. -dtb /home/mj/linux-4.10.2/arch/arm/boot/dts/vexpress-v2p-ca9.dtb \
  7. -append "root=/dev/mmcblk0 rw console=tty0" \
  8. -sd /home/mj/rootfs/rootfs.ext3

装13要完美,如果连关闭这个界面都不会还装sha!!

ctrl + alt 1和ctrl + alt 2进行界面切换,同时也可以将这个界面关闭
ctrl + alt 1和ctrl + alt 2进行界面切换,同时也可以将这个界面关闭
ctrl + alt 1和ctrl + alt 2进行界面切换,同时也可以将这个界面关闭

5. 使用u-boot引导Linux-uboot-2017.05

uboot-2017.05下载

  1. #1. 修改Makefile
  2. CROSS_COMPILE ?= arm-none-linux-gnueabi-
  3. #2. 修改config.mk
  4. ARCH ?= arm
  5. #3. 配置环境变量
  6. mj@DZ:~$ vim ~/.bashrc
  7. export ARCH=arm
  8. export CROSS_COMPILE=arm-none-linux-gnueabi-
  9. mj@DZ:~$ source ~/.bashrc
  10. #4. 编译
  11. make vexpress_ca9x4_defconfig
  12. make -j8
  13. #5. 引导
  14. mj@DZ:~/u-boot-2017.05$ qemu-system-arm -M vexpress-a9 -m 512M -nographic -kernel u-boot
  15. #6. 如果出现以下问题,解决方案看如下
  16. lib/asm-offsets.c:1:0: error: bad value (armv5) for -march= switch
  17. /*
  18. ^
  19. Kbuild:43: recipe for target 'lib/asm-offsets.s' failed
  20. make[1]: *** [lib/asm-offsets.s] Error 1
  21. make[1]: *** 正在等待未完成的任务....
  22. arch/arm/lib/asm-offsets.c:1:0: error: bad value (armv5) for -march= switch

解决方案

  1. 配置一个环境变量
  2. vim ~/.bashrc
  3. # 加入如下这两行代码
  4. export ARCH=arm
  5. export CROSS_COMPILE=arm-none-linux-gnueabi-
  6. # 执行
  7. source ~/.bashrc

启动效果

6. 配置QEMU网络功能

  1. 采用桥接(bridge)的网络连接与Host通信
  2. 需要主机内核tun/tap模块支持
  1. #1. 安装依赖包
  2. sudo apt install uml-utilities bridge-utils
  3. #2. 查看设备
  4. mj@DZ:~/u-boot-2017.05$ ll /dev/net/tun
  5. crw-rw-rw- 1 root root 10, 200 9 14 12:33 /dev/net/tun
  6. #3. 设置网卡配置文件
  7. mj@DZ:~$ cat /etc/network/interfaces
  8. # interfaces(5) file used by ifup(8) and ifdown(8)
  9. auto lo
  10. iface lo inet loopback
  11. auto eth0
  12. auto br0
  13. iface br0 inet dhcp
  14. bridge_ports ens33
  15. #4. 这些文件默认在安装完qemu就有,不需要修改
  16. mj@DZ:~$ cat /etc/qemu-if
  17. qemu-ifdown qemu-ifup
  18. #5. 重新编译内核,使用uboot引导
  19. mj@DZ:~/linux-4.10.2$ make LOADADDR=0x60003000 uImage -j8
  20. CHK include/config/kernel.release
  21. CHK include/generated/uapi/linux/version.h
  22. CHK include/generated/utsrelease.h
  23. CHK include/generated/timeconst.h
  24. CHK include/generated/bounds.h
  25. CHK include/generated/asm-offsets.h
  26. CALL scripts/checksyscalls.sh
  27. CHK include/generated/compile.h
  28. CHK kernel/config_data.h
  29. Kernel: arch/arm/boot/Image is ready
  30. Kernel: arch/arm/boot/zImage is ready
  31. UIMAGE arch/arm/boot/uImage
  32. Image Name: Linux-4.10.2
  33. Created: Fri Sep 14 16:34:52 2018
  34. Image Type: ARM Linux Kernel Image (uncompressed)
  35. Data Size: 3945760 Bytes = 3853.28 kB = 3.76 MB
  36. Load Address: 60003000
  37. Entry Point: 60003000
  38. Kernel: arch/arm/boot/uImage is ready
  39. #6. 主机配置tftp服务器
  40. mj@DZ:~/linux-4.10.2$ sudo apt-get install tftp-hpa tftpd-hpa xinetd
  41. # 配置文件
  42. mj@DZ:~/linux-4.10.2$ cat /etc/default/tftpd-hpa
  43. # /etc/default/tftpd-hpa
  44. TFTP_USERNAME="tftp"
  45. TFTP_DIRECTORY="/var/lib/tftpboot"
  46. TFTP_ADDRESS="0.0.0.0:69"
  47. TFTP_OPTIONS="-l -c -s"
  48. # 增加权限
  49. mj@DZ:~/linux-4.10.2$ sudo chmod 777 /var/lib/tftpboot/
  50. # 重启
  51. mj@DZ:~/linux-4.10.2$ /etc/init.d/tftpd-hpa restart
  52. #7. 修改u-boot引导内核镜像地址 - 188行,添加如下内容
  53. mj@DZ:~/u-boot-2017.05$ vim include/configs/vexpress_common.h +188
  54. #define CONFIG_BOOTCOMMAND \
  55. "tftp 0x60003000 uImage;tftp 0x60500000 vexpress-v2p-ca9.dtb; \
  56. setenv bootargs 'root=/dev/mmcblk0 console=ttyAMA0';\
  57. bootm 0x60003000 - 0x60500000; "
  58. /*定义板卡IP地址*/
  59. #define CONFIG_IPADDR 10.168.6.100
  60. #define CONFIG_NETMASK 255.255.255.0
  61. /*tftp服务器地址*/
  62. #define CONFIG_SERVERIP 10.168.6.21
  63. #8. 修改我们的启动脚本文件-无界面
  64. #!/bin/bash
  65. DATE=`date +"%Y-%m-%d"`
  66. echo -e "\033[44;37;5m #=======================================================\033[0m"
  67. echo -e "\033[44;37;5m # Author : MJ_DZ chenyuan \033[0m"
  68. echo -e "\033[44;37;5m # \033[0m"
  69. echo -e "\033[44;37;5m # Email : cyysu.github.io@gmail.com \033[0m"
  70. echo -e "\033[44;37;5m # \033[0m"
  71. echo -e "\033[44;37;5m # Last modified : $DATE \033[0m"
  72. echo -e "\033[44;37;5m # \033[0m"
  73. echo -e "\033[44;37;5m # Filename : start-nographic.sh \033[0m"
  74. echo -e "\033[44;37;5m # \033[0m"
  75. echo -e "\033[44;37;5m # Description : Boot system script \033[0m"
  76. echo -e "\033[44;37;5m #=======================================================\033[0m"
  77. echo -e "\033[32m[info] Begin to copy dtb files to tftp home directory!\033[0m"
  78. sudo cp /home/mj/linux-4.10.2/arch/arm/boot/dts/vexpress-v2p-ca9.dtb /var/lib/tftpboot
  79. echo -e "\033[32m[info] Begin to copy linux kernel to tftp home directory!\033[0m"
  80. sudo cp /home/mj/linux-4.10.2/arch/arm/boot/uImage /var/lib/tftpboot
  81. echo -e "\033[32m[info] Begin to run qemu vexpress-a9 board!\033[0m"
  82. sudo qemu-system-arm \
  83. -M vexpress-a9 \
  84. -m 512M \
  85. -kernel /home/mj/u-boot-2017.05/u-boot \
  86. -nographic \
  87. -sd /home/mj/rootfs/rootfs.ext3 \
  88. -net nic,vlan=0 \
  89. -net tap,vlan=0,ifname=tap0
  90. #-dtb /home/mj/linux-4.10.2/arch/arm/boot/dts/vexpress-v2p-ca9.dtb \
  91. #-append "root=/dev/mmcblk0 rw console=ttyAMA0" \
  92. #-kernel /home/mj/linux-4.10.2/arch/arm/boot/zImage \
  93. #9. 如果你想启动有界面的程序,需要你如下做
  94. #define CONFIG_BOOTCOMMAND \
  95. "tftp 0x60003000 uImage;tftp 0x60500000 vexpress-v2p-ca9.dtb; \
  96. setenv bootargs 'root=/dev/mmcblk0 console=ttyAMA0 console=tty0';\
  97. bootm 0x60003000 - 0x60500000; "
  98. 脚本内容如下:
  99. #!/bin/bash
  100. DATE=`date +"%Y-%m-%d"`
  101. echo -e "\033[44;37;5m #=======================================================\033[0m"
  102. echo -e "\033[44;37;5m # Author : MJ_DZ chenyuan \033[0m"
  103. echo -e "\033[44;37;5m # \033[0m"
  104. echo -e "\033[44;37;5m # Email : cyysu.github.io@gmail.com \033[0m"
  105. echo -e "\033[44;37;5m # \033[0m"
  106. echo -e "\033[44;37;5m # Last modified : $DATE \033[0m"
  107. echo -e "\033[44;37;5m # \033[0m"
  108. echo -e "\033[44;37;5m # Filename : start-nographic.sh \033[0m"
  109. echo -e "\033[44;37;5m # \033[0m"
  110. echo -e "\033[44;37;5m # Description : Boot system script \033[0m"
  111. echo -e "\033[44;37;5m #=======================================================\033[0m"
  112. echo -e "\033[32m[info] Begin to copy dtb files to tftp home directory!\033[0m"
  113. sudo cp /home/mj/linux-4.10.2/arch/arm/boot/dts/vexpress-v2p-ca9.dtb /var/lib/tftpboot
  114. echo -e "\033[32m[info] Begin to copy linux kernel to tftp home directory!\033[0m"
  115. sudo cp /home/mj/linux-4.10.2/arch/arm/boot/uImage /var/lib/tftpboot
  116. echo -e "\033[32m[info] Begin to run qemu vexpress-a9 board!\033[0m"
  117. sudo qemu-system-arm \
  118. -M vexpress-a9 \
  119. -m 512M \
  120. -kernel /home/mj/u-boot-2017.05/u-boot \
  121. -sd /home/mj/rootfs/rootfs.ext3 \
  122. -net nic,vlan=0 \
  123. -net tap,vlan=0,ifname=tap0

以上两个文件的默认配置

  1. mj@DZ:~$ cat /etc/qemu-ifup
  2. #! /bin/sh
  3. # Script to bring a network (tap) device for qemu up.
  4. # The idea is to add the tap device to the same bridge
  5. # as we have default routing to.
  6. # in order to be able to find brctl
  7. PATH=$PATH:/sbin:/usr/sbin
  8. ip=$(which ip)
  9. if [ -n "$ip" ]; then
  10. ip link set "$1" up
  11. else
  12. brctl=$(which brctl)
  13. if [ ! "$ip" -o ! "$brctl" ]; then
  14. echo "W: $0: not doing any bridge processing: neither ip nor brctl utility not found" >&2
  15. exit 0
  16. fi
  17. ifconfig "$1" 0.0.0.0 up
  18. fi
  19. switch=$(ip route ls | \
  20. awk '/^default / {
  21. for(i=0;i<NF;i++) { if ($i == "dev") { print $(i+1); next; } }
  22. }'
  23. )
  24. # only add the interface to default-route bridge if we
  25. # have such interface (with default route) and if that
  26. # interface is actually a bridge.
  27. # It is possible to have several default routes too
  28. for br in $switch; do
  29. if [ -d /sys/class/net/$br/bridge/. ]; then
  30. if [ -n "$ip" ]; then
  31. ip link set "$1" master "$br"
  32. else
  33. brctl addif $br "$1"
  34. fi
  35. exit # exit with status of the previous command
  36. fi
  37. done
  38. echo "W: $0: no bridge for guest interface found" >&2
  1. mj@DZ:~$ cat /etc/qemu-ifdown
  2. #! /bin/sh
  3. # Script to shut down a network (tap) device for qemu.
  4. # Initially this script is empty, but you can configure,
  5. # for example, accounting info here.
  6. :

7. 设置网络根文件系统步骤

一个完整的启动过程动画演示

此系统还不够完善,后面后出一个详细的定制根文件系统。未完待续。。。

结束语

以上内容有笔者自己编写,也有摘自互联网。摘自互联网部分笔者都会仔细阅读,确保符合笔者当时测试情况进行编写,当然在学习的过程中不可避免的有理解不到位的地方,还请读友批评指正。

打赏

                    支付宝                                                         微信

微信与支付宝支付

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注