AM335x 调试信息UART1输出代码修改
1. 关于pin_mux  的配置
代码修改位置:
/board/forlinx/ok335x/mux.c

 void enable_uart0_pin_mux(void)
{
configure_module_pin_mux(uart0_pin_mux_spl);
configure_module_pin_mux(uart1_pin_mux);
}

将这行代码打开。

代码跟踪流程:
arch/arm/cpu/armv7/start.S :
开头的_start 函数:

 .globl _start
_start: b reset

从reset 函数跳入cpu_init_crit 函数,还是在本文件内:

 reset:
bl save_boot_params
/*
* set the cpu to SVC32 mode
*/
mrs r0, cpsr
bic r0, r0, #0x1f
orr r0, r0, #0xd3
msr cpsr,r0
//......
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit
#endif
//......

从cpu_init_crit 函数进入lowlevel_init 函数。

这个函数在arch/arm/cpu/armv7/ti81xx/lowlevel_init.S 文件内。

 /*************************************************************************
*
* CPU_init_critical registers
*
* setup important registers
* setup memory timing
*
*************************************************************************/
cpu_init_crit:
/*
* Invalidate L1 I/D
*/
mov r0, # @ set up for MCR
mcr p15, , r0, c8, c7, @ invalidate TLBs
mcr p15, , r0, c7, c5, @ invalidate icache
mcr p15, , r0, c7, c5, @ invalidate BP array
mcr p15, , r0, c7, c10, @ DSB
mcr p15, , r0, c7, c5, @ ISB
//......
bl lowlevel_init @ go setup pll,mux,memory
//......

从lowlevel_init 函数进入s_init_start 函数。

 /*****************************************************************************
* lowlevel_init: - Platform low level init.
* Corrupted Register : r0, r1, r2, r3, r4, r5, r6
****************************************************************************/
.globl lowlevel_init
lowlevel_init: /* The link register is saved in ip by start.S */
mov r6, ip
/* check if we are already running from RAM */
ldr r2, _lowlevel_init
ldr r3, _TEXT_BASE
sub r4, r2, r3
sub r0, pc, r4
//......
ands r0, r0, #0xC0000000 /* MSB 2 bits <> 0 then we are in ocmc or DDR */
cmp r0, #0x80000000
bne s_init_start
mov r10, #0x01
b s_init_start //......

从s_init_start 函数进入s_init 函数。

 s_init_start:
