首页 > 代码库 > am335x UART1输入u-boot 调试信息代码修改

am335x UART1输入u-boot 调试信息代码修改

 

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

1 void enable_uart0_pin_mux(void)                                                 2 {                                                                               3     configure_module_pin_mux(uart0_pin_mux_spl);                                4     configure_module_pin_mux(uart1_pin_mux);                                    5 }                                                                               6                                                                                

将这行代码打开。

 

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

1 .globl _start                                                                   2 _start: b   reset   

 

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

 1 reset:                                                                           2     bl  save_boot_params                                                         3     /*                                                                           4      * set the cpu to SVC32 mode                                                 5      */                                                                          6     mrs r0, cpsr                                                                 7     bic r0, r0, #0x1f                                                            8     orr r0, r0, #0xd3                                                            9     msr cpsr,r0                10     //......11 #ifndef CONFIG_SKIP_LOWLEVEL_INIT                                               12     bl  cpu_init_crit                                                           13 #endif                                     14     //......

 

从cpu_init_crit 函数进入lowlevel_init 函数。

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

 1 /*************************************************************************       2  *                                                                               3  * CPU_init_critical registers                                                   4  *                                                                               5  * setup important registers                                                     6  * setup memory timing                                                           7  *                                                                               8  *************************************************************************/      9 cpu_init_crit:                                                                  10     /*                                                                          11      * Invalidate L1 I/D                                                        12      */                                                                         13     mov r0, #0          @ set up for MCR                                        14     mcr p15, 0, r0, c8, c7, 0   @ invalidate TLBs                               15     mcr p15, 0, r0, c7, c5, 0   @ invalidate icache                             16     mcr p15, 0, r0, c7, c5, 6   @ invalidate BP array                           17     mcr     p15, 0, r0, c7, c10, 4  @ DSB                                       18     mcr     p15, 0, r0, c7, c5, 4   @ ISB                                       19     //......20     bl  lowlevel_init       @ go setup pll,mux,memory  21     //......

 

 

从lowlevel_init 函数进入s_init_start 函数。

 1 /*****************************************************************************   2  * lowlevel_init: - Platform low level init.                                     3  * Corrupted Register : r0, r1, r2, r3, r4, r5, r6                               4  ****************************************************************************/   5 .globl lowlevel_init                                                             6 lowlevel_init:                                                                   7                                                                                  8     /* The link register is saved in ip by start.S */                            9     mov r6, ip                                                                  10     /* check if we are already running from RAM */                              11     ldr r2, _lowlevel_init                                                      12     ldr r3, _TEXT_BASE                                                          13     sub r4, r2, r3                                                              14     sub r0, pc, r4                                                             15     //......16     ands r0, r0, #0xC0000000 /* MSB 2 bits <> 0 then we are in ocmc or DDR */   17     cmp r0, #0x80000000                                                         18     bne s_init_start                                                            19     mov r10, #0x01                                                              20     b s_init_start                                                             21 22     //......


从s_init_start 函数进入s_init 函数。

