怎样样解决嵌入式linux移植过程中“串口终端”的问题?
Pxa27x的板子嵌入式linux系统移植,近来在移植到linux2.4.21过程时,遇到一个并口终端难以输出信息的问题,bootloader引导时才能输出信息,但引导kernel时就停在那了,没有任何显示。
在网上搜索到一些资料,也排除了这些可能的诱因,但还是没才能解决这个并口终端输出的问题。通过剖析bootloader到kernel内核引导的这一过程,最后把目标锁定在了kernel解压缩的过程中,恐怕大家使用的kenel都是经过压缩的内核,在BootLoader完成系统的引导之后并将Linux内核调入显存以后,跳转到kernel的起始位置。假如kernel没有压缩,就可以启动了(步入arch/arm/kernel/head_armv.S)。假如kernel压缩过嵌入式linux系统移植adobe air linux,则要进行解压,在压缩过的kernel背部有解压程序。压缩过得kernel入口第一个文件源码位置在arch/arm/boot/compressed/head.S。它将调用函数decompress_kernel(),这个函数在文件arch/arm/boot/compressed/misc.c中,decompress_kernel()又调用proc_decomp_setup(),arch_decomp_setup()进行设置,之后使用在复印出信息“UncompressingLinux...”后,调用gunzip()。将内核放于指定的位置。
decompress_kernel(ulgoutput_start,ulgfree_mem_ptr_p,ulgfree_mem_ptr_end_p,intarch_id)
output_data=(uch*)output_start;/*Pointstokernelstart*/
free_mem_ptr=free_mem_ptr_p;
free_mem_ptr_end=free_mem_ptr_end_p;
__machine_arch_type=arch_id;
arch_decomp_setup();
makecrc();
puts("UncompressingLinux...");
gunzip();
puts("done,bootingthekernel./n");
returnoutput_ptr;
其中的puts就是通过并口输出信息linux系统界面,再看一下puts的定义(在include/asm-arm/arch-pxa/uncompress.h中):
#defineFFUART((volatileunsignedlong*)0x40100000)
#defineBTUART((volatileunsignedlong*)0x40200000)
#defineSTUART((volatileunsignedlong*)0x40700000)
#defineUARTFFUART
static__inline__voidputc(charc)
while(!(UART[5]&0x20));
UART[0]=c;
/*
*Thisdoesnotappendanewline
*/
staticvoidputs(constchar*s)
while(*s){
putc(*s);
if(*s=='/n')
putc('/r');
s++;
发觉问题了,这儿UART定义为FFUART,而我在bootloader中初始化拿来并口输出的是STDUART,因而puts调用的putc中的while句子仍然会处于循环中,内核启动就停在此处了。
解决方式很简单,让UART指向STDUART就可以了(#defineUARTSTDUART)。
保存,重新编译,下载,上电,OK!
下边是网上找的一些资料:
在bootloader的运行过程中我们可以正确地向并口终端输出信息,但当bootloader启动内核后却未能见到内核的启动输出信息。对这一问题的缘由可以从以下几个方面来考虑:
(1)首先请确认你的内核在编译时配置了对并口终端的支持,并配置了正确的并口驱动程序。
(2)你的bootloader对并口的初始化设置可能会和内核对并口的初始化设置不一致。据悉,对于例如s3c44b0x这样的CPU,CPU时钟频度的设置也会影响并口,因而假如bootloader和内核对其CPU时钟频度的设置不一致,也会使并口终端未能正确显示信息。
(3)最后,还要确认bootloader所用的内核基地址必须和内核映像在编译时所用的运行基地址一致,尤其是对于uClinux而言。假定你的内核映像在编译时用的基地址是0xcxc0008000,但你的bootloader却将它加载到0xcxc0010000处去执行,这么内核映像其实不能正确地执行了。