AM1808开发记录(四)

SDK开发包默认是UART2作为启动调试口,修改UBOOT参数,编译下载内核无法启动
1.修改(board-da850-evm.c)函数static __init void da850_evm_init(void)--->这个比较明显
ret = davinci_cfg_reg_list(da850_uart2_pins);  //modify by zss********************************/
下载后从UART3可以输出启动信息
2.修改几个明显的地方
---->ret = davinci_cfg_reg_list(da850_uart0_pins); //modify by zss********************************/
---->static int __init da850_evm_console_init(void)
{
 if (!machine_is_davinci_da850_evm())
  return 0;

 return add_preferred_console("ttyS", 0, "115200"); //modify by zss*****************/
}

----> __raw_writel(0x00006001, IO_ADDRESS(DA8XX_UART0_BASE) + 0x30); //modify by zss*****************/
这个挺明显,查询手册就能得到相应值,照猫画虎改好即可

tftp下载还是没有启动信息,下面利用网上看的一个调试方法来追踪,那就是UBOOT的MD指令
通常linux编译的虚拟地址和物理地址有一个偏移,在这里这个偏移是0,也就是虚拟地址和物理地址相等,因为物理DDR地址

从0xc0000000开始,前面安排的是UBOOT,和内核的0xc0008000正好相等。
MD指令不仅可以看内存,配置的寄存器也是可以查看的,但是复位后UBOOT重新执行,这个时候寄存器的值并不一定是linux时

的值了,但是部分内存是可以的。
利用MD指令,配合内核的map文件,查找__log_buf的地址,通过在内部增加打印语句来进行追踪,通过追踪发现默认使用的是

MII接口,占用的UART0的pin,在UART0管脚配置后又进行了MII管脚配置,修改了UART0的配置
static int __init da850_evm_config_emac(void)
{
.........
if (1) {     //modify by zss******************************/
  val |= BIT(8);
  ret = davinci_cfg_reg_list(da850_evm_rmii_pins);
  pr_info("EMAC: RMII PHY configured, MII PHY will not be"
       " functional\n");

我使用的是RMII接口,这里就不费事,直接if(1)就ok了

重新编译下载后发现输出了启动信息,这也证实了我之前的猜测:)
(上面的方法有一个小的前提,我飞了一个LED到Uart0的发送pin,这样只要有数发送LED就会闪烁,这样可以排除由于时钟问

题或者波特率问题导致的没有启动提示)

这里总结一下上电没有启动信息的可能性和解决方法
1.死在Starting kernel ...  这个时候Uboot已经交接了,但是解压没有输出信息。查找解压部分代码的串口发送是否正确
2.死在Uncompressing Linux... done, booting the kernel.--->这种情况比较复杂,
 常见的是机器码,JTAG ID码设置不对(这些只能在汇编代码部分使用打印来追踪)
 Uboot传递的启动参数不对,console=ttyS0,115200n8
 管脚的设置是否正确,是否有电源管理之类的控制关闭了Uart部分

 

////////////////////////////////////////////////下面内容是汇编调试时追踪的启动过程/////////////////////////////////////////

arch\arm\mach-davinci\include\mach\uncompress.h
分析得知Starting kernel ...是uboot最后的遗言,正常下面应该Uncompressing Linux...可是没有输出,那么

sourceinsight搜索“Uncompressing Linux...”找到misc.c的decompress_kernel--->putstr("Uncompressing Linux...");
继续查找putstr--->putc()--->arch\arm\mach-davinci\include\mach\uncompress.h--->DEBUG_LL_DA8XX

(davinci_da850_evm, 2);修改为DEBUG_LL_DA8XX(davinci_da850_evm, 0);

include\generated\mach-types.h中包含了处理器ID码,赋值代码在\arch\arm\mach-davinci\board-da850-evm.c中
MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138/AM18x EVM")-----这个宏把一些参数安排到指定的位置,内

核直接从这个位置取地址,按照自己的结构体操作。

arch\arm\boot\文件夹下的代码和linux内核的“外封装”相关,uboot启动最后打印“Starting kernel ...”以后就进入了

“外封装”的head.s了,解压后打印信息,然后进入内核的head.s
arch\arm\kernel\文件夹下都与linux内核早期启动代码相关,head.s,head-common.s共同组合了内核最早启动部分,主要内

容有检查CPU和board的ID码是否正确,然后建立页表启动MMU,然后进行别的初始化函数

kernel的head.s后面的执行顺序:ldr r13, =__mmap_switched---->add pc, r10, #PROCINFO_INITFUNC(---

__arm926_setup)---->b __enable_mmu---->b __turn_mmu_on---->mov r3, r13;mov pc, r3(执行

__mmap_switched函数)---->b start_kernel(进入C语言执行函数\init.c\main.c)

/*********************************/
1.没有设置bootargs参数也可以启动以前的内核,是否说明不是这里的参数起作用?但是同一个uboot可以启动老内核,而自

己编译的新内核却不可以


/*****************************************/
1./arch/arm/mm/proc-arm926.s的__arm926_proc_info:对应于/arch/arm/include/asm/procinfo.h的struct proc_info_list

结构体,至于如何挂钩的我还没明白
/**********************************************************/
调试追踪:main.c(setup_arch(&command_line);)---->setup.c(paging_init(mdesc);)---->mmu.c(devicemaps_init

(mdesc);)---->mmu.c(mdesc->map_io();)---->\arch\arm\mach-davinci\board-da850-evm.c(.map_io  =

da850_evm_map_io,)---->\arch\arm\mach-davinci\da850.c(void __init da850_init(void))
//////////////////////////
common.c函数 ----------->ID 号不对有可能影响程序的继续执行导致没有输出打印
static int __init davinci_init_id(struct davinci_soc_info *soc_info)

/*for (i = 0, dip = soc_info->ids; i < soc_info->ids_num;
   i++, dip++)
  // Don't care about the manufacturer right now
  if ((dip->part_no == part_no) && (dip->variant == variant)) {
   soc_info->cpu_id = dip->cpu_id;
   pr_info("DaVinci %s variant 0x%x\n", dip->name,
     dip->variant);
   return 0;
  }*/

检查JTAG ID,用这个版本号做些初始化选择,通过UBOOT的MD指令读出ID号,添加到da850.c
/* Contents of JTAG ID register used to identify exact cpu type */
static struct davinci_id da850_ids[] = {
 {
  .variant = 0x0,
  .part_no = 0xb7d1,
  .manufacturer = 0x017, /* 0x02f >> 1 */
  .cpu_id  = DAVINCI_CPU_ID_DA850,
  .name  = "da850/omap-l138",
 },
 {
  .variant = 0x1,
  .part_no = 0xb7d1,
  .manufacturer = 0x017, /* 0x02f >> 1 */
  .cpu_id  = DAVINCI_CPU_ID_DA850,
  .name  = "da850/omap-l138/am18x",
 },
};


 

你可能感兴趣的:(AM1808开发记录(四))