1 s_init_start:                                                                   2     mov r0, r10 /* passing in_ddr in r0 */                                      3     bl s_init                                                                   4     /* back to arch calling code */                                             5     mov pc, r6                                                                  6     /* the literal pools origin */                                              7     .ltorg                                                                      8                                                                                 
 1 /*                                                                               2  * early system init of muxing and clocks.                                       3  */                                                                              4 void s_init(void)                                                                5 {                                                                                6     /* Can be removed as A8 comes up with L2 enabled */                          7     l2_cache_enable();                                                           8                                                                                  9     /* WDT1 is already running when the bootloader gets control                 10      * Disable it to avoid "random" resets                                      11      */                                                                         12     __raw_writel(0xAAAA, WDT_WSPR);                                             13     while(__raw_readl(WDT_WWPS) != 0x0);                                        14     __raw_writel(0x5555, WDT_WSPR);                                             15     while(__raw_readl(WDT_WWPS) != 0x0);          16 17     //......18     pll_init();19     //......20     enable_uart0_pin_mux();    21 22     //......23 

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

从这里进入enable_uart0_pin_mux() ;

1 void enable_uart0_pin_mux(void)                                                 2 {                                                                               3     configure_module_pin_mux(uart0_pin_mux_spl);                                4     configure_module_pin_mux(uart1_pin_mux);                                    5 }                                                                               

 

这函数的实现在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 的即是我修改的。

 1 static void per_clocks_enable(void)                                              2 {                                                                                3     /* Enable the module clock */                                                4     __raw_writel(PRCM_MOD_EN, CM_PER_TIMER2_CLKCTRL);                            5     while (__raw_readl(CM_PER_TIMER2_CLKCTRL) != PRCM_MOD_EN);                   6                                                                                  7     /* Select the Master osc 24 MHZ as Timer2 clock source */                    8     __raw_writel(0x1, CLKSEL_TIMER2_CLK);                                        9                                                                                 10     /* UART0 */                                                                 11     __raw_writel(PRCM_MOD_EN, CM_WKUP_UART0_CLKCTRL);                           12     while (__raw_readl(CM_WKUP_UART0_CLKCTRL) != PRCM_MOD_EN);                  13                                                                                 14     /* change by chen 2016/9/30 */                                              15     __raw_writel(PRCM_MOD_EN, CM_PER_UART1_CLKCTRL);                            16     while (__raw_readl(CM_PER_UART1_CLKCTRL) != PRCM_MOD_EN);                   17                                                                                 18     /* UART3 */                                                                 19     __raw_writel(PRCM_MOD_EN, CM_PER_UART3_CLKCTRL);                            20     while (__raw_readl(CM_PER_UART3_CLKCTRL) != PRCM_MOD_EN);                   21                                                                                 22     /* GPMC */                                                                  23     __raw_writel(PRCM_MOD_EN, CM_PER_GPMC_CLKCTRL);                             24     while (__raw_readl(CM_PER_GPMC_CLKCTRL) != PRCM_MOD_EN);                    25     //.....26 }

 

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

添加这一条宏定义。

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

 

 

代码修改跟踪流程:

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

再进入pll_init () 函数。

 1 /*                                                                               2  * Configure the PLL/PRCM for necessary peripherals                              3  */                                                                              4 void pll_init()                                                                  5 {                                                                               //  mpu_pll_config(MPUPLL_M_500);                                                6     mpu_pll_config(MPUPLL_M_720);                                                7     core_pll_config();                                                           8     per_pll_config();                                                            9     ddr_pll_config();                                                           10     /* Enable the required interconnect clocks */                               11     interface_clocks_enable();                                                  12     /* Enable power domain transition */                                        13     power_domain_transition_enable();                                           14     /* Enable the required peripherals */                                       15     per_clocks_enable();                                                        16 }                                                                              

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

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

 1 /*                                                                               2  * Enable the module clock and the power domain for required peripherals         3  */                                                                              4 static void per_clocks_enable(void)                                              5 {                                                                                6     /* Enable the module clock */                                                7     __raw_writel(PRCM_MOD_EN, CM_PER_TIMER2_CLKCTRL);                            8     while (__raw_readl(CM_PER_TIMER2_CLKCTRL) != PRCM_MOD_EN);                   9                                                                                 10     /* Select the Master osc 24 MHZ as Timer2 clock source */                   11     __raw_writel(0x1, CLKSEL_TIMER2_CLK);                                       12                                                                                 13     /* UART0 */                                                                 14     __raw_writel(PRCM_MOD_EN, CM_WKUP_UART0_CLKCTRL);                           15     while (__raw_readl(CM_WKUP_UART0_CLKCTRL) != PRCM_MOD_EN);                  16                                                                                 17     /* change by chen 2016/9/30 */                                              18     __raw_writel(PRCM_MOD_EN, CM_PER_UART1_CLKCTRL);                            19     while (__raw_readl(CM_PER_UART1_CLKCTRL) != PRCM_MOD_EN);     20     // ..................................21 }

 

 



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

1 #define CONFIG_SYS_NS16550_COM2     0x48022000   /* UART1 sbc-7109 */2 3 #define CONFIG_SERIAL2          1                                               4 #define CONFIG_CONS_INDEX       2   

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

 

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

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

再进入board_init_f 函数。

 

 

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

 1 void board_init_f(ulong bootflag)                                                2 {                                                                                3     bd_t *bd;                                                                    4     init_fnc_t **init_fnc_ptr;                                                   5     gd_t *id;                                                                    6     ulong addr, addr_sp;                                                         7                                                                                  8                                                                                  9     /* Pointer is writable since we allocated a register for it */              10     gd = (gd_t *) ((CONFIG_SYS_INIT_SP_ADDR) & ~0x07);                          11     /* compiler optimization barrier needed for GCC >= 3.4 */                   12     __asm__ __volatile__("": : :"memory");                                      13                                                                                 14     memset((void *)gd, 0, sizeof(gd_t));                                        15                                                                                 16     gd->mon_len = _bss_end_ofs;                                                 17                                                                                 18     for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {         19         if ((*init_fnc_ptr)() != 0) {                                           20             hang ();                                                            21         }                                                                       22     }                                                                           23     //......24 }

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

这个数组有如下定义:

 1 init_fnc_t *init_sequence[] = {                                                  2 #if defined(CONFIG_ARCH_CPU_INIT)                                                3     arch_cpu_init,      /* basic arch cpu dependent setup */                     4 #endif                                                                           5 #if defined(CONFIG_BOARD_EARLY_INIT_F)                                           6     board_early_init_f,                                                          7 #endif                                                                           8     timer_init,     /* initialize timer */                                       9 #ifdef CONFIG_FSL_ESDHC                                                         10     get_clocks,                                                                 11 #endif                                                                          12     env_init,       /* initialize environment */                                13     init_baudrate,      /* initialze baudrate settings */                       14     serial_init,        /* serial communications setup */                       15     console_init_f,     /* stage 1 init of console */                           16     display_banner,     /* say that we are here */                              17 #if defined(CONFIG_DISPLAY_CPUINFO)                                             18     print_cpuinfo,      /* display cpu info (and speed) */                      19 #endif                                                                          20 #if defined(CONFIG_DISPLAY_BOARDINFO)                                           21     checkboard,     /* display board info */                                    22     //.......23 }

 


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

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

 1 #if !defined(CONFIG_SERIAL_MULTI)                                                2 int serial_init (void)                                                           3 {                                                                                4                                                                                  5     int clock_divisor;                                                           6                                                                                  7 #ifdef CONFIG_NS87308                                                            8     initialise_ns87308();                                                        9 #endif                                                                          10                                                                                 11 #ifdef CONFIG_SYS_NS16550_COM1                                                  12     clock_divisor = calc_divisor(serial_ports[0]);                              13     NS16550_init(serial_ports[0], clock_divisor);                               14 #endif                                                                          15 #ifdef CONFIG_SYS_NS16550_COM2                                                  16     clock_divisor = calc_divisor(serial_ports[1]);                              17     NS16550_init(serial_ports[1], clock_divisor);                               18 #endif                                                                          19 #ifdef CONFIG_SYS_NS16550_COM3                                                  20     clock_divisor = calc_divisor(serial_ports[2]);                              21     NS16550_init(serial_ports[2], clock_divisor);                               22 #endif                                        23 //......24 }                                  

 


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

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

 

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

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

 


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

 1 static int display_banner(void)                                                  2 {                                                                                3     printf("\n\n%s\n\n", version_string);                                        4     printf("chen goto it ....\n") ;                                              5     debug("U-Boot code: %08lX -> %08lX  BSS: -> %08lX\n",                        6            _TEXT_BASE,                                                           7            _bss_start_ofs + _TEXT_BASE, _bss_end_ofs + _TEXT_BASE);              8 #ifdef CONFIG_MODEM_SUPPORT                                                      9     debug("Modem Support enabled\n");                                           10 #endif                                                                          11 #ifdef CONFIG_USE_IRQ                                                           12     debug("IRQ Stack: %08lx\n", IRQ_STACK_START);                               13     debug("FIQ Stack: %08lx\n", FIQ_STACK_START);                               14 #endif                                                                          15                                                                                 16     return (0);                                                                 17 }                                                                               


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

 1 int printf(const char *fmt, ...)                                                 2 {                                                                                3     va_list args;                                                                4     uint i;                                                                      5     char printbuffer[CONFIG_SYS_PBSIZE];                                         6                                                                                  7     va_start(args, fmt);                                                         8                                                                                  9     /* For this to work, printbuffer must be larger than                        10      * anything we ever want to print.                                          11      */                                                                         12     i = vsprintf(printbuffer, fmt, args);                                       13     va_end(args);                                                               14                                                                                 15     /* Print the string */                                                      16     puts(printbuffer);                                                          17     return i;                                                                   18 }                                                                             

 

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

 1 void puts(const char *s)                                                         2 {                                                                                3 #ifdef CONFIG_SILENT_CONSOLE                                                     4     if (gd->flags & GD_FLG_SILENT)                                               5         return;                                                                  6 #endif                                                                           7                                                                                  8 #ifdef CONFIG_DISABLE_CONSOLE                                                    9     if (gd->flags & GD_FLG_DISABLE_CONSOLE)                                     10         return;                                                                 11 #endif                                                                          12                                                                                 13     if (gd->flags & GD_FLG_DEVINIT) {                                           14         /* Send to the standard output */                                       15         fputs(stdout, s);                                                       16     } else {                                                                    17         /* Send directly to the handler */                                      18         serial_puts(s);                                                         19     }                                                                           20 }                                                                              

 


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

1 void                                                                            2 serial_puts(const char *s)                                                      3 {                                                                               4     _serial_puts(s,CONFIG_CONS_INDEX);                                          5 }                                                                              


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

1 #define CONFIG_CONS_INDEX       2        

 

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

 

 

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

 

 1 #ifdef CONFIG_ANDROID                                                            2 #define CON     \                                                                3     "console=ttyO0,115200n8 earlyprintk androidboot.console=ttyO0\0" \           4     "optargs=init=/init\0" \                                                     5     "mmcroot=/dev/mmcblk0p2 rw\0" \                                              6     "mmcrootfstype=ext4 rootwait\0" \                                            7     "nandroot=ubi0:rootfs rw ubi.mtd=7,2048\0" \                                 8     "nandrootfstype=ubifs rootwait=1\0"                                          9 #else                                                                           10 #define CON     \                                                               11     "console=ttyO1,115200n8\0" \                                                12     "optargs=\0" \                                                              13     "mmcroot=/dev/mmcblk0p2 ro\0" \                                             14     "mmcrootfstype=ext3 rootwait\0" \                                           15     "nandroot=ubi0:rootfs rw ubi.mtd=7,2048\0" \                                16     "nandrootfstype=ubifs rootwait=1\0"                                         17 #endif                                                                          

 


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

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

 45 #0:2345:respawn:/sbin/getty 115200 ttyO0 46 1:2345:respawn:/sbin/getty 115200 ttyO1

 

am335x UART1输入u-boot 调试信息代码修改