⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spl.c

📁 mx21的NAND Flash Bootloader源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************Title:   	Filename:   $Header:$Hardware:   MX21Summay:License:    The contents of this file are subject to the Mozilla Public            License Version 1.1 (the "License"); you may not use this file            except in compliance with the License. You may obtain a copy of            the License at http://www.mozilla.org/MPL/Author:   Company:    Freescale Suzhou Design Center====================Change Log========================$Log:$********************************************************************************//// @ingroup    NAND_BOOTLOADER/// @file       spl.c/// @brief	This main file of boot loader.//////		Spl Concept comes from DOC(M-System).///		It copy Kernel from NAND to SDRAM and jump to Kernel.///		It includes some tool to program NAND flash and debug./// /// @remarks	Spl Size must be below 14k\n///		linkscript is spllink.lds\n///		init asm code is splstartup.S/// @author     /// @bug        /// @version    $Version$//<<<<<Include#ifndef _STANDALONE_#define _STANDALONE_#endif #include "mx2.h"#include "mx2_nand.h"#include "uart.h"#include "usb.h"//>>>>>Include//<<<<<< Private Macro#define	CMD_LINE_LEN		80#define	DELAY_LOOP_COUNT 	0x20000    		///< When Bootloader Wait Input,System Delay. ///Linux Boot Argument.///@remark 	If you want to rootdisk writable, you must add @b rw to cmdline. char  cmdLine[] = "root=/dev/mtdblock/6 rw mem=48M";/// Kernel Start Address In SDRAM.#define KERNEL_START_ADDRESS 0xc0008000	/// Kernel Command Line Address.////// Before Jump to Kernel, Bootloader will copy cmdline to this address.#define KERNEL_CMDLINE       0xc03FF000		/// Kernel Max Size (Unit is Page)#define KERNEL_SIZE	     (0x200000/NAND_FLASH_PAGE_MAIN_SIZE)/// Kernel Partition start page of NAND Flash #define NAND_KERNEL_START    (0x100000/NAND_FLASH_PAGE_MAIN_SIZE)//>>>>>> Private Macro//<<<<<< Private Structure//>>>>>> Private Structure//<<<<<< Global Variable//>>>>>> Global Variable//<<<<<Private Function Declearation//>>>>>Private Function Declearation//<<<<<Body///Set Systme to AsynchMode.void SetAsynchMode(void){/*	__asm__(    	"mrc p15,0,r0,c1,c0,0\n\t"    	"mov r2, #0xC0000000\n\t"    	"orr r0,r2,r0\n\t"    	"mcr p15,0,r0,c1,c0,0\n\t"	);*/}///Init Mx2 Hardware. //////Init CS0,CS1,CS3, Call SetAsynchMode()void init(){    	 int dummy,reg;		    // burst-flash initialization    //comment # CS0 Initialization (Async Mode)     //comment # 32-bit, ?? wait states              //setmem 0xDF001000 0x00003E00 32//setmem 0xDF001004 0x00000E01 32	_reg_WEIM_CSU(0) = 0x00003E00;	_reg_WEIM_CSL(0) = 0x00000E01; //comment # Setting for Memory Map IO Port//comment # CS1 Initialization (Async Mode)//comment # 16-bit, D0..15, ?? wait states//setmem 0xDF001008 0x00002000 32//setmem 0xDF00100C 0x11118501 32	_reg_WEIM_CSU(1)=0x00002000 ;	_reg_WEIM_CSL(1)=0x11118501 ;//comment # CS3 Initialization (Async Mode)//comment # 32-bit, ?? wait states//setmem 0xDF001018 0x00003E00 32//setmem 0xDF00101C 0x11110601 32	_reg_WEIM_CSU(3)=0x00003E00 ;	_reg_WEIM_CSL(3)=0x11110601 ;//comment # Config MUX for pin PF18->CS1//comment # Clear PTF_GIUSE //setmem 0x10015520 0x00000000 32	_reg_GPIO_GIUS(GPIOF)&=~0x40000;//comment # Clear PTF_GPR//setmem 0x10015538 0x00000000 32	_reg_GPIO_GPR(GPIOF)&=~0x40000;//comment # FMCR Register//comment # Select CS3/CSD0 Pin as CS3 only.//setmem 0x10027814 0xFFFFFFC9 32	_reg_SYS_FMCR=0xFFFFFFC9;   // Initialize all peripheral in AIPI1 PSR[1:0] => 10=32bit, 01=16bit, 00=8bit	 _reg_AIPI1_PSR0 = 0x00040304;	 _reg_AIPI1_PSR1 = 0xFFFBFCFB;    // Initialize all peripheral in AIPI1 PSR[1:0] => 10=32bit, 01=16bit, 00=8bit	_reg_AIPI2_PSR0 = 0x0;	_reg_AIPI2_PSR1 = 0xFFFFFFFF; 	//write to the FMCR [31:24] (CLKMODE[1:0]) in order to get the write enable signal active 	_reg_SYS_FMCR |= 0xAA000000;	SetAsynchMode();    }/// Copy Kernel From NAND Flash to SDRAMvoid CopyKernelToMem(){	char 	*pDest = (char*)KERNEL_START_ADDRESS;	char 	spare[NAND_FLASH_PAGE_SPARE_SIZE];	int 	i;	for(i=NAND_KERNEL_START;i<NAND_KERNEL_START+KERNEL_SIZE;i++)	{	    if(i%32==0) //One block	    {		if(NAND_Read_OOB(0,i,spare,16))		{		    EUARTputString("Read OOB Data Error\n");		    return;		}		if(spare[5]!=0xFF)		{		    //Bad Block		    EUARTputString("A Bad Block\n");		    //i+=31;		    i+=32;		    continue;		}	    }	    if(NAND_Read_OnePage(i, pDest, spare))	    {		EUARTputString("Read Data Error\n");		return;	    }	    	    if(i%256==0)		EUARTputString(".");	   				    pDest+=NAND_FLASH_PAGE_MAIN_SIZE;		}}/// Get boot opition when system boot./// @return 	boot option code:///		@li 0 	Program bootloader image///		@li 1	Program kernel image///		@li 2	Program root-disk image///		@li 3	Download kernel and boot from RAM	(this version don't suppport)///		@li 4	Download kernel and boot with ver 0.1.x bootloader format (this version don't suppport)///		@li 5	Boot a ver0.1.x kernel (this version don't suppport)///		@li 6	Boot with a different command line(this version don't suppport)///		@li 7	Command Shell(this version don't suppport)#define __PLL_CHOICE__int GetBootOption(){	int countDown;	int bootOption = 0;	int delayCount ;	while (EUARTdataReady()) EUARTgetData();	// clear input buffer	EUARTputString("Press any key for alternate boot-up options ...   ");	countDown = 2;	bootOption = 0;	while ((countDown) && (!bootOption))	{		EUARTputString("\b\b");		// two back spaces		EUARTputHex(countDown);		delayCount = 0;		do		{			delayCount++;			if (EUARTdataReady()) bootOption = 1;		} while ((delayCount < DELAY_LOOP_COUNT) && (!bootOption));		--countDown;	}		EUARTputString("\b\b");		// two back spaces	EUARTputHex(countDown);	EUARTputString("\n\n");	if (bootOption)	{		while (EUARTdataReady()) EUARTgetData();	// clear input buffer		// print options		EUARTputString("0. Program bootloader image\n");		EUARTputString("1. Program kernel image\n");		EUARTputString("2. Program root-disk image\n");		//EUARTputString("3. Download kernel and boot from RAM\n");		//EUARTputString("4. Download kernel and boot with ver 0.1.x bootloader format\n");		//EUARTputString("5. Boot a ver0.1.x kernel\n");		EUARTputString("6. Boot with a different command line\n");		//EUARTputString("7. Command Shell\n");#ifdef __PLL_CHOICE__		EUARTputString("8. Booting with different fclk/bclk \n");		#endif		EUARTputString("9. Restore bad block bits\n");		EUARTputString("\n   Please enter selection ->  ");		do		{			while (!EUARTdataReady());		// wait for key press			bootOption = EUARTgetData();			if (bootOption >= 0x20)			{				EUARTputData('\b');				EUARTputData(bootOption);			}		} while ((bootOption  < '0') || (bootOption > '9'));		EUARTputString("\n\n");		return bootOption;		}	return -1;}/// @brief   Program NAND FLASH////// @param   pSource         SDRAM Source Address/// @param   size            Size to program/// @param   choice          The choice to program bootloader or kernel or rootdisk///			     @li 0  bootloader///			     @li 1  kernel///			     @li 2  rootdiskvoid ProgramFlash(IN int pSource,IN int size,IN int choice){	int	startPage, page;	char	spare[NAND_FLASH_PAGE_SPARE_SIZE];	int*	p = (int*)pSource;	int write_over = 0;	int erase_over = 0;	int	isFirstPageOfaBlock = 0,badBlockPos;	int	i, last = 512, nBadBlock = 0;	if(choice == 0)	    startPage = 0x0;	else if(choice == 1)	    startPage = 0x100000/512;	else	    startPage = 0x300000/512;	page = startPage;	for(i=0;i<NAND_FLASH_PAGE_SPARE_SIZE;i++)		spare[i]=0xff;	EUARTputString("\n");	while(1)	{		if(page%32==0) //one block		{			badBlockPos =page;		    // choice == 0 need no bad block check		    if(choice && NAND_Read_OOB(0,page,spare,16))		    {			EUARTputString("Read OOB Data Error\n");			return;		    }		    // 0xFF is the setting from factory		    // but after eraseall, the value will change to be 0x00		   // if(choice && (spare[5] != 0xFF) && (spare[5] != 0x00))		    if(choice && (spare[5] != 0xFF))		    {			EUARTputString("A bad block, just skip it\n");			nBadBlock++;			page+=32;			if(size<(page-startPage-nBadBlock*32)*512)				return;			continue;		    }		    else		    {			if(NAND_Erase(page))			{				EUARTputString("Erase Error\n");				FoundBadBlock(page);				return;			}			EUARTputString(".");			isFirstPageOfaBlock = 1;		    }		}		// ECC handle before write a page		last = size-(page-startPage-nBadBlock*32)*512 < 512 ? 		    	size-(page-startPage-nBadBlock*32)*512 : 512;		//mx2_write_ecc((char*)p, spare, last);		if(isFirstPageOfaBlock) //First page of a block		{		  /*  spare[8] = 0x85;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -