首页 热点资讯 义务教育 高等教育 出国留学 考研考公
您的当前位置:首页正文

Ubuntu使用QEMU模拟ARM环境

2024-12-17 来源:花图问答

注:实验环境是 Ubuntu 16.04.1 gnome

  1. 安装交叉编译工具、GDB 和 QEMU
~/work $ sudo apt-get install gcc-arm-linux-gnueabi
~/work $ sudo apt-get install gdb-multiarch
~/work $ sudo apt-get install qemu-system-arm
  1. 配置编译内核
~/work/linux-3.10.61 $ make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm vexpress_defconfig
~/work/linux-3.10.61 $ make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm
  1. 创建目录 arm-image 目录,将 zImage 和 dtb(device tree binary)文件复制到此目录
~/work $ mkdir arm-image
~/work $ cp ./linux-3.10.61/arch/arm/boot/zImage ./arm-image
~/work $ cp ./linux-3.10.61/arch/arm/boot/dts/*.dtb ./arm-image
  1. 复制编译器提供的 C 库和 ld 库
~/work $ mkdir -p ./arm-linux/lib
~/work $ cp -a /usr/arm-linux-gnueabi/lib/* ./arm-linux/lib

  1. (1) 将下载好的 BusyBox 解压在 /home/user/work/busybox-1.25.1 中,进行配置
~/work/busybox-1.25.1 $ make ARCH=arm defconfig
~/work/busybox-1.25.1 $ sudo apt-get install libncurses5-dev
~/work/busybox-1.25.1 $ make menuconfig

(2) 然后 :

Busybox Settings -> Build Options -> [*] Build BusyBox as a static Binary (no shared libs)

保存退出
(3) 编译和安装:

~/work/busybox-1.25.1 $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
~/work/busybox-1.25.1 $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- install

(4) 复制 _install 目录下的内容

~/work/busybox-1.25.1 $ ./_install/* ../arm-linux/
  1. 新建系统启动脚本
~/work/arm-linux $ mkdir -p proc sys dev etc/init.d
~/work/arm-linux $ vim etc/init.d/rcS

rcS 的内容:

#! /bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
mount -t devtmpfs devtmpfs /dev
/sbin/mdev -s

分配运行权限:

~/work/arm-linux $ chmod +x  ./etc/init.d/rcS
  1. 根文件系统通过 nfs 的方式提供给 ARM Linux 使用
~/work $ sudo apt-get install nfs-kernel-server
~/work $ sudo vim /etc/exports

加入一行规则,nfs 将合适的路径提供给 ARM Linux 使用。示例:

/home/user/work/arm-linux *(rw,sync,no_subtree_check,no_root_squash,insecure)

重新启动 nfs 服务:

~/work $ sudo service nfs-kernel-server restart
  1. 用 qemu-system-arm 启动 ARM linux 系统
~/work $ vim ./start.sh

start.sh (注意修改对应的 IP 地址和 nfsroot 的位置):

qemu-system-arm \
        -M vexpress-a9 -m 1024M \
        -kernel ./arm-image/zImage \
        -dtb arm-image/vexpress-v2p-ca9.dtb \
        -serial stdio \
        -append "console=ttyAMA0 nfsroot=192.168.118.133:/home/user/work/arm-linux
rw ip=dhcp"
  1. 使用 GDB 调试内核
~/work $ vim ./debug.sh

debug.sh:

#! /bin/sh
gnome-terminal -x gdb-multiarch; \
qemu-system-arm \
        -S -s \
        -M vexpress-a9 -m 1024M \
        -kernel ./arm-image/zImage \
        -dtb arm-image/vexpress-v2p-ca9.dtb \
        -serial stdio \
        -append "console=ttyAMA0 nfsroot=192.168.118.133:/home/user/work/arm-linux
rw ip=dhcp"

使用 .gdbinit
(1)

~ $ vim .gdbinit

.gdbinit 的内容:

add-auto-load-safe-path /home/user/work/.gdbinit

(2)

~/work $ vim .gdbinit

.gdbinit 的内容:

set architecture arm
target remote localhost:1234

(3) 不同阶段调试内核 gdb 需要输入的命令

  • zImage 重定位之前:
~/work $ ./debug.sh
(gdb) set disassemble-next on
(gdb) add-symbol-file ./linux-3.10.61/arch/arm/boot/compressed/vmlinux 0x60010000
(gdb) b * 0x60010000
(gdb) c
(gdb) si
  • zImage 重定位之后:
~/work $ ./debug.sh
(gdb) set disassemble-next on
(gdb) add-symbol-file ./linux-3.10.61/arch/arm/boot/compressed/vmlinux 0x604E4160
(gdb) b * 0x604E4210
(gdb) c
  • 内核解压后:
~/work $ ./debug.sh
(gdb) set disassemble-next on
(gdb) add-symbol-file ./linux-3.10.61/vmlinux 0x60008240 -s .head.text 0x60008000 -s .rodata 0x60479000
(gdb) b stext
(gdb) c
  • start_kernel 及之后:
~/work $ ./debug.sh
(gdb) file ./linux-3.10.61/vmlinux
(gdb) b start_kernel
(gdb) c
  1. 文件结构概览

/home/user

.gdbinit
./work

./linux-3.10.61
./busybox-1.25.1
./arm-image
./arm-linux
.gdbinit
start.sh
debug.sh


注: 使用 ctags 和 cscope

~/work/linux-3.10.61 $ make tags ARCH=arm
~/work/linux-3.10.61 $ make cscope ARCH=arm

全文完


Reference:

显示全文