mov r0, r10 /* passing in_ddr in r0 */
bl s_init
/* back to arch calling code */
mov pc, r6
/* the literal pools origin */
.ltorg
 /*
* early system init of muxing and clocks.
*/
void s_init(void)
{
/* Can be removed as A8 comes up with L2 enabled */
l2_cache_enable(); /* WDT1 is already running when the bootloader gets control
* Disable it to avoid "random" resets
*/
__raw_writel(0xAAAA, WDT_WSPR);
while(__raw_readl(WDT_WWPS) != 0x0);
__raw_writel(0x5555, WDT_WSPR);
while(__raw_readl(WDT_WWPS) != 0x0); //......
pll_init();
//......
enable_uart0_pin_mux(); //......

这个函数的实现在board/forlinx/ok335x/evm.c 文件内.

从这里进入enable_uart0_pin_mux() ;

 void enable_uart0_pin_mux(void)
{
configure_module_pin_mux(uart0_pin_mux_spl);
configure_module_pin_mux(uart1_pin_mux);
}

这函数的实现在board/forlinx/ok335x/mux.c 文件内。

把这个uart1_pin_mux 的功能打开。

2. 关于uart1 时钟的配置
代码添加位置:
board/forlinx/ok335x/pll.c
per_clocks_enable 函数内,添加对uart1 始终的配置。

change by chen 2016/9/30 的即是我修改的。

 static void per_clocks_enable(void)
{
/* Enable the module clock */
__raw_writel(PRCM_MOD_EN, CM_PER_TIMER2_CLKCTRL);
while (__raw_readl(CM_PER_TIMER2_CLKCTRL) != PRCM_MOD_EN); /* Select the Master osc 24 MHZ as Timer2 clock source */
__raw_writel(0x1, CLKSEL_TIMER2_CLK); /* UART0 */
__raw_writel(PRCM_MOD_EN, CM_WKUP_UART0_CLKCTRL);
while (__raw_readl(CM_WKUP_UART0_CLKCTRL) != PRCM_MOD_EN); /* change by chen 2016/9/30 */
__raw_writel(PRCM_MOD_EN, CM_PER_UART1_CLKCTRL);
while (__raw_readl(CM_PER_UART1_CLKCTRL) != PRCM_MOD_EN); /* UART3 */
__raw_writel(PRCM_MOD_EN, CM_PER_UART3_CLKCTRL);
while (__raw_readl(CM_PER_UART3_CLKCTRL) != PRCM_MOD_EN); /* GPMC */
__raw_writel(PRCM_MOD_EN, CM_PER_GPMC_CLKCTRL);
while (__raw_readl(CM_PER_GPMC_CLKCTRL) != PRCM_MOD_EN);
//.....
}

CM_PER_UART1_CLKCTR的宏定义设置在arch/arm/include/asm/arch-ti81xx/cpu.h文件内。

添加这一条宏定义。

 #define CM_PER_UART1_CLKCTRL        (CM_PER + 0x6C) /* UART1 */
#define CM_PER_UART3_CLKCTRL (CM_PER + 0x74) /* UART3 */

代码修改跟踪流程:

在上面已经跟踪的s_init 函数里面。

再进入pll_init () 函数。

 /*
* Configure the PLL/PRCM for necessary peripherals
*/
void pll_init()
{ // mpu_pll_config(MPUPLL_M_500);
mpu_pll_config(MPUPLL_M_720);
core_pll_config();
per_pll_config();
ddr_pll_config();
/* Enable the required interconnect clocks */
interface_clocks_enable();
/* Enable power domain transition */
power_domain_transition_enable();
/* Enable the required peripherals */
per_clocks_enable();
}

这个函数的实现在:board/forlinx/ok335x/pll.c

再进入per_clocks_enable()函数内,这个函数在本文件内实现。

 /*
* Enable the module clock and the power domain for required peripherals
*/
static void per_clocks_enable(void)
{
/* Enable the module clock */
__raw_writel(PRCM_MOD_EN, CM_PER_TIMER2_CLKCTRL);
while (__raw_readl(CM_PER_TIMER2_CLKCTRL) != PRCM_MOD_EN); /* Select the Master osc 24 MHZ as Timer2 clock source */
__raw_writel(0x1, CLKSEL_TIMER2_CLK); /* UART0 */
__raw_writel(PRCM_MOD_EN, CM_WKUP_UART0_CLKCTRL);
while (__raw_readl(CM_WKUP_UART0_CLKCTRL) != PRCM_MOD_EN); /* change by chen 2016/9/30 */
__raw_writel(PRCM_MOD_EN, CM_PER_UART1_CLKCTRL);
while (__raw_readl(CM_PER_UART1_CLKCTRL) != PRCM_MOD_EN);
// ..................................
}

3. 关于include/configs/ok335x.h配置
代码修改位置:

 #define CONFIG_SYS_NS16550_COM2     0x48022000   /* UART1 sbc-7109 */

 #define CONFIG_SERIAL2          1
#define CONFIG_CONS_INDEX 2

如上所示,添加这三个宏定义。
CONFIG_CONS_INDEX 这个为修改,原来uart0 输出调试信息的时候是为1。

代码跟踪流程:
arch/arm/cpu/armv7/start.S :从_start 进入reset 函数。

 /* Set stackpointer in internal RAM to call board_init_f */
call_board_init_f:
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
bic sp, sp, # /* 8-byte alignment for ABI compliance */
ldr r0,=0x00000000
bl board_init_f

再进入board_init_f 函数。

这个函数的实现在:
arch/arm/lib/board.c 文件内。

 void board_init_f(ulong bootflag)
{
bd_t *bd;
init_fnc_t **init_fnc_ptr;
gd_t *id;
ulong addr, addr_sp; /* Pointer is writable since we allocated a register for it */
gd = (gd_t *) ((CONFIG_SYS_INIT_SP_ADDR) & ~0x07);
/* compiler optimization barrier needed for GCC >= 3.4 */
__asm__ __volatile__("": : :"memory"); memset((void *)gd, , sizeof(gd_t)); gd->mon_len = _bss_end_ofs; for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != ) {
hang ();
}
}
//......
}

在这个函数内有for循环运行一系列的初始化。

这个数组有如下定义:

 init_fnc_t *init_sequence[] = {
#if defined(CONFIG_ARCH_CPU_INIT)
arch_cpu_init, /* basic arch cpu dependent setup */
#endif
#if defined(CONFIG_BOARD_EARLY_INIT_F)
board_early_init_f,
#endif
timer_init, /* initialize timer */
#ifdef CONFIG_FSL_ESDHC
get_clocks,
#endif
env_init, /* initialize environment */
init_baudrate, /* initialze baudrate settings */
serial_init, /* serial communications setup */
console_init_f, /* stage 1 init of console */
display_banner, /* say that we are here */
#if defined(CONFIG_DISPLAY_CPUINFO)
print_cpuinfo, /* display cpu info (and speed) */
#endif
#if defined(CONFIG_DISPLAY_BOARDINFO)
checkboard, /* display board info */
//.......
}

再进入serial_init 串行通信初始化。

这个函数的实现在:drivers/serial/serial.c 文件后内。

 #if !defined(CONFIG_SERIAL_MULTI)
