200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > bootloader功能介绍/时钟初始化设置/串口工作原理/内存工作原理/NandFlash工作原理...

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

时间:2022-06-26 00:31:30

相关推荐

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

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.sAREA start_main,CODE, READONLYENTRYIMPORT uart_testSTARTB uart_testEND//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 1ULCON0 = 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:非总线设备。 命令、地址、数据复用端口。 忙闲位。

裸板操作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 *)0xE020)#define PAGE_SIZE2048void 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 = 15nsNFCONF |= 1<<2 | 1<< 8 | 1<< 4;//AdrCycle [1]1=5 address cycleNFCONF |= 1<<1;//MODE [0] NAND Flash controller operating node// 0=disable nand flash controller// *1 = enable nand flash controllerNFCONT |= 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_xxxMP0_3CON = 0X22222222;return ;}void nand_read_id(char id[]){int i;//write read_id cmd 90thNFCMMD = 0X90;//write address 00hNFADDR = 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 00hNFCMMD = 0X00;//write 5 addressNFADDR = (addr >> 0) & 0xFF;NFADDR = (addr >> 8) & 0x7;NFADDR = (addr >> 11) & 0xFF;NFADDR = (addr >> 19) & 0xFF;NFADDR = (addr >> 27) & 0x1;//write read_page cmd 30hNFCMMD = 0X30;//wait for R/nB -->readywhile( (NFSTAT &(1<<0))==0 );//read data 2048 bytesfor(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);}}

uboot中操作NandFlash的示例代码:

//s3c2440_nand.c

#include <common.h>#if 0#define DEBUGN printf#else#define DEBUGN(x,args ...){}#endif#include <nand.h>#include <asm/arch/s3c24x0_cpu.h>#include <asm/arch/s3c2410.h>#include <asm/io.h>#define __REGb(x) (*(volatile unsigned char *)(x))#define __REGi(x) (*(volatile unsigned int *)(x))#define NF_BASE 0x4e000000#define NFCONF __REGi(NF_BASE + 0x0)#define NFCONT __REGi(NF_BASE + 0x4)#define NFCMD __REGb(NF_BASE + 0x8)#define NFADDR __REGb(NF_BASE + 0xc)#define NFDATA __REGb(NF_BASE + 0x10)#define NFMECCD0 __REGi(NF_BASE + 0x14)#define NFMECCD1 __REGi(NF_BASE + 0x18)#define NFSECCD__REGi(NF_BASE + 0x1C)#define NFSTAT __REGb(NF_BASE + 0x20)#define NFSTAT0__REGi(NF_BASE + 0x24)#define NFSTAT1__REGi(NF_BASE + 0x28)#define NFMECC0__REGi(NF_BASE + 0x2C)#define NFMECC1__REGi(NF_BASE + 0x30)#define NFSECC __REGi(NF_BASE + 0x34)#define NFSBLK __REGi(NF_BASE + 0x38)#define NFEBLK __REGi(NF_BASE + 0x3C)#define S3C2440_NFCONT_nCE (1<<1)#define S3C2440_ADDR_NALE 0x08#define S3C2440_ADDR_NCLE 0x0c#ifdef CONFIG_NAND_SPL/* in the early stage of NAND flash booting, printf() is not available */#define printf(fmt, args...)static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len){int i;struct nand_chip *this = mtd->priv;for (i = 0; i < len; i++)buf[i] = readb(this->IO_ADDR_R);}#endifulong IO_ADDR_W = NF_BASE; static void s3c2440_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl){struct nand_chip *chip = mtd->priv;DEBUGN("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);if (ctrl & NAND_CTRL_CHANGE) {IO_ADDR_W = NF_BASE;if (!(ctrl & NAND_CLE))IO_ADDR_W |= S3C2440_ADDR_NCLE;if (!(ctrl & NAND_ALE))IO_ADDR_W |= S3C2440_ADDR_NALE;if (ctrl & NAND_NCE)NFCONT &= ~ S3C2440_NFCONT_nCE;elseNFCONT |= S3C2440_NFCONT_nCE; }if (cmd != NAND_CMD_NONE)writeb(cmd, (void *)IO_ADDR_W);}static int s3c2440_dev_ready(struct mtd_info *mtd){DEBUGN("dev_ready\n");return(NFSTAT & 0x01);}#ifdef CONFIG_S3C2410_NAND_HWECCvoid s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode){struct s3c2410_nand *nand = s3c2410_get_base_nand();debugX(1, "s3c2410_nand_enable_hwecc(%p, %d)\n", mtd, mode);writel(readl(&nand->NFCONF) | S3C2410_NFCONF_INITECC, &nand->NFCONF);}static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,u_char *ecc_code){struct s3c2410_nand *nand = s3c2410_get_base_nand();ecc_code[0] = readb(&nand->NFECC);ecc_code[1] = readb(&nand->NFECC + 1);ecc_code[2] = readb(&nand->NFECC + 2);debugX(1, "s3c2410_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x\n",mtd , ecc_code[0], ecc_code[1], ecc_code[2]);return 0;}static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,u_char *read_ecc, u_char *calc_ecc){if (read_ecc[0] == calc_ecc[0] &&read_ecc[1] == calc_ecc[1] &&read_ecc[2] == calc_ecc[2])return 0;printf("s3c2410_nand_correct_data: not implemented\n");return -1;}#endifint board_nand_init(struct nand_chip *nand){u_int32_t cfg;u_int8_t tacls, twrph0, twrph1;struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();DEBUGN("board_nand_init()\n");writel(readl(&clk_power->CLKCON) | (1 << 4), &clk_power->CLKCON);/* initialize hardware */twrph0 = 4;twrph1 =2;tacls = 0;cfg = ((tacls<<12)|(twrph0<<8)|(twrph1<<4));NFCONF=cfg;cfg = ((1<<6)|(1<<4)|(0<<1)|(1<<0));NFCONT=cfg;/* initialize nand_chip data structure */nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)0x4e000010;/* read_buf and write_buf are default *//* read_byte and write_byte are default *//* hwcontrol always must be implemented */nand->cmd_ctrl = s3c2440_hwcontrol;nand->dev_ready = s3c2440_dev_ready;nand->ecc.mode = NAND_ECC_SOFT;DEBUGN("end of nand_init\n");return 0;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。