Archives
If you have issues when using qemu-omap3, please post it on issues page of qemu-omap3 on googlecode. A google groups of qemu-omap3 is also available. Thanks.
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!
x-load 已经可以在qemu-omap3中运行起来。对x-load主要做了两个地方的修改:
1. 对判断外部输入时钟频率的部分,做了修改。x-load判断外部时钟频率的方法是先设置32KHZ的基准时钟,然后设置GP1的时钟源为SYS_CLK。然后读取GP1 Timer在20个cycle内的差值,进而判断时钟。这个方法在emulator中有的时候并不是很准。因为emulator除了执行指令外,还需要做其他事情。有的时候,emulator去读取GP1 Timer 的时候,实际上运行的时间已经不止ARM 20个cycle的时间,因此读取出来的counter值偏大。而x-load仍然认为刚才是跑了20个cycle。因此,得到的频率比实际的频率大。在 qemu-omap3中,目前认为外部时钟的频率是12MHZ13MHZ,因此,去掉了x-load中判断外部时钟频率的部分,在x-load中直接赋值外部时钟频率12MHZ13MHZ.
2. 去掉了nand flash中进入ECC检查的部分。也就是注释掉drivers/k9f1g08r0a.c中的宏ECC_CKECK_ENABLE
//57 #define ECC_CHECK_ENABLE
下面是x-load运行的信息:
# ./qemu-system-arm -M beagle -mtdblock beagle-nand.bin -serial stdio -nographic
Texas Instruments X-Loader 1.41
Starting OS Bootloader...
运行到u-boot的时候还有点问题。go on working.
讨论见这里:http://lists.gnu.org/archive/html/qemu-devel/2006-11/msg00144.html
Fabrice 的回复:http://lists.gnu.org/archive/html/qemu-devel/2006-11/msg00149.html
这里还有qemu 中3D加速的讨论:http://www.mail-archive.com/qemu-devel@nongnu.org/msg15702.html
Recent Comments