码迷,mamicode.com
首页 > 其他好文 > 详细

bootloader功能介绍/时钟初始化设置/串口工作原理/内存工作原理/NandFlash工作原理

时间:2015-04-15 21:27:37      阅读:297      评论:0      收藏:0      [点我收藏+]

标签:

bootloader功能介绍

初始化开发板上主要硬件(时钟,内存,硬盘),
把操作系统从硬盘拷贝到内存,然后让cpu跳转到内存中执行操作系统。
技术分享

boot阶段
1.关闭影响CPU正常执行的外设
-关闭看门狗(watch dog)   WTCON 0xE2700000
-关闭中断 CPSR I和F位设置为1,关闭,不响应任何中断。
2.初始化时钟
-倍频到1Ghz,为外设分频
*串口驱动

3.初始化内存控制器,DDRAM
-验证内存,往里面写一个值,然后再读出来
4.初始化硬盘,nand Flash
-nand flash 读驱动(从nand往外读数据)

loader阶段
1.从硬盘指定的地址加载kernel到内存指定的地址。
2.跳转到内存kernel所在的地址,执行

附加功能:
实现bootloader中shell(命令解释器)

附加功能:
实现bootloader中shell(命令解释器)

uboot中支持的命令, 
help
loadb 下载程序, kermit 协议
go 0X21000000;

例如:在uboot中直接控制蜂鸣器
mm 0xe02000a0 0x1(控制寄存器)
mm 0xe02000a4 0x1(数据寄存器)

常用调试手段:
1.led点灯大法
2.串口调试,uart_getchar,uart_putchar,进一步实现stdio.h

时钟初始化设置

pll 锁相环, 倍频

技术分享

串口工作原理

技术分享

串口工作核心图

技术分享

技术分享

#define ULCON0 *((volatile unsigned int *)0XE2900000)
volatile 关键字,防止编译器做优化,每次读取寄存器的值,都是重新读取寄存器。
//start.s
	AREA start_main,CODE, READONLY
	ENTRY
	IMPORT uart_test
START
	B uart_test
	
	END
//uart.c
#define ULCON0 *((volatile unsigned int *)0XE2900000)
#define UCON0 *((volatile unsigned int *)0XE2900004)
#define UTRSTAT0 *((volatile unsigned int *)0XE2900010)
#define UTXH0 *((volatile unsigned int *)0XE2900020)
#define URXH0 *((volatile unsigned int *)0XE2900024)
#define UBRDIV0 *((volatile unsigned int *)0XE2900028)
#define UDIVSLOT0 *((volatile unsigned int *)0XE290002C)
#define GPACON0 *((volatile unsigned int *)0XE0200000)
void uart_init(void)
{
	//串口管脚设置成功能态
	GPACON0 = 0x22;
	//设置8  N  1
	ULCON0 = 0X3;
	//设置轮询工作模式
	UCON0 = 0X5;
	//设置波特率
	UBRDIV0 = 34;
	UDIVSLOT0 = 0XDDDD;
	
}
char uart_getchar(void)
{
	char ch;
	//如果有数据到达,状态寄存器第0位置1
	//判断状态位是否为1,决定读接收缓冲寄存器,读到的值作为函数的返回值
	while (!(UTRSTAT0 & 0x1))
		;
	ch = URXH0;
	return ch;
}
void uart_putchar(char ch)
{
	//如果状态寄存器第1为置1,表示发送单元为空,可以发送数据
	//把ch赋值到发送缓冲寄存器里,状态寄存器第1为置0, 自动发送,当发送完毕
	while (!(UTRSTAT0 & 0X2))
		;
	UTXH0 = ch;
}
void uart_test(void)
{
	char ch;
	
	uart_init();
	uart_putchar('a');
	uart_putchar('b');
	uart_putchar('c');
	//串口回显功能
	while (1)
	{
		ch = uart_getchar();
		uart_putchar(ch);
	}
}

内存工作原理

技术分享

--------------------------------------------------

技术分享


NandFlash工作原理

内存是总线设备,nandflash属于非总线设备。

没有地址线, 只有数据线。
内存:总线数据, nandflash:非总线设备。
命令、地址、数据复用端口。
忙闲位。
技术分享

技术分享

#define NFCONF (*(volatile unsigned int *)0xB0E00000)
#define NFCONT (*(volatile unsigned int *)0xB0E00004)
#define NFCMMD (*(volatile unsigned int *)0xB0E00008)
#define NFADDR (*(volatile unsigned int *)0xB0E0000C)
#define NFDATA (*(volatile unsigned int *)0xB0E00010)
#define NFSTAT (*(volatile unsigned int *)0xB0E00028)

#define MP0_3CON (*(volatile unsigned int *)0xE0200320)

#define PAGE_SIZE	2048

void nand_init(void)
{
	//[15:12]TACLS = 1->(1) 1/133Mhz = 7.5ns
	//[11:8] TWRPH0 = 1->(1+7) 7.5ns*2 = 15ns
	//[7:4] TWRPH1 = 1->(1+1) 7.5ms *2 = 15ns
	NFCONF |= 1<<2 | 1<< 8 | 1<< 4;
	//AdrCycle [1]1=5 address cycle
	NFCONF |= 1<<1;
	//MODE [0] NAND Flash controller operating node
	// 0=disable nand flash controller
	// *1 = enable nand flash controller
	NFCONT |= 1<<0;
	//Reg_nCE0 [1] nandflash memort nRCS[0] signal control 
	// *0 = force nRCS[0] to low (enable chip select)
	// 1 = force nRCS[0] to high(disable chip select)
	NFCONT &= ~(1<<1);
	//GPIO functional mux setting 
	// 0010 = NF_xxx
	MP0_3CON = 0X22222222;
	return ;	
}

void nand_read_id(char id[])
{
	int i;
	//write read_id cmd 90th
	NFCMMD = 0X90;
	//write address 00h
	NFADDR = 0x00;
	for(i=0; i<5; i++)
	{
		id[i] = NFDATA;
	}
	return ;
}

void nand_read_page(int addr, char buf[])
{
	int i;
	char tmp;
	//write read_page cmd 00h
	NFCMMD = 0X00;
	//write 5 address
	NFADDR = (addr >> 0) & 0xFF;
	NFADDR = (addr >> 8) & 0x7;
	NFADDR = (addr >> 11) & 0xFF;
	NFADDR = (addr >> 19) & 0xFF;
	NFADDR = (addr >> 27) & 0x1;
	//write read_page cmd 30h
	NFCMMD = 0X30;
	//wait for R/nB -->ready
	while( (NFSTAT &(1<<0))==0 )
		;
	//read data 2048 bytes
	for(i=0; i<PAGE_SIZE; i++)
	{
		buf[i] = NFDATA;
	}
	for (i=0; i<64; i++)
	{
		tmp = NFDATA;
	}
	return ;
	
}

void nand_read(int nand_addr, char *sdram_addr, int size)
{
	int pages = (size -1)/PAGE_SIZE + 1;
	int i;
	
	for (i=0; i<pages; i++)
	{
		nand_read_page(nand_addr + i*PAGE_SIZE, sdram_addr + i*PAGE_SIZE);		
	}
	
}



bootloader功能介绍/时钟初始化设置/串口工作原理/内存工作原理/NandFlash工作原理

标签:

原文地址:http://blog.csdn.net/waldmer/article/details/44993647

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!