如何实现BOOTLOADER
扫描二维码
随时随地手机看文章
1.之所以要实现一个专用的bootloader,一是为了更好的移植和自身的升级,二是为了方便操作系统的调试,当然,你完全可以将这部分所要实现的与操作系统相关的功能集成到操作系统中去
2.确定一个简单的bootloader所要完成的功能:我们这里只需要完成两个主要功能,一是将操作系统加载到内存中去运行,二是将自己和操作系统内核固化到rom存储区(这里的rom可以是很多设备,比如嵌入式芯片中的flash,pc机上的软盘,u盘,硬盘等) 3.bootloader的编写:
第一步:要进行相关硬件的初使化,比如在at91rm9200这块嵌入式板子上(以后都使用这一款芯片,主要是我对这款芯片比较熟悉,嘿嘿),大概要做接下来的几方面的工作,其一:将cpu模式切换进系统模式,关闭系统中断,关闭看门狗,根据具体情况进行内存区域映射,初始化内存控制区,包括所使用的内存条的相关参数,刷新频率等,其二:设定系统运行频率,包括使用外部晶振,设置
cpu频率,设置总线频率,设置外部设备所采用的频率等。其三:设置系统中断相关,包括定时器中断,是否使用fiq中断,外部中断等,还有就是中断优先级设置,这里只实现两个优先级,只有时钟中断高一级,其它都一样,而中断向量初始化时都将这些中断向量指向0x18处,并关闭这里的所有中断,如果板子还接有诸如flash设备的话,还需要设置诸如flash相关操制寄存器,其四:需要关闭cache,到此为止,芯片相关内容就完成初始化了 第二步:中断向量表,arm的中断与pc机芯片的中断向量表有一点差异,嵌入式设备为了简单,当发生中断时,由cpu直接跳入由0x0开始的一部分区域(arm芯片自身决定了它中断时就会跳入0x0开始的一片区域内,具体跳到哪个地址是由中断的模式决定的,一般用到的就是复位中断,fiq,irq中断,swi中断,指令异常中断,数据异常中断,预取指令异常中断),而当cpu进入相应的由0x0开始的向量表中时,这就需要用户自己编程接管中断处理程序了,这就是需要用户自己编写中断向量表,中断向量表里存放的就是一些跳转指令,比如当cpu发生一个irq中断时,就会自动跳入到0x18处,这里就是用户自己编写的一个跳转指令,假如用户在此编写了一条跳转到0x20010000处的指令,那么这个地址就是一个总的irq中断处理入口,一个cpu可能有多个irq中断,在这个总的入口处如何区分不同的中断呢?就由用户编程来决定了,具体实现请参见以后相关部分,中断向量表的一般用一个vector.s文件,当然,如何命名那是你自己的喜爱,但有一点需要声明,那就是在链接时一定要将它定位在0x0处 第三步:设置堆栈,一般使用三个栈,一个是irq栈,一个是系统模式下的栈(系统模式下和用户模式共享寄存器和内存空间,这主要是为了简单),设置栈的目的主要是为了进行函数调用和局部变量的存放,不可能全用汇编,也不可能不用局部变量 第四步:将自己以后的代码段和数据段全部拷贝至内存,并将bss段清零 第五步:进行串口的初始化(主要是为了与用户交互,进行与pc机的文件传输),flash的初始化这里在flash中存放boot和内核),flash驱动的编写(这里的驱动有别于平常所说的驱动,由于flash不像sdram,只要设定了相关控制器之后就可以直接读写指定地址的数据,对flash的写操作是一块一块数据进行,而不是一个字节一个字节地写,具体请查阅相关资料)
第六步:等待一定的秒数,来接收用户进行输入,如果在指定的秒数内用户未输入任何字符,那么boot就开始在flash中的指定位置(可以由自己指定,这么做主要是为了简单)读取内核的所有数据到内存中(具体是内存中的什么位置由自己指定,也可以采用linux之类的做法,就是在内存的起始位置加上一个0x8000处),将跳转到内核的第一条代码处);如果用户在指定的秒数内键入了字符(这主要是为了方便开发,如果开发定型之后完全可以不要这段代码),那么就在串口与用户进行交互,接受用户在串口输入的命令,比如用户要求下载文件在flash中指定的位置等,具体内容可参考u-boot之类的开源项目到这里为止,boot部分已完成,这个boot非常简单,仅仅只是将pc机上传下来的文件固化到flash中,然后再将flash中的操作系统内核部分加载进内存中,并将cpu的控制权交给操作系统,下一页开始讲解如何写一个最简单的操作系统,呵,到现在才开始切入正题呢!!!!