zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    vmware ubuntu 异常关机无法连接到网络
    Speed up GCC link
    常用的一些解压命令
    Log4j 漏洞复现
    Test Case Design method Boundary value analysis and Equivalence partitioning
    CCA (Citrix Certified Administrator) exam of “Implementing Citrix XenDesktop 4”
    What is Key Word driven Testing?
    SAP AGS面试小结
    腾讯2013终端实习生一面
    指针的引用
  • 原文地址:https://www.cnblogs.com/chenfulin5/p/5924413.html
Copyright © 2011-2022 走看看