完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
请问:
1. uboot在第一阶段就已经进行时钟初始化了,为什么第二阶段还要进行,两者之间有什么区别? 2. 在start_ARMboot中为什么init_fnc_t **init_fnc_ptr, init_fnc_t *init_fnc_ptr不能满足吗? 3. uboot在哪设置直接启动Linux,而非等待串口命令输入,即设置为用户级uboot? |
|
相关推荐
1个回答
|
|
===============================================================================================
1. uboot在第一阶段就已经进行时钟初始化了,为什么第二阶段还要进行,两者之间有什么区别? 我只看到第一阶段的clock_init()代码,第二阶段的时钟初始化代码在哪儿? =============================================================================================== 2. 在start_armboot中为什么init_fnc_t **init_fnc_ptr, init_fnc_t *init_fnc_ptr不能满足吗? 先把相关的代码贴下来: typedef int (init_fnc_t) (void); //定义init_fnc_t是一个函数,该函数具有void参数和int返回值 init_fnc_t **init_fnc_ptr; //init_fnc_ptr是“指针的指针”。剥离一次:*init_fnc_ptr是init_fnc_t *型的函数指针 //换句话说,init_fnc_ptr代表的地址里面,存放的是init_fnc_t *型的函数指针 //init_sequence[]是一个数组,数组内的每一个元素具有init_fnc_t *类型,即:init_sequence[]数组 //的每一个元素都是指向init_fnc_t型函数的函数指针。c语言中用函数名代表函数首地址。 init_fnc_t *init_sequence[] = { cpu_init, /* 初始化IRQ/FIQ的栈 */ board_init, /* 初始化GPIO,设置机器ID和taglist在内存中的起始地址(这两个是传给内核入口点的参数) */ interrupt_init, /* 初始化并启动 Timer 4 */ env_init, /* 检查Flash上环境参数的有效性(CRC校验) */ init_baudrate, /* 设置波特率 */ serial_init, /* serial communications setup */ console_init_f, /* stage 1 init of console */ display_banner, /* say that we are here */ ...... dram_init, /* 向bd_t结构体中填充SDRAM的起始地址和长度字段 */ display_dram_config,/* 打印SDRAM的起始地址和长度信息 */ NULL, }; //init_fnc_ptr = init_sequence 之后,init_fnc_ptr指向cpu_init, //init_fnc_ptr自增之后,指向下一个init_fnc_t *元素,也就是board_init,依此类推。 for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { if ((*init_fnc_ptr)() != 0) { hang (); } } 假设按照楼主说的,init_fnc_t *init_fnc_ptr, 那么init_fnc_ptr就是函数指针,你可以 init_fnc_t *init_fnc_ptr; init_fnc_ptr = cpu_init; //现在init_fnc_ptr指向cpu_init()函数的首地址 接下来那你想怎么办?假设楼主想这样: init_fnc_ptr++; 那么,init_fnc_ptr会指向 [ cpu_init()函数的首地址的下一个地址 ],并强制性地将这个地址转化为init_fnc_t *型的函数指针。在代码中: int cpu_init (void) { /* * setup up stacks if necessary */ #ifdef CONFIG_USE_IRQ /* CONFIG_USE_IRQ有定义 */ IRQ_STACK_START = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4; FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ; FREE_RAM_END = FIQ_STACK_START - CONFIG_STACKSIZE_FIQ - CONFIG_STACKSIZE; FREE_RAM_SIZE = FREE_RAM_END - PHYS_SDRAM_1; #else FREE_RAM_END = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4 - CONFIG_STACKSIZE; FREE_RAM_SIZE = FREE_RAM_END - PHYS_SDRAM_1; #endif return 0; } 也就相当于把标红语句的地址强制转换成一个函数指针,于是就会发生错误! 综上所述,如果你想按照cpu_init(),board_init(),......这样的顺序来调用函数,最好的 办法就是把他们放到一个函数指针数组内。到这里,也应该明白为啥要将init_fnc_ptr定义为 init_fnc_t **类型了。 =============================================================================================== 3. uboot在哪设置直接启动Linux,而非等待串口命令输入,即设置为用户级uboot? common/main.c中有以下代码: #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) s = getenv ("bootdelay"); bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY; debug ("### main_loop entered: bootdelay=%dnn", bootdelay); 这段代码是说,先从NAND里面的环境变量读取看看bootdelay参数有没有设置,如果设置了就用它, 如果没设置,就用CONFIG_BOOTDELAY。在uboot代码中查找这个CONFIG_BOOTDELAY。发现 include/configs/100ask24x0.h里面有这样的宏定义: #define CONFIG_BOOTDELAY 2 如果仍然怀疑,可以重启开发板,看看倒数计时是不是2秒。 如果不想等待,可以直接 #define CONFIG_BOOTDELAY 0 试试看。 =============================================================================================== 以上。 =============================================================================================== |
|
|
|
只有小组成员才能发言,加入小组>>
197个成员聚集在这个小组
加入小组为什么点亮LED的例子放在NORFlash上跑会出现奇怪的现象?
2199 浏览 6 评论
1997 浏览 5 评论
韦东山老师推出的《玩转ARM裸机实战》课程将帮你以上问题一扫而光!
4554 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-4 18:32 , Processed in 0.644224 second(s), Total 78, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (威廉希尔官方网站 图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号