int serial_init (void)
{ int clock_divisor; #ifdef CONFIG_NS87308
initialise_ns87308();
#endif #ifdef CONFIG_SYS_NS16550_COM1
clock_divisor = calc_divisor(serial_ports[]);
NS16550_init(serial_ports[], clock_divisor);
#endif
#ifdef CONFIG_SYS_NS16550_COM2
clock_divisor = calc_divisor(serial_ports[]);
NS16550_init(serial_ports[], clock_divisor);
#endif
#ifdef CONFIG_SYS_NS16550_COM3
clock_divisor = calc_divisor(serial_ports[]);
NS16550_init(serial_ports[], clock_divisor);
#endif
//......
}

第一个CONFIG_SYS_NS16550_COM1为UART0的串口初始化。

第二个CONFIG_SYS_NS16550_COM2要自己定义,在include/configs/ok335x.h 内添加。

 #define CONFIG_SYS_NS16550_COM2     0x48022000   /* UART1 sbc-7109 */           

这里的话只是完成了初始化,但是还要指定调试信息输出的端口。

回到arch/arm/lib/board.c
进入display_banner 函数,这个函数的实现在本文件内实现。

 static int display_banner(void)
{
printf("\n\n%s\n\n", version_string);
printf("chen goto it ....\n") ;
debug("U-Boot code: %08lX -> %08lX BSS: -> %08lX\n",
_TEXT_BASE,
_bss_start_ofs + _TEXT_BASE, _bss_end_ofs + _TEXT_BASE);
#ifdef CONFIG_MODEM_SUPPORT
debug("Modem Support enabled\n");
#endif
#ifdef CONFIG_USE_IRQ
debug("IRQ Stack: %08lx\n", IRQ_STACK_START);
debug("FIQ Stack: %08lx\n", FIQ_STACK_START);
#endif return ();
}

进入printf 函数,这个函数在/common/console.c 文件内实现。

 int printf(const char *fmt, ...)
{
va_list args;
uint i;
char printbuffer[CONFIG_SYS_PBSIZE]; va_start(args, fmt); /* For this to work, printbuffer must be larger than
* anything we ever want to print.
*/
i = vsprintf(printbuffer, fmt, args);
va_end(args); /* Print the string */
puts(printbuffer);
return i;
}

还是在本文件内,进入puts 函数:

 void puts(const char *s)
{
#ifdef CONFIG_SILENT_CONSOLE
if (gd->flags & GD_FLG_SILENT)
return;
#endif #ifdef CONFIG_DISABLE_CONSOLE
if (gd->flags & GD_FLG_DISABLE_CONSOLE)
return;
#endif if (gd->flags & GD_FLG_DEVINIT) {
/* Send to the standard output */
fputs(stdout, s);
} else {
/* Send directly to the handler */
serial_puts(s);
}
}


再进入serial_puts 函数,这个函数的实现在drivers/serial/serial.c文件内实现。

 void
serial_puts(const char *s)
{
_serial_puts(s,CONFIG_CONS_INDEX);
}


这里指定了输出的端口,这个宏定义也是在include/configs/ok335x.h 里面定义:

 #define CONFIG_CONS_INDEX       2        

到此,在u-boot 阶段串口输出的调试信息即可以在UART1输出。

4. 关于kernel 调试信息的打印配置
在u-boot 文件夹内
include/configs/ok335x.h
将console=ttyO1 这样的话kernel 的调试信息也将在UART1输出。

 #ifdef CONFIG_ANDROID
#define CON \
"console=ttyO0,115200n8 earlyprintk androidboot.console=ttyO0\0" \
"optargs=init=/init\0" \
"mmcroot=/dev/mmcblk0p2 rw\0" \
"mmcrootfstype=ext4 rootwait\0" \
"nandroot=ubi0:rootfs rw ubi.mtd=7,2048\0" \
"nandrootfstype=ubifs rootwait=1\0"
#else
#define CON \
"console=ttyO1,115200n8\0" \
"optargs=\0" \
"mmcroot=/dev/mmcblk0p2 ro\0" \
"mmcrootfstype=ext3 rootwait\0" \
"nandroot=ubi0:rootfs rw ubi.mtd=7,2048\0" \
"nandrootfstype=ubifs rootwait=1\0"
#endif

5. 关于文件系统调试信息的配置
在文件系统目录。
etc/inittab

46行位UART1 输出,45行为UART0输出。

  #::respawn:/sbin/getty  ttyO0
::respawn:/sbin/getty ttyO1

