PMON initmips()源码分析
假initmips()源码分析
PMON的启动代码start.S执行完成之后,跳转到了zloader/initmips.c中的initmips()函数继续执行。
zloader/initmips.c并不是手工编写的源代码文件,而是由一个叫做genrom的perl脚本生成的。
这个脚本的主要任务是打开目标代码文件pmon,在其中搜索以下几个符号的地址:
_edata: 数据段的结尾地址,也是bss开始地址_end_:bss段的结尾地址initmips: 真正的initmips()函数的入口地址,这个函数是在Targets/LS2K/ls2k/tgt_machdep.c中定义的。_start_: 入口地址,但是因为start.o已经执行过一遍了,所以得到这个地址并不是为了再次执行start.o,而是 为了确定要将biosdata[]解压到何处,以及确定堆栈的起始地址,因为stack=_start - 0x4000。
现在分析initmips()的执行流程:
- 打印
Uncompressing Bios; run_unzip(biosdata, _start): 解压缩biosdata[]到地址_start;- 打印”OK, Booting Bios”;
bss清零,也就是从_edata到_end这一段内存;_start-0x1000到_start这一段内存清零;- 跳到
realinitmips()执行; - 在
realinitmips()中,设置堆栈起点为_start - 0x4000, 跳转到真正的initmips()执行。
真initmips()源码分析
真正的initmips()函数是在Targets/LS2K/ls2k/tgt_machdep.c中定义的。
现在分析真正的initmips()的执行流程:
- 启动CPU1?Undocumented Loongson!
- 设置
sata gpio??? - 使能FPU;
- 清TLB;
- 设置内存边界;
- 探测CPU工作频率,打印
cpu freq %u\n; CPU_ConfigCache(): 在pmon/arch/mips/cache.S中定义;- spi, nand, gpio, pwm 相关设置;
- main()