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",
},
};