uboot原理
uboot虽然乱七八糟很多文件,其实本身不复杂,可以看做一个elf/bin loader ,只是这个loader专门用来加载kernel。包括所有boot都是这个目的。
这个工具的核心是ram地址、run地址、loader地址等乱七八糟的地址。在kernel link阶段的ldscript(或ld命令行)中指定入口地址、ram地址等,然后顺着这个地址链接。这里可以忽略mmu变换之后的地址,而只关注实地址。
uboot可以认为是在一堆二级存储中寻找kernel镜像,然后把镜像读进内存(当然,地址需要和上面说的地址吻合),之后做必要的环境打理,比如关掉mmu之类,最后跳到ram中的kernel去。抛开所有的繁华,如果自己做个类似boot的工具,最简单的就是控制nand,从固定的nand sector读到sram(可能首先需要定制sram初始化)的某个地址,关掉mmu,然后jmp过去,完了。
关于移植
那么uboot毕竟是个比较全面的loader,它比较上面说的自己做的boot,kernel镜像可以来自“一堆二级存储”,包括磁盘、sd、nandflash、网络等物理设备,自然也包括这些存储设备中基本的文件系统如ext2,3,如果牵扯网络文件系统,还会涉及到tcp网络协议栈。简单浏览会发现driver中的东西就这些。文件系统和网络是现成的几乎不需要动手,sd、nandflash、netinterface等设备都和linux内核里差不多,每个具体的设备太具体也不不好展开了,基本代码可以在kernel code里找。
我个人认为uboot里90%的代码是辅助代码,都是为了“读到kernel这个文件”,甚至自己还有mmu管理,搞虚拟内存,我个人认为没多少用也多少没必要,反而搞越搞越复杂,不如多加一个调度器直接叫ukernel好了,何必委屈自己只做一个boot?剩下9%是命令行便于测试调试验证等等,剩下只有1%是核心,而这1%的核心,剥开之后也只剩下“地址”这一个概念了。