Archives
1. u-boot and linux kernel can boot from mmc image
2. Because twl4030 emulation is not complete, mmc device can not be found in linux kernel.
Next step:
1. twl4030 emulation. Big effort is needed.
2. dss/dma emulation
3. usb
Qemu currently supports nand flash emulation in hw/nand.c. But it is for spi flash and it's not ready for big page nand flash, 2k page nand flash for example. I add the big page nand flash emulation to it, but it has some bugs. When I boots jffs2 rootfs from qemu-omap, some error messages appear.
<4>mtd->read(0x1f9f4 [...]
I meet a strange problem when doing MMC emulation. The x-loader code is downloaded from http://beagleboard.googlecode.com/files/x-load_beagle_revb.tar.gz.
In function mmc_send_cmd(cpu/omap3/mmc.c)
145 OMAP_HSMMC_BLK = BLEN_512BYTESLEN | NBLK_STPCNT;
146 OMAP_HSMMC_STAT = 0xFFFFFFFF;
147 OMAP_HSMMC_ARG = arg;
148 [...]
Hi everyone, a good news for you. Linux in running successfully on qemu-omap3. Following is the screenshot.
However, MMC/USB/audio/LCD display/keyboard emulation are not ok . I will work on it.
In the following I will give you some informations of how to run qemu-omap3.
1. checkout qemu-omap3 from svn. Tag v0.01 is working.
svn checkout http://qemu-omap3.googlecode.com/svn/tags/v0.01 qemu-omap3
Or you can [...]
Working on qmeu-omap3. A starange problem. If I use the kernel image downloaded from http://beagleboard.googlecode.com/files/uImage_OTG, some kernel boot informations can be displayed in uart3. But when I use the kernel source from linux omap git and build it by myself, there are NO linux kernel boot informations at all.
Linux kernel uses printk to output informations [...]
I use qemu-omap3 to boot linux kernel from nand. The linux image is downloaded from http://beagleboard.googlecode.com/files/uImage_OTG.
OMAP3 beagleboard.org #
OMAP3 beagleboard.org # nand read 0x80000000 0x280000 0x400000
NAND read: device 0 offset 0x280000, size 0x400000
4194304 bytes read: ERROR
OMAP3 beagleboard.org # bootm 0x80000000
## Booting kernel from Legacy Image at 80000000 ...
Image Name: Linux-2.6.22.18-omap3
[...]
Good news. LCD is working in qemu-omap3
Beagle board has an DVI transmitter TFP 410 and it outputs ditigal signal to LCD panel which has DVI connector. However, we do not care TFP 410 because it is just a pipe for LCD output data. What we care about is the LCD output data itself.
According to the [...]
在u-boot中,采用函数udelay来进行延时。这是一个单纯等待的算法。在beagle board的u-boot中,udelay会不断去读OMAP general purpose timer的count值,然后根据general purpose timer的输入时钟来得到已经经过的时间。
在u-boot中,gp timer2的输入时钟为系统时钟,beagle board中为13MHZ。并且时钟经过了256分频。因此,每一秒钟的时间,gp timer2的count的值会增加1*(13MHZ/256)。
对于qemu来说,必须要保证当u-boot去读gptimer寄存器值的时候,返回的count值是正确的。也就是说,必须是实际经过的时间*13MHZ/256。
在qemu中,ticks_per_sec的值为1000000000。函数qemu_get_clock可以得到当前时间的ticks。因此,当u-boot来读gptimer寄存器值的时候,返回的count值应该为:
(qemu_get_clock/ticks_per_sec)*(13MHZ/256)
也就是
(qemu_get_clock*13MHZ)/(ticks_per_sec*256)
见函数omap_gp_timer_read
distance = muldiv64(distance, timer->rate, timer->ticks_per_sec);
这里,timer->ticks_per_sec= ticks_per_sec*256。
可是问题的关键在于,函数muldiv64的原型为
/* compute with 96 bit intermediate result: (a*b)/c */
uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
也就是说,参数b和c都是32bit的。而timer->ticks_per_sec已经超过了32bit。导致distance的计算出错,后果是u-boot中的延时函数是不准的。
解决方法:
首先判断一下ticks_per_secis有没有超过32bit,然后根据情况分别计算。
/*if ticks_per_secis bigger than 32bit, we can not use muldiv64 anymore!*/
if (timer->ticks_per_sec>0xffffffff){
distance = distance/(ticks_per_sec/1000); /*distance ms*/
rate = timer->rate >> (timer->pre ? timer->ptv [...]
经过几天的debug,在很多地方加入 判断是否有SIG pending的语句,结果都是没有信号pending。那么唯一的可能就根本没有产生SIGALRM信号! 继续追踪。Qemu中提供了很多中定时器的实现方法,见数组alarm_timers。
1: static struct qemu_alarm_timer alarm_timers[] = {
2: #ifndef _WIN32
3: #ifdef __linux__
4: {"dynticks", ALARM_FLAG_DYNTICKS, dynticks_start_timer,
5: dynticks_stop_timer, dynticks_rearm_timer, NULL},
6: /* HPET - if available - is preferred */
7: {"hpet", 0, hpet_start_timer, hpet_stop_timer, NULL, NULL},
8: [...]
那在qemu中,有一个gui timer会定时刷新gui的信息。现在gui的tile没有变化,就说明这个gui timer 根本没有被触发。
而在qemu中的定时器是通过函数host_alarm_handler来触发运行的,函数host_alarm_handler又是通过信号来进行触发的。那么问题的根源就是信号没有被发送或者被block(还没有查出具体原因)。
我尝试在终端中向qemu发生SIGALRM信号,果然,qemu接收到SIGALRM信号后,执行host_alarm_handler然后会执行所有注册了的定时器的超时函数(包括display_state.gui_timer)。
kill-bill: # ps aux | grep qemu
root 2945 101 3.2 196468 8404 pts/1 R+ 09:36 0:14 ./qemu-system-arm -M beagle -mtdblock beagle-nand.bin
root 2947 0.0 0.2 2996 692 pts/0 R+ 09:36 0:00 grep qemu
kill-bill: # kill -s SIGALRM 2945
多次发送SIGALRM信号后,qemu可以正常接受终端的输入。下面是qemu运行u-boot的截图。
接下来就需要查找为什么qemu没有收到SIGALRM!
Recent Comments