// 判断状态 //
nand_wait_ready();
// 读数据 //
for(; (col<2048) && (i
{
buf[i] = nand_data();
i++;
addr++;
}
col = 0;
}
// 取消片选 //
del_select();
}
//
为什么该函数能够判断成功,因为程序运行到此时如果是nand启动,则上电后nand flash的前4K会被复制到片内SARM中运行,往地址0写入数据相当于往片内内存0地址写数据可以成功;但是如果是nor启动,上电后直接在nor的0地址运行,程序依然在nor flash中,nor flash可以像内存一样读,但是无法像内存一样写,故直接向0地址赋值会失败。
//
int isBootFromNorFlash(void)
{
volatile int *p =(volatile int *)0;
int val=0;
val = *p;
*p = 0x1234ab;
if(*p == 0x1234ab)
{
//写成功,表示是nand flash启动
*p=val;
return 0;
}
else
{
//写失败,说明是nor flash启动
return 1;
}
}
void copy_code_to_sdram(unsigned char *src, unsigned char *dest, unsigned int len)
{
unsigned int i=0;
if(isBootFromNorFlash())//nor启动
{
while(i
{
dest[i] = src[i];
i++;
}
}
else //nand启动
{
nand_read(src,dest,len);
}
}
void clear_bss(void)
{
extern int __bss_start, __bss_end;
int *p = &__bss_start;
for(; p < &__bss_end; p++)
*p = 0;
}
#define PCLK 50000000 // init.c中的clock_init函数设置PCLK为50MHz
#define UART_CLK PCLK // UART0的时钟源设为PCLK
#define UART_BAUD_RATE 115200 // 波特率
#define UART_BRD ((UART_CLK / (UART_BAUD_RATE * 16)) - 1)
//
* 初始化UART0
* 115200,8N1,无流控
//
void uart0_init(void)
{
GPHCON |= 0xa0; // GPH2,GPH3用作TXD0,RXD0
GPHUP = 0x0c; // GPH2,GPH3内部上拉
ULCON0 = 0x03; // 8N1(8个数据位,无较验,1个停止位)
UCON0 = 0x05; // 查询方式,UART时钟源为PCLK
UFCON0 = 0x00; // 不使用FIFO
UMCON0 = 0x00; // 不使用流控
UBRdiv0 = UART_BRD; // 波特率为115200
}
//
* 发送一个字符
//
void putc(unsigned char c)
{
// 等待,直到发送缓冲区中的数据已经全部发送出去 //
while (!(UTRSTAT0 & TXD0READY));
// 向UTXH0寄存器中写入数据,UART即自动将它发送出去 //
UTXH0 = c;
}
void puts(char *str)
{
int i = 0;
while (str[i])
{
putc(str[i]);
i++;
}
}
void puthex(unsigned int val)
{
// 0x1234abcd //
int i;
int j;
puts("0x");
for (i = 0; i < 8; i++)
{
j = (val >> ((7-i)*4)) & 0xf;
if ((j >= 0) && (j <= 9))
putc(0 + j);
else
putc(A + j - 0xa);
}
}
=================================================================
boot.c
#include "setup.h"
extern void uart0_init(void);
extern void nand_read(unsigned int addr, unsigned char *buf, unsigned int len);
extern void puts(char *str);
extern void puthex(unsigned int val);
static struct tag *params;
void setup_start_tag(void)
{
params = (struct tag *)0x30000100;
params->hdr.tag = ATAG_CORE;
params->hdr.size = tag_size (tag_core);
params->u.core.flags = 0;
params->u.core.pagesize = 0;
params->u.core.rootdev = 0;
params = tag_next (params);
}
void setup_memory_tags(void)
{
params->hdr.tag = ATAG_MEM;
params->hdr.size = tag_size (tag_mem32);
params->u.mem.start = 0x30000000;
params->u.mem.size = 64*1024*1024;
params = tag_next (params);
}
int strlen(char *str)
{
int i = 0;
while (str[i])
{
i++;
}
return i;
}
void strcpy(char *dest, char *src)
{
while ((*dest++ = *src++) != \0);
}
void setup_commandline_tag(char *cmdline)
{
int len = strlen(cmdline) + 1;
params->hdr.tag = ATAG_CMDLINE;
params->hdr.size = (sizeof (struct tag_header) + len + 3) >> 2;
strcpy (params->u.cmdline.cmdline, cmdline);
params = tag_next (params);
}
void setup_end_tag(void)
{
params->hdr.tag = ATAG_NONE;
params->hdr.size = 0;
}
int main(void)
{
void (*theKernel)(int zero, int arch, unsigned int params);
// 0. 帮内核设置串口: 内核启动的开始部分会从串口打印一些信息,但是内核一开始没有初始化串口 //
uart0_init();
// 1. 从NAND FLASH里把内核读入内存 //
nand_read(0x60000+64,(unsigned char *)0x30008000,0x200000);