分类: 嵌入式
2014-10-30 14:12:53
系统刚上电时,CPU从0xbfc0.0000开始执行。这个地址在Rom空间中,在完成TLB,Cache,UART等初始化后,CPU就将代码拷到0x8010.0000开始的RAM空间(这个地址是编译Pmon时分配符号_start的),然后跳转到initmips(),开始在内存空间的执行。
执行initmips之前,CPU做的初始化只是初步的,其作用只是为CPU在内存中运行做一些必要的准备。主要的初始化工作:PCI设备的扫描、空间映射、资源分配都是initmips()函数所完成的。
首先是获取CPU的时钟频率,这是tgt_cpufreq()完成的。它定义在tgt_machdep.c中。主要的方法就是先读取COP0中的count寄存器,然后延时一段时间,再读取count寄存器。两次的差值乘以2就是这段时间内cpu的时钟周期数。另外,CMOS中有个实时钟,在延时前后读取当前时间该相减,就可以知道延时的准确时间。从而计算出cpu的时钟频率。全局变量md_cpufreq记录了cpu频率值,md_pipefreq是流水线的频率,它们的值分别是500MHZ和1000MHZ;
接着调用的是dbginit(),这是最要的一个函数,几乎所有的初始化代码都由他直接或间接调用。
**** 构造函数(constructor)的执行 ****
Dbginit()调用的第一个函数是__init()。这个函数的过程很简单,它就是将所有的constructor的函数执行一遍,建立一些基本的数据结构。在pmon中有三类constructor函数,它们都是静态函数。
1) 命令处理初始化函数,位于pmon/cmds目录下,其名称都叫init_cmd()。
2) 文件系统初始化函数。pmon/fs目录下。函数名称叫init_fs()或者init_xxxfs()。
3) 可执行文件类型初始化。在pmon/loader目录下。函数名称叫init_exec()
文件系统初始化就是代表各个文件系统的数据结构插入到相应链表。对于磁盘文件系统,链表的头指针式DiskFileSystems。对于其他的文件系统,头指针是FileSystems。这样当需要对某个文件操作(包括虚拟文件,如与用户交互的终端termio)。通过这两个链表可以找到相应的结构,在通过里面的函数指针就可以对文件进行具体操作了。