`
steeven
  • 浏览: 307228 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

利用qemu写mips汇编程序控制malta显示器

 
阅读更多
hello world不会写,先玩玩malta虚拟器上的跑马灯,就是qemu起来后ctrl+atl+5切换出来那个,安装debian mips版本后会有个"LINUX ON MALTA"在那一直循环。

参考之前的文章,windows和linux下都有qemu,gnu的交叉编译工具也都有,所以两个平台应该都能跑。

本文参考了:
http://comments.gmane.org/gmane.comp.emulators.qemu/107966
http://comments.gmane.org/gmane.comp.emulators.qemu/11911
还有qemu对malta机器模拟的源码:
http://svn.peeklinux.com/trunk/qemu/hw/mips_malta.c 这个东西很重要,能看到很多内部实现。

注意:
1. qemu-system-mipsel的-bios参数没实现,指定什么参数启动的时候都不会加载。
2. qemu-system-mipsel的-kernel参数必须指定elf文件,经过objdump -O binary的文件时不会被加载的,看过那篇文章玩qemu-system-arm的人可能会想不通(http://balau82.wordpress.com/2010/02/14/simplest-bare-metal-program-for-arm/)。
3. qemu-system-mipsel的kernel加载位置就是ld时指定链接模板定义的,建议为0x80100000, 这是debian linux kernel文件抄来的,应该不会错多少。malta的bios会根据你的elf入口决定跳转位置,但是,你的elf在256M内存之外,它还是会老老实实跳过去。。。
4. 从malta源码看,这个灯的地址应该是0x1fxxxxxx的,但是用调试工具访问这个地址失败。在qemu的monitor console里面x,xp可以看出来,这个地址是物理地址。那么它的映射地址是多少呢?See MIPS RUN这书2.8图2-1有mips系统内存映射。原来是0xbfxxxxx。
5. 不要以为后面就好办了,gdb里面直接设置0xbf000418(显示字符串的起始位置)这个内存值,但是不会生效,在debian里面试过,不行。搜索"LINUX ON MALTA", 原来内核里面定时刷新的。
6. 好吧,qemu-system-mipsel -s -S -kernel xxxx, 然后用gdb target remote :1234进去,这个地址写进去值,没响应。读就不要想了,从源码看这个地址不支持读。这个不知道算不算qemu的bug, 写应该支持啊。
7. 好吧,写个汇编,让程序去说话,终于成功了~~

test.S
.global __start
.text
__start:
	add $t0,$0, 0xbf000408 #LED address
	add $t3,$0, 0xbf000418 #display char address
	add $s2, $s2, 0x3ffffff #delay time
	add $s0, $0,0x55 #LED: "# # # # " 
update:
	sw $s0,0($t0) #send to LED
	sw $s0,0($t3) #send to display
	sw $s0,8($t3) #send to display
	sw $s0,16($t3) #send to display
	sw $s0,24($t3) #send to display
	sw $s0,32($t3) #send to display
	sw $s0,40($t3) #send to display
	sw $s0,48($t3) #send to display
	sw $s0,56($t3) #send to display

	add $t1, $0, 0

delay:
	add $t1, $t1, 1
	bne $t1, $s2, delay

	add $s0, $s0, 1
	b update


test.ld
引用
ENTRY(__start)
SECTIONS
{
    . = 0x80100000;
    .text : { *(.text) }
    .data : { *(.data) }
    .bss : { *(.bss) }
    . = . + 0x1000; /* 4kB of stack memory */
    stack_top = .;
}


Makefile:
引用
all: test
test: testclean
mipsel-linux-gnu-gcc -mips32 -EL -c test.S -o test.o
mipsel-linux-gnu-ld -mips32 -EL -T test.ld test.o -o test
mipsel-linux-gnu-objcopy -O binary test test.bin
testclean:
rm -f test
rm -f test.bin
testrun:
        qemu-system-mipsel  -kernel test


qemu通过ctrl+alt+5切换到led界面,Malta LEDBAR:显示很多跳动的# ###, Malta ASCII跳动显示的是当前字符,实际上LED是字符的二进制格式。

单步汇编调试:
qemu-system-mipsel  -kernel test -s -S
mipsel-linux-gnu-gdb test
(gdb) target remote :1234
(gdb) load
(gdb) break __start ////$pc最开始bios,即0xbfc0.0000
(gdb) i reg
(gdb) c
(gdb) x/16i $pc
(gdb) si

刚学mips, 用C写一样的。玩虚拟机一定要用SSD,现在很便宜了,进出都是按秒算的。。。
0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics