GNU ARM汇编--(十五)linux下的printascii

发布者:神雕最新更新时间:2015-10-14 来源: eefocus关键字:ARM汇编  linux  printascii 手机看文章 扫描二维码
随时随地手机看文章
        在前面对很多s3c2440的功能模块进行学习后,已经具备了将这些模块综合起来的条件,基于此,将前面的代码综合成一个简单的bootloader.自己写的bootloader在引导kernel的时候,串口输出只有Uncompressing Linux...和done, booting the kernel。串口有这个输出,说明kernel被正确引导了,但是串口有问题。

        这篇blog只是分析解决这个问题的第一步:

        既然"Uncompressing Linux..."这句打印是kernel代码中的,那kernel的其他打印怎么没有?

        在archarmootcompressed目录下的misc.c中,上面的打印是在decompress_kernel函数中,而该函数是在kernel的初始汇编中调用的,也就是说这个时候kernel的串口驱动肯定是没有工作的,那这里的串口输出只能是用bootloader初始化好的串口,

        putstr("Uncompressing Linux...");

        putstr(" done, booting the kernel. ");

 

[html] view plaincopy
 
  1. static void putstr(const char *ptr)  
  2. {  
  3.     char c;  
  4.   
  5.     while ((c = *ptr++) != '') {  
  6.         if (c == ' ')  
  7.             putc(' ');  
  8.         putc(c);  
  9.     }  
  10.   
  11.     flush();  
  12. }  
  13.   

        在includeasm-armplat-s3uncompress.h中,有putc函数的定义:

 

 

[html] view plaincopy
 
  1. static void putc(int ch)  
  2. {  
  3.     if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) {  
  4.         int level;  
  5.   
  6.         while (1) {  
  7.             level = uart_rd(S3C2410_UFSTAT);  
  8.             level &= fifo_mask;  
  9.   
  10.             if (level < fifo_max)  
  11.                 break;  
  12.         }  
  13.   
  14.     } else {  
  15.         /* not using fifos */  
  16.   
  17.         while ((uart_rd(S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE) != S3C2410_UTRSTAT_TXE)  
  18.             barrier();  
  19.     }  
  20.   
  21.     /* write byte to transmission register */  
  22.     uart_wr(S3C2410_UTXH, ch);  
  23. }  
        从这里可以看到,这里的输出的确是利用了bootloader中对串口的初始化,但是这部分代码还是通用的:不管在bootloader中将串口初始化为用fifo还是非fifo的,这一小块代码都是可以正常串口输出的。

 

        既然明白了这两句打印为什么可以输出后,就要排查后续没有打印的原因了,这里我们就利用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函数修改如下:

[page]

[cpp] view plaincopy
 
  1. asmlinkage int printk(const char *fmt, ...)  
  2. {  
  3.     va_list args;  
  4.     int r;  
  5.       
  6. #ifdef CONFIG_DEBUG_LL  
  7.         extern void printascii(const char *);  
  8.         char buff[256];  
  9. #endif  
  10.   
  11.     va_start(args, fmt);  
  12.     r = vprintk(fmt, args);  
  13.       
  14. #ifdef CONFIG_DEBUG_LL  
  15.         vsprintf(buff, fmt, args);  
  16. #endif  
  17.     va_end(args);  
  18. #ifdef CONFIG_DEBUG_LL  
  19.         printascii(buff);  
  20. #endif  
  21.   
  22.     return r;  
  23. }  


 

        重新编译内核烧写后,发现kernel的输出都有了,这说明kernel的串口驱动有问题,或者说要去研究要bootloader如何向kernel传递参数的。另外一个疑惑就是printk没有输出,为什么printascii有输出呢?

        查看源码才知道,printascii是针对arm平台的debug函数:

        在archarmkerneldebug.S中

[html] view plaincopy
 
  1. ENTRY(printascii)  
  2.         addruart r3  
  3.         b   2f  
  4. 1:      waituart r2, r3  
  5.         senduart r1, r3  
  6.         busyuart r2, r3  
  7.         teq r1, #' '  
  8.         moveq   r1, #' '  
  9.         beq 1b  
  10. 2:      teq r0, #0  
  11.         ldrneb  r1, [r0], #1  
  12.         teqne   r1, #0  
  13.         bne 1b  
  14.         mov pc, lr  
  15.   

        在includeasm-armarch-s3c241debug-macro.S中,addruart宏定义如下:

 

 

[html] view plaincopy
 
  1.   .macro addruart, rx  
  2.         mrc p15, 0,  x, c1, c0  
  3.         tst  x, #1  
  4.         ldreq    x, = S3C24XX_PA_UART  
  5.         ldrne    x, = S3C24XX_VA_UART  
  6. #if CONFIG_DEBUG_S3C_UART != 0  
  7.         add  x,  x, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C_UART)  
  8. #endif  
  9.     .endm  
  10.   
        从p15协处理器来查看MMU是否打开了,从而用PA或者VA,这说明MMU打开前或者后都可以用printascii进行debug。

 

        在includeasm-armplat-s3cdebug-macro.S中,有senduart、busyuart和waituart的定义,具体代码就不贴出来了,这三个代码实现了串口的输出,这三个宏定义针对fifo和非fifo的情况都做了处理,保证代码的健壮。

        到这里,可以看出来printascii基于bootloader或者kernel对串口的初始化后才能起作用,但一般用printascii辅助debug主要用于kernel的最开始部分,这时候的串口初始化用的还是bootloader的。当然,在kernel的串口驱动正常工作后,printascii同样是起作用的。最后,printascii代码还是很健壮的,而且printascii的生命周期也是相当长的,从kernel启动开始到kernle关闭之时,printascii都是能向串口输出信息的。

        在用printascii函数debug和分析printascii是如何实现之后,对于开头的问题,进一步缩小了分析目标,后面的分析将围绕bootloader与kernel之间的参数传递问题,以及linux的串口驱动。

关键字:ARM汇编  linux  printascii 引用地址:GNU ARM汇编--(十五)linux下的printascii

上一篇:GNU ARM汇编--(十四)GNU ARM汇编下做任务调度
下一篇:GNU ARM汇编--(十六)bootloader与kernel之间

推荐阅读最新更新时间:2024-03-16 14:35

汽车级Linux的标准参考平台采用瑞萨电子R-Car入门套件,可加速下一代联网汽车的IVI开发
瑞萨电子株式会社今日宣布,汽车级Linux(AGL)已将R-Car入门套件作为其一个软件开发的标准参考软件平台而采用。 AGL是一个合作的开源项目,将汽车制造商、供应商和技术公司聚集起来,为汽车应用构建基于Linux的开放软件平台,可以作为实际应用的行业标准。采用瑞萨R-Car入门工具包使软件开发人员能够轻松获取运行该项目开发的软件和硬件环境,快速、轻松地为下一代联网汽车开发车载信息娱乐(IVI)应用软件。下面就随汽车电子小编一起来了解一下相关内容吧。 R-Car入门套件支持最新的Unified Code Base 3.0 64位软件环境 汽车级Linux标准参考平台采用瑞萨电子R-Car入门套件 R-Car 入门套件
[汽车电子]
通用和Red Hat合作开发基于Linux的全新开源车载系统
包括汽车和卡车在内,目前大多数车载系统都是基于相对封闭的专有软件,这些企业包括 Research In Motion(黑莓背后的公司)、一级供应商大陆集团和 Google。通用汽车希望通过与软件公司 Red Hat 的合作来改变这种状况。 本周二,通用汽车公司宣布,IBM 旗下的 Red Hat 公司将牵头开发一个新的、基于 Linux 的开源操作系统,该系统将支撑通用汽车在 2021 年宣布的基于云的客户服务平台 Ultifi 计划。通用汽车的 Ultifi平台将监督从未来的信息娱乐系统操作和电池管理到该公司的汽车与其他车辆、智能基础设施甚至家庭的通信方式等一切。 那么相比较市场上的其他车载系统,Red Hat 的系统有
[汽车电子]
ARM下启动linux条件-bootloader
为了启动在ARM板上启动linux系统,需要在启动kernel之前运行一小段叫bootloader的程序,bootloader初始化各种设备后调用kernel,并向其传递一些参数; 言之,bootloader必须完成以下作用: (1) 设置并初始化内存; (2) 初始化一个串口; (3) 判断平台设备类型; (4) 设置启动参数列表;//标记列表(tagged list) (5) 启动内核; 1 . 设置并初始话内存 bootloader用于寻找并初始化kernel启动后在RAM内存中存储的易丢失性数据,按某个机器特定方式执行(或者用基本的算法自动加载数据和计算RA
[单片机]
基于ARM9的嵌入式LINUX地震数据采集系统设计
    本文简要地介绍了微处理器AT91RM9200和嵌入式LINUX操作系统,同时讨论了地震数据采集系统的硬件设计以及相应的软件设计方法。     引言     随着数字技术的飞速发展,数字化仪器已成为观测技术领域的主流仪器,因而数据采集技术也成为观测技术领域中一个十分重要的技术环节。众所周知,地震预报是一个的世界性难题,作为地震预报的基础,地震及地震前兆观测数据的地位可想而知,获得真实、可靠的观测数据取决于地震观测仪(包括传感器和采集器两部分)。伴随着计算机的迅速发展,以嵌入式为平台的数据采集系统就应运而生了,它具有可靠性高,体积小,易扩展、功能强,开发周期短、成本低。本论文是基于东方地球物理公司地震采集系统设计项目,
[嵌入式]
Linux系统在嵌入式DVR中的应用
以强稳定性的优势,嵌入式DVR越来越被安防行业与广大客户所接受。嵌入式DVR的稳定性优势不光来自于硬件的低故障率,很大因素取决于嵌入式DVR中所采用的操作系统及应用软件的高稳定性,它所选用的软件平台起着至关重要的作用。   从国内嵌入式DVR的领军人物海康威视公司在嵌入式DVR的开发历程上,可清晰地看出Linux系统在嵌入式DVR中的地位日益凸显出来。海康威视公司第一代嵌入式DVR的研发初期,在确定以Samsung S3C2510加Ti的DM642作为其硬件平台的时候,采用了Linux与VxWorks同时开发,相互参照、评估,最终主要由于基于对WindRiver 的VxWorks商用软件的信赖,选用了VxWorks作为其操作系统
[单片机]
linux 2.6.32 在arm9(s3c2440)平台的移植
板子用的友善的mini2440, 起初按照光盘提供的手册, 照猫画虎,,,,,,,,,但是遇到各种问题, 很多未解决.....原因是还没理解每层目录的Makefile和Kconfig的关系, 以及在Kernel Configure菜单树中对应的选项, 以及对nand_flash设备的结构体的意义没搞清楚,~ so~ 在http://www.kernel.org/ 下载2.6.32的源代码. 编译器用的arm-linux-gcc 4.1.2 . 1 内核代码/uboot代码中中机器码的定义位置,在/root/linux-2.6.32/arch/arm/tools/mach-types 和 uboot/include/asm-
[单片机]
嵌入式Linux应用程序访问物理地址的实例
前言   按照Linux分层驱动思想,外设驱动与主机控制器的驱动不相关,主机控制器的驱动不关心外设,而外设驱动也不关心主机,外设访问核心层的通用应用程序接口进行数据传输,主机和外设之间可以进行任意的组合。这样思想要求应用程序不应当直接访问物理地址,而是应当通过驱动程序的调用来实现,以便保持应用程序的可移植性,操作访问的统一性,应用程序利用系统的统一调用接口访问外设,如使用write(),read()等函数进行实际的外设读写控制。应用程序通过调用接口进入内核函数后,内核利用copy_from_user()获得应用层数据,内核驱动程序也通过分层最终执行物理访问,之后把获得的数据用copy_to_user()回传给应用程序的调用者。由于
[嵌入式]
利用MLD自动化操作系统移植降低Linux的成本
随着基于 Linux 的嵌入式系统得到日益广泛的应用,人们不禁要问,类似 Linux 这样的免费开放源代码操作系统的真正成本到底是多少?其实,最主要的成本是在劳动力上。要将 Linux 内核移植到定制嵌入式处理系统,您必须对产品所需要的内核功能、这些功能对其他内核服务的依赖程度以及您的工程团队的技能都有深入的了解。更重要的是,要了解可以借助哪些新技术来使这些任务自动化,以达到节省成本的目标。 开放源代码与商业操作系统 我们很多人都看过为如何使用 Linux 源代码提供指导的 GNU 通用公共许可证 (GPL)。要确定在系统中使用 Linux 的成本,一般来说,第一步是了解 Linux 的哪些部分是真正免费且不受法律约束的,哪些
[应用]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
热门活动
换一批
更多
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

更多精选电路图
换一换 更多 相关热搜器件
更多每日新闻
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved