自己写bootloader2 -init.c,基于s3c2440
来源:互联网 发布:php exec 返回值 编辑:程序博客网 时间:2024/05/01 08:09
这里面主要是从拷贝代码到内存,清除BSS,还有nand的读函数。
#define NFCONF (*((volatile unsigned long *)0x4E000000))
#define NFCONT (*((volatile unsigned long *)0x4E000004))
#define NFCMMD (*((volatile unsigned char *)0x4E000008))
#define NFADDR (*((volatile unsigned char *)0x4E00000c))
#define NFDATA (*((volatile unsigned char *)0x4E000010))
#define NFSTAT (*((volatile unsigned char *)0x4E000020))
/*GPIO*/
#define GPHCON (*(volatile unsigned long *)0x56000070)
#define GPHUP (*(volatile unsigned long *)0x56000078)
/*UART registers*/
#define ULCON0 (*(volatile unsigned long *)0x50000000)
#define UCON0 (*(volatile unsigned long *)0x50000004)
#define UFCON0 (*(volatile unsigned long *)0x50000008)
#define UMCON0 (*(volatile unsigned long *)0x5000000c)
#define UTRSTAT0 (*(volatile unsigned long *)0x50000010)
#define UTXH0 (*(volatile unsigned char *)0x50000020)
#define URXH0 (*(volatile unsigned char *)0x50000024)
#define UBRDIV0 (*(volatile unsigned long *)0x50000028)
#define TXD0READY (1<<2)
//#define UART_BRD ((UART_CLK / (UART_BAUD_RATE * 16)) - 1)
void nand_read(unsigned int addr, unsigned char *buf, unsigned int len);
int Is_Boot_From_Norflash(void)
{
volatile int *p = (volatile int *)0;
int val;
val = *p;
*p = 0x12345678;
if (*p == 0x12345678)
{
/*写入内存成功,不是nor启动*/
*p = val;
return 0;
}
else
{
/*norflash 不能像内存一样写,她只能读 */
return 1;
}
}
void copy_to_sdram(unsigned char *src, unsigned char *dest, unsigned int len)
{
int i = 0;
/*如果是从nor启动,*/
if (Is_Boot_From_Norflash())
{
while(i < len)
{
dest[i] = src[i];
i++;
}
}
else /* 否则是从nand启动*/
{
//nand_init();
nand_read((unsigned int)src, dest, len);
}
}
void clean_bss(void)
{
extern int __bss_start, __bss_end;
int *p = &__bss_start;
for (; p < &__bss_end; p++)
*p = 0;
}
void nand_init(void)
{
#define TACLS 0
#define TWRPH0 1
#define TWRPH1 0
/* 设置时序 */
NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
/* 使能NAND Flash控制器, 初始化ECC, 禁止片选 */
NFCONT = (1<<4)|(1<<1)|(1<<0);
}
void select(void)
{
NFCONT &= ~(1 << 1);
}
void delselect(void)
{
NFCONT |= (1 << 1);
}
void write_cmd(unsigned char cmd)
{
volatile int i ;
NFCMMD = cmd;
for(i = 0; i < 10; i++);
}
void write_addr(unsigned int addr)
{
unsigned int col = addr % 2048;
unsigned int page = addr / 2048;
volatile int i;
NFADDR = col & 0xff;
for (i = 0; i < 10; i ++);
NFADDR = (col >> 8) & 0xff;
for (i = 0; i < 10; i ++);
NFADDR = page & 0xff;
for (i = 0; i < 10; i ++);
NFADDR = (page >> 8) & 0xff;
for (i = 0; i < 10; i ++);
NFADDR = (page >> 16) & 0xff;
for (i = 0; i < 10; i ++);
}
int write_data(void)
{
return NFDATA;
}
void nand_wait(void)
{
while (!(NFSTAT & 1));
}
void nand_read(unsigned int addr, unsigned char *buf, unsigned int len)
{
int i = 0;
int col = addr % 2048;
/*1: 选中芯片*/
select();
while(i < len)
{
/*2: 发出读命令00h*/
write_cmd(0x00);
/*3: 发出读地址*/
write_addr(addr);
/*4: 发出读命令30h*/
write_cmd(0x30);
/*5: 读状态*/
nand_wait();
/*6:读数据*/
for (; (col < 2048)&&(i < len); col++)
{
buf[i] = write_data();
i++;
addr++;
}
col = 0;
}
/*取消:片选*/
delselect();
}
#define TXD0READY (1<<2)
#define RXD0READY (1)
#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)
{
int i;
int j;
puts("0x");
for(i = 0; i < 8; i++)
{
j = (val >> ((7 - i) * 4)) & 0xf;
if ((j >= 0 ) && (j <= 9))
{
putc(j + '0');
}
else
{
putc('A' + j - 0xa);
}
}
声明:这些代码都是参考韦东山老师视屏写的代码。
- 自己写bootloader2 -init.c,基于s3c2440
- 自己写bootloader2 -init.c,基于s3c2440
- 自己写bootloader2 -跳转执行,基于s3c2440
- 自己写bootloader2 -跳转执行,基于s3c2440
- 自己写bootloader1 - start.S,基于s3c2440
- [Funkunux] 自己写MMU实验 基于S3C2440
- 自己写bootloader1 - start.S,基于s3c2440
- 自己写bootloader笔记3---init.c分析
- 自己写bootloader笔记3---init.c分析
- 04-S3C2440学习之自己写bootloader
- 自己写的基于SDL的C语言游戏!
- 自己写的一个基于ocilib的c连接池,未经测试
- 基于linux2.6.31.14内核自己写虚拟摄像头驱动myvivi.c
- C++-----自己写的哈希表
- apache(基于c写cgi)
- s3c2440烧写第一步
- 基于S3C2440的linux-3.6.6移植——内核移植,建立自己的平台系统
- 基于S3C2440的linux-3.6.6移植——内核移植,建立自己的平台系统
- eclipse报出的错误
- hbase修复.META.表与HDFS文件不一致问题
- CX51 用户手册----MODP2 伪指令
- ios菜鸟之路:textfield隐藏键盘以及点击背景取消键盘
- android View.measure
- 自己写bootloader2 -init.c,基于s3c2440
- 自己动手学TCP/IP--以太网帧
- hbase中region的规划与硬盘配置分析
- 笔记-- vs2008 ,右键转到定义,弹出“未定义符号”
- android屏幕亮度的调整
- 拦截器中多个URL-PATTERN配置
- 切片源图片的工具MapCruncher使用说明
- MySQL 启动slave报错 ERROR 1201 (HY000)
- hbase入库过程中JVM 新生代大小配置试验