Ссылки
- Gentoo Cross Development Guide
- Building a ARM powered Debian VM with QEMU on Ubuntu Lucid
- Compiling an ARM1176 kernel for QEMU
- ARM Emulation Using QEMU
- The Kernel Newbie Corner: Kernel and Module Debugging with gdb
ARM Versatile PB
Пути
Создаем каталог, в котором будет проходить вся работа.
# mkdir /some/dir # export VM=/some/dir
Виртуальная машина (Debian Squeeze)
Устанавливаем QEMU с включенной опцией arm в переменных QEMU_SOFTMMU_TARGETS и QEMU_USER_TARGETS.
Создаем диск.
# cd $VM # qemu-img create -f qcow2 vm.qcow2 20G
Скачиваем образ установщика.
# cd $VM # wget http://caesar.acc.umu.se/cdimage/archive/6.0.8/armel/iso-cd/debian-6.0.8-armel-netinst.iso
Скачиваем ядро и initrd установщика (QEMU не поддерживает загрузчик для ARM).
# cd $VM # wget ftp://ftp.us.debian.org/debian/dists/wheezy/main/installer-armel/20130613+deb7u1+b1/images/versatile/netboot/vmlinuz-3.2.0-4-versatile # wget ftp://ftp.us.debian.org/debian/dists/wheezy/main/installer-armel/20130613+deb7u1+b1/images/versatile/netboot/initrd.gz
Устанавливаем Debian.
# brctl show br0 bridge name bridge id STP enabled interfaces br0 8000.3085a997443e no eth0 # cat $VM/vm-ifup.sh #! /bin/bash set -x ifconfig $1 up && brctl addif br0 $1 # qemu-system-arm \ -m 2047 -M versatilepb -hda $VM/vm.qcow2 \ -net nic,vlan=1,macaddr=de:ad:be:af:11:22 \ -net tap,vlan=1,ifname=myvm,script=$VM/vm-ifup.sh \ -kernel $VM/vmlinuz-3.2.0-4-versatile \ -initrd $VM/initrd.gz \ -cdrom $VM/debian-6.0.8-armel-netinst.iso \ -boot d
Вытаскиваем initrd из установленного Debian.
# qemu-nbd --connect=/dev/nbd0 $VM/vm.qcow2 # mkdir $VM/vm-disk # fdisk -l /dev/nbd0 # mount /dev/nbd0p1 $VM/vm-disk # cp $VM/vm-disk/boot/initrd.img-2.6.32-5-versatile $VM/ # umount $VM/vm-disk # rmdir $VM/vm-disk # qemu-nbd --disconnect $VM/vm.qcow2
Загружаем дефолтный Debian.
# qemu-system-arm \ -m 2047 -M versatilepb -hda $VM/vm.qcow2 \ -net nic,vlan=1,macaddr=de:ad:be:af:11:22 \ -net tap,vlan=1,ifname=myvm,script=$VM/vm-ifup.sh \ -kernel $VM/vmlinuz-3.2.0-4-versatile \ -initrd $VM/initrd.img-2.6.32-5-versatile \ -append "root=/dev/sda1"
Тулчейн
Устанавливаем crossdev.
# emerge -av sys-devel/crossdev
Устанавливаем тулчейн.
# crossdev --binutils 2.20.1 --gcc 4.6.4 --kernel 3.1 --libc 2.11.3 --target arm-linux-gnueabi
Устанавливаем GDB (флаг expat нужен для парсинга XML, который раздает gdbserver QEMU).
# USE=expat emerge -av cross-arm-linux-gnueabi/gdb
Ядро
У меня работали ядра 2.6.x версий от 2.6.29 до 2.6.35.9.
Скачиваем и распаковываем ядро.
# cd $VM # wget ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.32.5.tar.bz2 # tar xvf linux-2.6.32.5.tar.bz2
Конфигурируем.
# cd $VM/linux-2.6.32.5 # make versatile_defconfig # make menuconfig
Нужно включить эти опции:
General Setup --->
[*] Kernel .config support
[*] Enable access to .config through /proc/config.gz
Kernel Features --->
[*] Use VM EABI to compile the kernel
[*] Allow old ABI binaries to run with this kernel
Bus Support --->
[*] PCI Support
Device Drivers --->
SCSI Device Support --->
[*] SCSI Device Support
[*] SCSI Disk Support
[*] SCSI CDROM support
[*] SCSI low-lever drivers --->
[*] SYM53C8XX Version 2 SCSI support
Generic Driver Options--->
[*] Maintain a devtmpfs filesystem to mount at /dev
[*] Automount devtmpfs at /dev, after the kernel mounted the root
Input device support--->
[*] Event interface
File systems --->
<*> Ext3 journalling file system support
<*> The Extended 4 (ext4) filesystem
Pseudo filesystems--->
[*] Virtual memory file system support (former shm fs)
Kernel hacking --->
[*] Compile the kernel with debug info
Собираем ядро и модули.
# mkdir -p $VM/arm-modules # cd $VM/linux-2.6.32.5 # make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- # make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- modules # make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- modules_install INSTALL_MOD_PATH=$VM/arm-modules
Копируем ядро.
# cp $VM/linux-2.6.32.5/arch/arm/boot/zImage $VM/debug-kernel
Initrd
Распаковываем оригинальный initrd.
# mkdir -p $VM/initrd # cd $VM/initrd # gunzip - < $VM/initrd.img-2.6.32-5-versatile | cpio -id
Заменяем модули на собранные нами.
# cd $VM/initrd/lib/modules # rm -rf * # cp -a $VM/arm-modules/lib/modules/* .
Запаковываем новый initrd.
# cd $VM/initrd/ # find . | cpio --create --format='newc' | gzip > $VM/debug-initrd
Запуск
Проверяем, что новое ядро успешно загружается.
# qemu-system-arm \ -m 2047 -M versatilepb -hda $VM/vm.qcow2 \ -net nic,vlan=1,macaddr=de:ad:be:af:11:22 \ -net tap,vlan=1,ifname=myvm,script=$VM/vm-ifup.sh \ -kernel $VM/debug-kernel \ -initrd $VM/debug-initrd \ -append "root=/dev/sda1"
Отладка ядра
Запускаем QEMU с gdbserver (опции -s и -S).
# qemu-system-arm -s -S \ -m 2047 -M versatilepb -hda $VM/vm.qcow2 \ -net nic,vlan=1,macaddr=de:ad:be:af:11:22 \ -net tap,vlan=1,ifname=myvm,script=$VM/vm-ifup.sh \ -kernel $VM/debug-kernel \ -initrd $VM/debug-initrd \ -append "root=/dev/sda1"
Запускаем отладчик.
# cd $VM/linux-2.6.32.5 # arm-none-linux-gnueabi-gdb (gdb) file vmlinux (gdb) target remote :1234 (gdb) continue ..... ^C (gdb) backtrace (gdb) list
Можно также поставить breakpoint на функцию icmp_reply() и попинговать виртуалку.
Отладка модуля
Пишем простой модуль.
# cat $VM/hello/Makefile
KERNEL := $VM/linux-2.6.32.5
ARCH := arm
CROSS := arm-linux-gnueabi-
CFLAGS_hello.o := -g
obj-m += hello.o
all:
make -C $(KERNEL) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS) modules
clean:
make -C $(KERNEL) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS) clean
# cat $VM/hello/hello.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
void goodbye(void); // без static!
void goodbye(void)
{
printk(KERN_INFO "goodbye!\n");
}
static int __init hello_init(void)
{
printk(KERN_INFO "hello_init\n");
return 0;
}
static void __exit hello_exit(void)
{
goodbye();
printk(KERN_INFO "hello_exit\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("hello module");
Собираем модуль.
# cd $VM/hello # make
Копируем hello.ko на виртуалку и загружаем.
# insmod hello.ko # cat /sys/module/hello/sections/.text 0x0000000000000001 # cat /sys/module/hello/sections/.data 0x0000000000000002 # cat /sys/module/hello/sections/.bss 0x0000000000000003
Загружаем символы модуля в GDB.
(gdb) add-symbol-file ../hello/hello.ko \
0x0000000000000001 -s .data 0x0000000000000002 -s .bss 0x0000000000000003
(gdb) b goodbye
(gdb) c
Выгружаем модуль, чтобы сработал breakpoint.
# rmmod hello
Отладка в Emacs
Советую настроить Emacs так:
(setq gdb-non-stop-setting nil) (setq gdb-many-windows t)
И запускать отладчик так:
M-x gdb arm-linux-gnueabi-gdb -i=mi
И затем в консоли GDB:
(gdb) file vmlinux (gdb) target remote :1234 .....
PowerPC
Для PowerPC последовательность действий та же, за исключением перечисленных ниже моментов.
QEMU
QEMU был собран с флагом ppc.
Debian
Использовался Debian Wheezy с ядром 3.x.
Т.к. QEMU под PowerPC поддерживает загрузчик, вручную передавать ядро и initrd из установщика не требуется (опции -kernel и -initrd).
Crossdev
Использовался тулчейн powerpc-unknown-linux-gnu и соответственно отладчик cross-powerpc-unknown-linux-gnu/gdb.
Ядро
Проверялись ядра 2.6.39 и 3.6.11 с флагами сборки:
ARCH="powerpc" CROSS="powerpc-unknown-linux-gnu-"
Вместо versatile_defconfig и включения перечисленных опций ядра был использован конфиг ядра из Debian Wheezy.
В QEMU опцией -kernel передавался файл $VM/linux-3.6.11/vmlinux.
Комментариев нет:
Отправить комментарий