GNU ARM汇编--(十五)linux下的printascii
这篇blog只是分析解决这个问题的第一步:
既然"Uncompressing Linux..."这句打印是kernel代码中的,那kernel的其他打印怎么没有?
在archarmootcompressed目录下的misc.c中,上面的打印是在decompress_kernel函数中,而该函数是在kernel的初始汇编中调用的,也就是说这个时候kernel的串口驱动肯定是没有工作的,那这里的串口输出只能是用bootloader初始化好的串口,
putstr("Uncompressing Linux...");
putstr(" done, booting the kernel.");
[html]view plaincopy
- staticvoidputstr(constchar*ptr)
- {
- charc;
- while((c=*ptr++)!=){
- if(c==)
- putc();
- putc(c);
- }
- flush();
- }
在includeasm-armplat-s3uncompress.h中,有putc函数的定义:
[html]view plaincopy
- staticvoidputc(intch)
- {
- if(uart_rd(S3C2410_UFCON)&S3C2410_UFCON_FIFOMODE){
- intlevel;
- while(1){
- level=uart_rd(S3C2410_UFSTAT);
- level&=fifo_mask;
- if(level
- break;
- }
- }else{
- /*notusingfifos*/
- while((uart_rd(S3C2410_UTRSTAT)&S3C2410_UTRSTAT_TXE)!=S3C2410_UTRSTAT_TXE)
- barrier();
- }
- /*writebytetotransmissionregister*/
- uart_wr(S3C2410_UTXH,ch);
- }
既然明白了这两句打印为什么可以输出后,就要排查后续没有打印的原因了,这里我们就利用printascii函数来debug,我们知道kernel的printf函数是printk,在printk函数内部添加printascii函数,make menuconfig中选中:
Kernel hacking下的[*] Kernel low-level debugging functions下的[*] Kernel low-level debugging messages via S3C UART,并选择(0) S3C UART to use for low-level debug
Device Drivers -->Character devices-->Serial drivers--><*> Samsung S3C2410/S3C2440/S3C2442/S3C2412 Serial port support和[*] Support for console on S3C2410 serial port
printk函数修改如下:
[cpp]view plaincopy
- asmlinkageintprintk(constchar*fmt,...)
- {
- va_listargs;
- intr;
- #ifdefCONFIG_DEBUG_LL
- externvoidprintascii(constchar*);
- charbuff[256];
- #endif
- va_start(args,fmt);
- r=vprintk(fmt,args);
- #ifdefCONFIG_DEBUG_LL
- vsprintf(buff,fmt,args);
- #endif
- va_end(args);
- #ifdefCONFIG_DEBUG_LL
- printascii(buff);
- #endif
- returnr;
- }
重新编译内核烧写后,发现kernel的输出都有了,这说明kernel的串口驱动有问题,或者说要去研究要bootloader如何向kernel传递参数的。另外一个疑惑就是printk没有输出,为什么printascii有输出呢?
查看源码才知道,printascii是针对arm平台的debug函数:
在archarmkerneldebug.S中
[html]view plaincopy
- ENTRY(printascii)
- addruartr3
- b2f
- 1:waituartr2,r3
- senduartr1,r3
- busyuartr2,r3
- teqr1,#
- moveqr1,#
- beq1b
- 2:teqr0,#0
- ldrnebr1,[r0],#1
- teqner1,#0
- bne1b
- movpc,lr
在includeasm-armarch-s3c241debug-macro.S中,addruart宏定义如下:
[html]view plaincopy
- .macroaddruart,rx
- mrcp15,0,x,c1,c0
- tstx,#1
- ldreqx,=S3C24XX_PA_UART
- ldrnex,=S3C24XX_VA_UART
- #ifCONFIG_DEBUG_S3C_UART!=0
- addx,x,#(S3C2410_UART1_OFF*CONFIG_DEBUG_S3C_UART)
- #endif
- .endm
在includeasm-armplat-s3cdebug-macro.S中,有senduart、busyuart和waituart的定义,具体代码就不贴出来了,这三个代码实现了串口的输出,这三个宏定义针对fifo和非fifo的情况都做了处理,保证代码的健壮。
到这里,可以看出来printascii基于bootloader或者kernel对串口的初始化后才能起作用,但一般用printascii辅助debug主要用于kernel的最开始部分,这时候的串口初始化用的还是bootloader的。当然,在kernel的串口驱动正常工作后,printascii同样是起作用的。最后,printascii代码还是很健壮的,而且printascii的生命周期也是相当长的,从kernel启动开始到kernle关闭之时,printascii都是
ARM汇编linuxprintasci 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)