am335x UART1输入u-boot 调试信息代码修改的更多相关文章

  1. 在vscode中进行nodejs服务端代码调试(代码修改自动重启服务端)

    使用到的是nodemon,具体在package.json文件中配置如下: "scripts": { "start": "node ./bin/www& ...

  2. 利用 Serial Over Lan(SOL)搭建 XEN 的调试信息输出环境

    如有转载,请注明出处与本文连接,谢谢! 修改XEN的源码实现额外的功能,需要有一个调试环境来得到XEN的调试信息(有关源码编译并安装 XEN 请阅读我以前的博文:在CentOS下源码安装 Xen并搭建 ...

  3. 利用chrome调试JavaScript代码

    看见网上很多人问怎么用chrome调试JavaScript代码,我也对这个问题抱着疑问,但是没有找到一篇能用的中文文章(可能我的google有问题),也不知道怎么点出一篇E文的,感觉作者写得不错,所以 ...

  4. lr 增强窗格中,如何生成调试信息?

    我是根据电子书来操作的, 如何生成调试信息?在测试运行的某些时候,经常需要向输出设备发送消息,指出当前位置和其他信息.这些输出消息会出现在回放日志和 Controller 的输出窗口中.可以发送标准输 ...

  5. Android调试系列—使用android studio调试smali代码

    1.工具介绍 使用工具 android killer:用于反编译apk包,得到smali代码 android studio:调试smali代码工具,或者使用idea,android studio就是在 ...

  6. OpenGL笔记<5> shader 调试信息获取 Debug

    我们今天来讲调试信息,这个东西讲起来会比较无聊,因为都是一些函数调用,没啥可讲的,函数就是那样用的,不过其效果挺好玩的,同时在程序设计中也是很必要的,所以还是来写一下,不过,就是因为知识比较固定且简单 ...

  7. 【转】VC调试的时候 “没有调试信息,未加载符号”

    概述调试是一个程序员最基本的技能,其重要性甚至超过学习一门语言.不会调试的程序员就意味着他即使会一门语言,却不能编制出任何好的软件.这里我简要的根据自己的经验列出调试中比较常用的技巧,希望对大家有用. ...

  8. 利用pycharm远程调试openstack代码

    1.安装pycharm专业版 本文安装pycharm 2016.2.3专业版.网上教程较多,这里不做详细介绍,只要到pycharm官网上下载应用程序进行安装即可. 2.pycharm配置 (1)首先按 ...

  9. 如何调试Javascript代码

    转自原文如何调试Javascript代码 目前,常用的浏览器IE.Chrome.Firefox都有相应的脚本调试功能.作为我们.NET 阵营,学会如何在IE中调试JS就足够了,在掌握了IE中的调试方法 ...

随机推荐

  1. Jetty 简单使用

    Jetty与Tomcat类似,也是一种Servlet引擎,可以用来运行Java Web项目. 其常被嵌入到项目中,以便于开发.测试,以及Demo等项目的运行. 1.作为插件——作为开发.测试时项目运行 ...

  2. Xcode卡顿解决方案

    1.禁用indexing 在终端(terminal) 输入 defaults write com.apple.dt.XCode IDEIndexDisable 并重启Xcode. (不是大神勿用哈,附 ...

  3. CSS样式优先级

    关于CSS样式优先级 一般情况下: [1位重要标志位] > [4位特殊性标志] > 声明先后顺序 !important > [ id > class > tag ] 使用 ...

  4. 为你的Visual Studio单独设置代理服务器

    http://blog.sina.com.cn/s/blog_58c506600101tycn.html 最近,因为国内访问Visual Studio Online(微软的免费代码托管服务,以前叫Te ...

  5. struts2 拦截器和actioninvocation、PreResultListener

       Interceptor说明 Interceptor的接口定义没有什么特别的地方,除了init和destory方法以外,intercept方法是实现整个拦截器机制的核心方法.而它所依赖的参数Act ...

  6. iOS-马上着手开发iOS应用应用程序-第二部分构建应用程序

    第二部分构建应用程序 1,应用程序开发过程 2,设计用户界面 3,定义交互 4,教程:串联图 1,应用程序开发过程 定义概念 设计用户界面 定义交互 实现行为整合数据 对象是应用程序的基石 类是对象的 ...

  7. Fortify

    sourceanalyzer -b my_buildid -scan -f xxx.fpr -b  取一个build的ID号,通常以这个项目名称加扫描时间为buildID-Xmx 指定JVM使用的最大 ...

  8. svn branch and merge(svn切换分支和合并)详解

    下文的实践主要是参考了TortoiseSVN的帮助文档和Subversion的在线文档,Subversion的在线文档:http://svnbook.red-bean.com/en/1.5/svn-b ...

  9. CF451B Sort the Array 水题

    Codeforces Round #258 (Div. 2) Sort the Array B. Sort the Array time limit per test 1 second memory ...

  10. 江湖救急:webbrowser中js文件丢失问题~

    页面中,有一个按钮,点击按钮通过js create 了一个 script标签 ,链接加载一个外部js文件,执行该js文件 $("#a").click(function(){ $.g ...