• 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("
    
    %s
    
    ", version_string);                                       
     4     printf("chen goto it ....
    ") ;                                             
     5     debug("U-Boot code: %08lX -> %08lX  BSS: -> %08lX
    ",                       
     6            _TEXT_BASE,                                                          
     7            _bss_start_ofs + _TEXT_BASE, _bss_end_ofs + _TEXT_BASE);             
     8 #ifdef CONFIG_MODEM_SUPPORT                                                     
     9     debug("Modem Support enabled
    ");                                           
    10 #endif                                                                          
    11 #ifdef CONFIG_USE_IRQ                                                           
    12     debug("IRQ Stack: %08lx
    ", IRQ_STACK_START);                               
    13     debug("FIQ Stack: %08lx
    ", 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"           
     4     "optargs=init=/init"                                                     
     5     "mmcroot=/dev/mmcblk0p2 rw"                                              
     6     "mmcrootfstype=ext4 rootwait"                                            
     7     "nandroot=ubi0:rootfs rw ubi.mtd=7,2048"                                 
     8     "nandrootfstype=ubifs rootwait=1"                                         
     9 #else                                                                           
    10 #define CON                                                                    
    11     "console=ttyO1,115200n8"                                                 
    12     "optargs="                                                               
    13     "mmcroot=/dev/mmcblk0p2 ro"                                              
    14     "mmcrootfstype=ext3 rootwait"                                            
    15     "nandroot=ubi0:rootfs rw ubi.mtd=7,2048"                                 
    16     "nandrootfstype=ubifs rootwait=1"                                         
    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
  • 相关阅读:
    写在毕业季前
    使用Github Page鼓励自己每日编程
    win8/Metro开发系列一 Xaml布局
    AlertDialog详解
    安卓项目文件目录
    Andriod布局之LinearLayout
    Andriod定时任务
    android 设置布局横屏竖屏
    Android默认启动程序问题
    Android全屏显示
  • 原文地址:https://www.cnblogs.com/chenfulin5/p/5924413.html
Copyright © 2020-2023  润新知