利用qemu写mips汇编程序控制malta显示器
来源:互联网 发布:淘宝客服投诉电话400 编辑:程序博客网 时间:2024/06/09 02:56
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
test.ld
Makefile:
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,现在很便宜了,进出都是按秒算的。。。
参考之前的文章,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
.global __start.text__start:add $t0,$0, 0xbf000408 #LED addressadd $t3,$0, 0xbf000418 #display char addressadd $s2, $s2, 0x3ffffff #delay timeadd $s0, $0,0x55 #LED: "# # # # " update:sw $s0,0($t0) #send to LEDsw $s0,0($t3) #send to displaysw $s0,8($t3) #send to displaysw $s0,16($t3) #send to displaysw $s0,24($t3) #send to displaysw $s0,32($t3) #send to displaysw $s0,40($t3) #send to displaysw $s0,48($t3) #send to displaysw $s0,56($t3) #send to displayadd $t1, $0, 0delay:add $t1, $t1, 1bne $t1, $s2, delayadd $s0, $s0, 1b update
test.ld
引用
ENTRY(__start)
SECTIONS
{
. = 0x80100000;
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss) }
. = . + 0x1000; /* 4kB of stack memory */
stack_top = .;
}
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
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,现在很便宜了,进出都是按秒算的。。。
- 利用qemu写mips汇编程序控制malta显示器
- mips qemu
- QEMU 模拟 MIPS
- Coursera - 计算机组成 - W3 - MIPS汇编程序设计
- MIPS汇编程序设计——冒泡排序
- 第一次互评作业:MIPS汇编程序设计
- mips汇编程序中的.set指令使用
- 自写的汇编程序
- qemu mips msub instruction emulation bug
- qemu模拟运行mips程序调试
- 自己写的51单片机控制无线模块RFM12B 发送数据的汇编程序,呵呵
- 控制显示器的类
- 显示器控制,待测试
- ARM汇编程序-逻辑控制
- 计算机组成第一次互评作业:MIPS汇编程序设计
- 用VC6.0写汇编程序
- 利用IDA Pro反汇编程序
- qemu利用uboot启动
- Android通过PHP连接MySQL(读取)
- 利用画线插件如何删除线
- 线程池
- sqlserver char nchar varchar nvarchar 的区别
- [QT]QDir和QFile的基本操作
- 利用qemu写mips汇编程序控制malta显示器
- 习题4.3a
- 软考(二)常见的软件开发模型
- 如何使用Python开发环境Wing IDE的Search in Files工具
- C++ 文件hash值 BT种子的hash值
- [QT]QFileDialog关于选择文件对话框中的几个信号的说明
- Opencv学习_3 (Opencv读取视频 &视频进度控制 &写视频)
- BaseAdapter分析
- 关于oracle dbresp.pl进行耗尽CPU的解决办法