最开始时采用Windows 开发环境
arm toolchains
windows版qemu
cygwin
我也有虚拟机,里面是debian,主要是虚拟机太占资源,可怜我的小黑只有1G内存呀,所以我是不到万不得已是不会开虚拟机的,呵呵。
先说一下qemu吧,
QEMU can load a Linux kernel using the -kernel and -initrd options; at a low level, these options have the effect of loading two binary files into the emulated memory: the kernel binary at address 0x10000 (64KiB) and the ramdisk binary at address 0x800000 (8MiB). Then QEMU prepares the kernel arguments and jumps at 0x10000 (64KiB) to execute Linux. The emulator starts the execution at address 0x00000000, where few instructions (already in place) are used to jump at the beginning of the kernel image.
The interrupt table of ARM cores, usually placed at address 0x00000000, is not present, and the peripheral interrupts are disabled at startup, as needed to boot a Linux kernel. Knowing this, to implement a working emulation I need to considerate a few things:
The software must be compiled and linked to be placed at 0x00010000
I need to create a binary image of our program
I can ignore interrupt handling for now
qemu可以通过-kernel和initrd选项,把两个2进制文件装到模拟的memory当中,内核被装载到地址0x10000,ramdisk镜像被装载到0x80000
首先编写test.S
.global _start
.text
_start:
mov r0, #0
mov r1, #1
mov r2, #2
loop:
b loop
编译生成带调试符号文件test.elf和去掉符号的test.bin
CC=arm-elf-gcc
LD=arm-elf-ld
OBJDUMP=arm-elf-objdump
OBJCOPY=arm-elf-objcopy
OBJ= test
OBJ : $(OBJ).S
$(CC) -g -c -o $(OBJ).o
$(OBJ).S
$(LD) -Ttext 0x10000 -g
$(OBJ).o -o $(OBJ).elf
$(OBJCOPY) -O binary
$(OBJ).elf $(OBJ).bin
$(OBJDUMP) -d $(OBJ).elf
> $(OBJ).dump
clean:
rm *.o *.elf *.bin
*.dump
接下来准备调试
qemu-system-arm -M versatilepb -m 18M -s -S -kernel test.bin
-S
freeze CPU at startup (use 'c' to start execution)
-s
wait gdb connection to port 1234
target remote localhost:1234
alt-f2
(qemu)gdbserver 1234
(gdb) info register
(gdb) ni/ns ;汇编下一步,stepin
(gdb) display /10i $pc-16
(gdb) x /16 0 这个是查看0x00000000开始的16个字(32 bits per word)的内存信息