自己编写bootloader(三):代码重定位(一)-----完成NorFlash准备工作

    这节课,我们就开始实现代码重定位部分的内容。再此之前,我们要讨论一下重定位的情形:对于NorFlash启动,我们需要将NorFlash上的所有代码都复制到SDRAM里面去,在重定位之前,使用的必须是位置无关码;对于NandFlash启动,我们需要将NandFlash上的所有代码都复制到SDRAM里面去,在重定位之前,使用的必须是位置无关码。然而,对于NorFlash的访问和NandFlash的访问,都是不同的操作,我们首先需要判断,程序是从NandFlash启动,还是从NorFlash启动的。如果是从NorFlash启动的话,代码可以直接再NorFlash上进行运行,但无法像普通的RAM那样进行写入操作;如果是从NandFlash启动的话,其前面的4K内存都会被复制到片内SRAM中去,此时可以写入操作就是RAM的写入操作。因此,我们只需在零地址里写入某个数值,然后再把它读出来,看看有没有写成功,如果写成功的话,说明程序就是从NandFlash里启动的,反之则是从NorFlash中启动的。

    既然要实现能从NandFlash和NorFlash中进行读取的话,就必须先实现相关的接口。对于NorFlash,不需要初始化,但在读写之前,需要进行一些操作来解锁;对于NandFlash,我们实际是操纵NandFlash控制器的寄存器,它帮我们简化了操作,但在由于不同的NandFlash会有不同的时序,所以我们再使用前要初始化好NandFlash控制器的寄存器,设置好时序。

    那我们首先来编写NorFlash相关接口的编写。首先,我们得先翻阅其原理图:


    我们看到,这款开发板的NorFlash型号是:MX29LV160DBTI,这里我们打开和它同样的一款的NorFlash芯片手册(型号稍老,但讲得比较详细):

我们看到,对于普通的读操作,我们可以像内存一样,发出地址,然后收到数据。但对于写操作(也就是program那里),要先先发出一些命令后,才可以进行解锁写操作,且在烧写之前,要先对NorFlash进行擦除,这又是另一个操作了。

     下面我们来编写代码,首先最简单的是都操作,我们只需要发出地址就可以读到数据了。然而,我们这个地址,必须是在NorFlash上的地址。对于如果程序是从NorFlash启动的话,则NorFlash的基地址就是0;如果程序是从NandFlash启动的话,则NorFlash的基地址就是0x08000000,所以我们要先这里要进行一下宏定义:

#ifdef BOOT_FROM_NOR
#define NOR_BASE_ADDR 0
#else
#define NOR_BASE_ADDR 0x08000000
#endif

    这样,我们就可以接受一个相对地址,从中读取相应的数据了。然而,这个相对地址还不能真正对应的NorFlash上的地址,我们来看NorFlash的结构图:


我们看到,地址线0并没有连接在NorFlash上,地址线1是连到NorFlash上的第一个地址线接口。因此,对于我们传入的偏移值,要先把偏移左移一位,才能对应NorFlash上的真正地址。现在,我们就可以编写读取NorFlash的函数了:

//读取NorFlash地址上的值
unsigned int nor_read(unsigned    int offset)
{
	//读取一个字的长度
	unsigned short *p=(volatile short*)(NOR_BASE_ADDR+(offset<<1))
	return *p;
}

读操作我们做完了,我们本该继续做烧写操作的,但我们做bootloader的根本目的就是读出内核运行,因此这里用到读操作就好了。

猜你喜欢

转载自blog.csdn.net/xiaokangdream/article/details/79675040