DSP的boot一般没有特别的名字,就叫做boot或者bootloader;Linux的boot就不一样,有专门的名字叫做u-boot。其实,从名字开始说我是有目的的,这类似于中国古时候,最开始是妇女没有名字,然后是不读书的人只能有名而没有字;因此,有没有名字需要归结在“社会地位”高不高的因素中。从这个方面来看,DSP的boot就地位不高,属于贫贱阶级,Linux的boot(以下简称u-boot)地位很高,属于富贵阶级。
boot的目的就是引导,从boot的目的就注定了boot会牺牲自我,造福他人。boot的目的就是为了让正常的程序跑起来。dsp boot是这样,u-boot也是这样。因此大家都一样,只是服务对象不同。dsp boot通常就是讲dsp的代码拷贝到常用RAM,然后跳转指针到入口程序开始执行。u-boot的主要功能也是如此。两者的主要差别就是相应的服务对象不同。
DSP boot需要引导的DSP代码通常是很少很少的。就算是复杂的、有OS的DSP,其OS代码量也是极其简单的(相对linux而言);因此,DSP的boot负担较少,这是一个方面。另外一个方面,DSP开发时,往往需要先确定开发方案,比如画好PCB图,确定好I/O设备等等。因此DSP的开发者会有的放矢。需要用的外设就开发,不需要的外设就压根不理。但是这样对于boot就有很强的限制,无法针对所有DSP写一个boot。比如你写了flash boot,现在这个DSP板子上没有flash,你怎么办?因此,DSP的鼻祖们就用了返璞归真的方式,针对不同的DSP使用不同的boot方式,每一种boot方式都是极其简单的,这样也简化的boot的开发工作。比如DSP有I2C接口的,那么都可以使用I2C boot,有EMIF接口的DPS,可以使用EMIF boot。啥都没有的DSP,可以直接指定复位后从某个地址直接运行,无视boot。
u-boot就不同,它支持的是“高帅富”的Linux,注定了他服务在高级社群。也就是说u-boot会提供全面的面面俱到的服务。这样的话简单已经是不可能的了,全面就意味着复杂。也就是之所有u-boot相对这么复杂,它都是自找的。运行后你就发现,那么大一块代码,你用到的其实就那么点。这也是让DSP的开发人员的我感到太奢侈,太浪费的一个主要原因。由于u-boot提供了对“高帅富”——Linux的全面支持,它支持boot不同架构,单板,外设等等的Linux,而且也要用户方面的新加入各种特性,久而久之他就越来越臃肿,就像滚雪球一样。
DSP boot的过程比较简单,可以分为4个部分,第一部分为复位,DSP上电复位后从某个固定地址启动,这段代码就是boot代码。第二部分是boot设备的初始化需求,比如你用I2c,SPI等接口,你都需要初始化接口,设置默认的变量;第三部分是代码的拷贝,boot会从某个地址拷贝代码,往往这个地址是事先确定好的,长度也在其中;最后一部分是控制权交换,拷贝完代码后,boot工作完成,就直接将pc指针跳至指定入口地址,该地址也是在拷贝代码的时候就能获得。
u-boot的实现过程就比较复杂,第一部分为复位,也会从某个固定地址启动,执行u-boot代码;第二部分是代码的重定位,因为u-boot的代码比较长,而且复位后的内存效率往往很低(比如在外部的Flash中),因此u-boot会将自己拷贝到内部的RAM总执行,也就是自己拷贝自己;第三部分是设备初始化,这个初始化是用户需要关注的,哪些需要初始化,哪些不需要,一般来说,DDR内存控制器,UART串口,I2C等外设都需要在这里初始化;第四部分是人工交互界面的设置,因为u-boot可以人机交互,因此有一堆的代码需要配置;第五步就是循环的执行用户输入的命令,只要用户输入 go或者bootm等命令启动引导Kernel为止;
总结
DSP boot和Linux boot的差别还是比较大的,最主要的还是两者实现的功能不同。对于DSP的开发人员,需要转变观念,从纯到多,从精到杂。接下来会写几篇专门基于uboot的帖子。