===============================================================================================
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 试试看。
===============================================================================================
以上。
===============================================================================================
===============================================================================================
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 试试看。
===============================================================================================
以上。
===============================================================================================
举报