微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 自己写bootloader

自己写bootloader

时间:11-21 来源:互联网 点击:

// 判断状态 //

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);

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top