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

📄 bootloader.c

📁 mx21 Nor flash Bootloader 源代码
💻 C
字号:
/// @ingroup	AMD_BOOTLOADER/// @file       bootloader.c/// @brief      Main file of bootloader.//////             It copies Kernel from AMD Flash to SDRAM and jump to Kernel.///             It includes some tool to program AMD Flash and debug./// /// @remarks    Bootloader Size must be below 1M-16K\n///             linkscript is Init/link.lds\n///             init asm code is Init/startup.S/// @bug        //<<<<<Include#include "Include/type.h"#include "Include/mx2.h"#include "Include/devnode.h"#include "Include/Tahiti_def.h"//>>>>>Include//<<<<<< Private Macro#define	CMD_LINE_LEN		80#define	DELAY_LOOP_COUNT		0x20000//>>>>>> Private Macro//<<<<<< Private Structuredevnode_t   *pNode1, *pNode2;//>>>>>> Private Structure//<<<<<< Global Variablechar        *pMemName, *pCmdNodeName, *pCmdLine, *pChar;const char  memName[] = "DRAMM";const char  cmdNodeName[] = "command line";unsigned char CharOut[50] = "This is Tahiti Uart Test\n";char  cmdLine[CMD_LINE_LEN] = "rw root=/dev/mtdblock/2 load_ramdisk=0 prompt_ramdisk=0 noinitrd mem=48M";//#define _reg_PLL_PCDR    	(*((volatile unsigned long *)(IO_ADDRESS(0x21b020))))//>>>>>> Global Variable//<<<<<Private Function Declearationextern void EUARTinit(void);extern U8 EUARTdataReady(void);extern U8 EUARTgetData(void);extern void EUARTputData(U8);extern void EUARTputString(U8 *line);extern void MX21_InitInternalUART();void mx21_module_init();void mx21_gpio_init();	//Added  Aug-17-04//>>>>>Private Function Declearation//<<<<<Body///The Main Functionint main(){   U32 	*pSource, *pDestin, count;	U8		countDown, bootOption;	U32	delayCount;	U32	fileSize, i,*p=(U32*)0xc0000000;	char	c;	char	*pCmdLine;	char    *pMem;#ifdef __PLL_CHOICE__	int mpll[3];	int MFI,MFN,MFD;	unsigned long mpll_value,fout;	unsigned long presc,bclkdiv,ipdiv,fref;	int fout_trial;	S32 deviation;	U32 temp;	int redundant = 0;	//stat data	char  freq = '7';//default setting, mpll 266,fclk 266, bclk 88.		#endif  /*init is for CS1, burst flash*/   init();   MX21_UartSetting();		//config the GPIO and PLL setting for UART   MX21_InitInternalUART();	// InitInternalUART   mx21_gpio_init();	//Added Aug-17-04   EUARTputString("\n\ni.MX21 Linux Bootloader ver mx21_to3_rel_3.2\n");   EUARTputString("Copyright (C) 2005 Freescale Semiconductor Suzhou Ltd.\n\n");   EUARTputString((U8 *)cmdLine);   EUARTputString("\n\n");  // EUARTputString("MPLL = 266, FCLK = 266, BCLK = 133\n");	// alternate boot-up options ?	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("\n   Please enter selection ->  ");		do		{			while (!EUARTdataReady());		// wait for key press			bootOption = EUARTgetData();			if (bootOption >= 0x20)			{				EUARTputData('\b');				EUARTputData(bootOption);			}		} while ((bootOption  < '0') || (bootOption > '8'));		EUARTputString("\n\n");		// process boot option		if ((bootOption >= '0') && (bootOption <= '4'))		{			fileSize = usbrx();			EUARTputData('\n');		}		if ((bootOption >= '0') && (bootOption <= '2'))		// i.e. flash programming		{			switch (bootOption)			{#if 0				case '0':	// i.e. program bootloader					progFlash(0x0B006E00, 0x0C000000, fileSize);					break;				case '1':	// i.e. program kernel image					progFlash(0x0B006E00, 0x0C100000, fileSize);					break;				case '2':	// i.e. program root-disk					progFlash(0x0B006E00, 0x0C300000, fileSize);#else //MX2#define USB_DISK_START		(0xc2000000)#define BIN_START_IN_SDRAM	(USB_DISK_START +0x9A00)				case '0':	// i.e. program bootloader					progFlash(BIN_START_IN_SDRAM, 0xc8000000, fileSize);					break;				case '1':	// i.e. program kernel image					progFlash(BIN_START_IN_SDRAM, 0xc8100000, fileSize);					break;				case '2':	// i.e. program root-disk					progFlash(BIN_START_IN_SDRAM, 0xc8300000, fileSize);#endif			}			EUARTputString("\nPress RESET button on ADS board ...");			while (1);	// infinite loop		}	}	if (bootOption == '6')	// i.e. boot with a different command line	{		EUARTputString("New command line: ");		i = 0;		do		{			while (!EUARTdataReady());		// wait for key press			c = EUARTgetData();			if (c != '\r')			{				if (c == '\b')				{					if (i > 0)					{						// erase the character						EUARTputData('\b');						EUARTputData(' ');						EUARTputData('\b');						--i;					}				}				else				{					EUARTputData(c);					cmdLine[i++] = c;				}			}		} while ((c != '\r') && (i < CMD_LINE_LEN-1));		if (i > 0)			cmdLine[i] = 0;		// mark end of string		EUARTputData('\n');	}	if (bootOption == '7')	// i.e.read/write command	{		while(1)	   {			EUARTputString(">: ");		i = 0;		do		{			while (!EUARTdataReady());		// wait for key press			c = EUARTgetData();			if (c != '\r')			{				if (c == '\b')				{					if (i > 0)					{						// erase the character						EUARTputData('\b');						EUARTputData(' ');						EUARTputData('\b');						--i;					}				}				else				{					EUARTputData(c);					cmdLine[i++] = c;				}			}		} while ((c != '\r') && (i < CMD_LINE_LEN-1));		if (i > 0)			cmdLine[i] = 0;		// mark end of string	//command_parase();			EUARTputData('\n');	   }		}#ifdef __PLL_CHOICE__	if(bootOption == '8')	{		//now it is mpll266,presc 0, bclkdiv 2,ipdiv 1.		//get input mpll				EUARTputString("Please enter your settings mpll(MHz)... \n ");		i = 0;		do		{			while (!EUARTdataReady());		// wait for key press			c = EUARTgetData();			if (c != '\r')			{				EUARTputData(c);				c = c - '0';				mpll[i++] = c;			}		} while ((c != '\r') && (i<3));		mpll_value = mpll[0]*100 + (mpll[1])*10 + mpll[2];		EUARTputString("\n");		//get input presc value		#if 0		EUARTputString("Please enter your settings PRESC(0~3)... \n ");#else//Changed for TO2		EUARTputString("Please enter your settings PRESC(0~7)... \n ");#endif		while (!EUARTdataReady());		// wait for key press		c = EUARTgetData();		if (c != '\r')		{			EUARTputData(c);			c = c - '0';			presc = c;		}		EUARTputString("\n");				//get input bclkdiv value				EUARTputString("Please enter your settings BCLKDIV(00~15)... \n ");		i = 0;		do		{			while (!EUARTdataReady());		// wait for key press			c = EUARTgetData();			if (c != '\r')			{				EUARTputData(c);				c = c - '0';				mpll[i++] = c;			}		} while ((c != '\r') && (i <2));		bclkdiv = mpll[0]*10+mpll[1];		EUARTputString("\n");		//get input ipdiv value				EUARTputString("Please enter your settings ipdiv(0~1)... \n ");		while (!EUARTdataReady());		// wait for key press		c = EUARTgetData();		if (c != '\r')		{			EUARTputData(c);			c = c - '0';			ipdiv = c;		}				*(VP_U32)CRM_MPCTL0 = mpll_value | (presc<<10) | (bclkdiv<<16) | (ipdiv<<26);		EUARTputString("\n");	}#endif	if ((bootOption == '3') || (bootOption == '4'))	{	// i.e. download kernel and run    	// copy kernel from 0xc8100000 to 0xc0008000	EUARTputString("Copying Kernel from USB disk to RAM...\n");    	count = fileSize;    	pSource = (U32 *)0xc2006e00;    	pDestin = (U32 *)0xc0008000;	    	do	    	{	     		*(pDestin++) = *(pSource++);	        	count -= 4;	    	} while (count > 0);	}	else // i.e. kernel image is in FLASH	{    	// copy kernel from FLASH to RAM    	EUARTputString("Copying kernel from Flash to RAM ...\n"); 	    	count = 0x200000;   // 2 Mbytes    	pSource = (U32 *)0xc8100000;    	pDestin = (U32 *)0xc0008000;    	do    	{     		*(pDestin++) = *(pSource++);        	count -= 4;    	} while(count!=0);	}    EUARTputString("Booting kernel ...\n\n");	 if ((bootOption == '4') || (bootOption == '5'))		// boot a ver0.1.x kernel	 {	    // prepare devnodes   	 // Parameters passed to kernel must reside in the memory range	    // of 0x08000000 to 0x083FFFFF (kernel will map to this 4M of   	 // memory during startup with proper MMU setting).	    // We should be very careful of not to put parameters in those   	 // locations occupied by the kernel itself. So we'll use the	    // last 4K only.   	 pNode1 = (devnode_t *)  0x083FF000;	    pNode2 = (devnode_t *)  0x083FF100;	    pMemName = (char *)     0x083FF200;   	 pChar = (char *)&memName;	    do {   	 } while ((*(pMemName++) = *(pChar++)) != 0);	    pMemName = (char *)     0x083FF200;   	 pCmdNodeName = (char *) 0x083FF300;	    pChar = (char *)&cmdNodeName;   	 do {	    } while ((*(pCmdNodeName++) = *(pChar++)) != 0);   	 pCmdNodeName = (char *) 0x083FF300;	    pCmdLine = (char *)     0x083FF400;   	 pChar = (char *)&cmdLine;	    do {   	 } while ((*(pCmdLine++) = *(pChar++)) != 0);	    pCmdLine = (char *)     0x083FF400;    	 pNode1->next = (devnode_t *)0;	    pNode1->type = (DEVNODE_DEVICE << 16) | DEVNODE_DEVICE_MEMORY;   	 pNode1->params[0] = 0;	    pNode1->params[1] = MEM_SIZE;   	 pNode1->name = pMemName;	    pNode1->data = (void *)0;   	 pNode1->size = 0;	    pNode2->next = pNode1;   	 pNode2->type = (DEVNODE_OS << 16) | DEVNODE_OS_COMMAND_LINE;	    pNode2->params[0] = 0;   	 pNode2->params[1] = 0;	    pNode2->name = pCmdNodeName;   	 pNode2->data = pCmdLine;	    pNode2->size = 23;	    mx21_module_init();	    JumpToKernel0x((void *)0xc0008000, 0, 17, pNode2) ;	 }	 // the command line is passed through the last 4K of the 3M memory allocated to the kernel	 // this 3M memory block will be mapped to the kernel space during kernel startup	 pMem = (char *)0xc03FF000;	 pCmdLine = (char *)&cmdLine;	 while ((*(pMem++)=*(pCmdLine++)) != 0);	   	 mx21_module_init();  	 JumpToKernel((void *)0xc0008000, 0xc03FF000) ;	 return (0);}/* * Added Aug-17-04 * Config GPIO to save power in Sleep mode. */void mx21_gpio_init(){	//Enable 	*( (volatile U32 *)CRM_PCCR0 ) |= 0x800;		//Set GPIO C, E as GPIO function, output	*((volatile U32 *)GPIOC_GIUS) = 0xffffffe0;	//This is the default value	*((volatile U32 *)GPIOC_DDIR) = 0xffffffe0;	//Output port	*((volatile U32 *)GPIOC_OCR1) = 0xfffffc00;	*((volatile U32 *)GPIOC_OCR2) = 0x00fc0f20;	*((volatile U32 *)GPIOE_GIUS) = 0x00fc0f20;	//This is the default value	*((volatile U32 *)GPIOE_DDIR) = 0x00000020;	//Set PE5(PWMO) as output	*((volatile U32 *)GPIOE_OCR1) |= 0xc00;		//Select data register as output for PWMO}void mx21_module_init(){	 // enable it to let all the registers be accessed in user mode.	 *( (volatile U32 *)AIPI1_PAR ) = 0;	 *( (volatile U32 *)AIPI2_PAR ) = 0;//comment #################//comment # AHB-Lite IP Interface//setmem 0x10000000 0x00040304 32	 *( (volatile U32 *)AIPI1_PSR0 ) = 0x00040304;//setmem 0x10020000 0x00000000 32	 *( (volatile U32 *)AIPI2_PSR0 ) = 0;//setmem 0x10000004 0xFFFBFCFB 32	 *( (volatile U32 *)AIPI1_PSR1 ) = 0xFFFBFCFB;//setmem 0x10020004 0xFFFFFFFF 32	 *( (volatile U32 *)AIPI2_PSR1 ) = 0xFFFFFFFF;//comment # Config MUX for pin PF18->CS1//comment # Clear PTF_GIUSE //setmem 0x10015520 0x00000000 32	*( (volatile U32 *)GPIOF_GIUS ) = 0;//comment # Clear PTF_GPR//setmem 0x10015538 0x00000000 32	*( (volatile U32 *)GPIOF_GPR ) = 0;	//comment # FMCR Register//comment # Select CS3/CSD0 Pin as CS3 only.//setmem 0x10027814 0xFFFFFFC9 32	*( (volatile U32 *)SYS_FMCR ) = 0xFFFFFFC9;//comment ### PCCR0 (Disable LCDC)//setmem 0x1002701C 0x35084003 32	*( (volatile U32 *)CRM_PCCR0 ) = 0x35084003;	//comment ### Master Priority Register for Slave Port 3//setmem 0x1003F300 0x00123456 32//	*( (volatile U32 *)0x1003F300 ) = 0x00123456;		// Keep LCDC as the highest priority	*( (volatile U32 *)SYS_PSCR ) = 0;		*( (volatile U32 *)MAX_SLV3_MPR3 ) = 0x00123056;	*( (volatile U32 *)MAX_SLV3_SGPCR3 ) = 0;		//add for SLCDC//	*( (volatile U32 *)0x1003F310 ) |= 0x00040000;		//end/* 2comment ########################################################comment # CSD0 Initialization    comment # 16Mx16x2 IAM=0 CSD0 CL3 comment ########################################################comment *** Set Precharge Commandsetmem 0xDF000000 0x92120300 32comment *** Issue Precharge all Commandmemory 0xC0200000 +1 32          comment *** Set AutoRefresh Commandsetmem 0xDF000000 0xA2120300 32 comment *** Issue AutoRefresh Commandmemory 0xC0000000 +1 32         memory 0xC0000000 +1 32memory 0xC0000000 +1 32memory 0xC0000000 +1 32memory 0xC0000000 +1 32         memory 0xC0000000 +1 32memory 0xC0000000 +1 32memory 0xC0000000 +1 32comment *** Set Mode Registersetmem 0xDF000000 0xB2120300 32comment *** Issue Mode Register Commandcomment Burst Length = 8memory 0xC0119800 +1 32           comment *** Set to Normal Modecomment # From the spec of the SDRAM K4S56163LC-RG75000, comment # 1. tRCD = 19ns minimum  -> RCD = 3 clk (SDCLK=133MHz) -> SRCD = 11b comment # 2. tRP  = 19ns minimum  -> RP  = 3 clk (SDCLK=133MHz) -> SRP  = 0b comment # 3. tRC  = 65ns minimum  -> RC  = 9 clk (SDCLK=133MHz) -> SRC  = 1001b comment # 4. refresh rate = 8192rows/64ms -> SREFR = 11bsetmem 0xDF000000 0x8212F339 32 comment ### End of Memory Configuration ########################################## 2*///comment # ena emma//setmem 0x1002701C 0x3d0Cc003 32	*( (volatile U32 *)CRM_PCCR0 ) = 0x3d0Cc003;	//comment # enable user mode CSI access//setmem 0x10027818 0x6000e 32	*( (volatile U32 *)SYS_GPCR ) = 0x6000e;	//Just for test//*( ( volatile unsigned int *)0xe4021030 ) = 0x800f000f;//*( (volatile unsigned int *)0xe403f200 ) = 0x543012;//*( (volatile unsigned int *)0xe403fd00 ) = 1;//*( (volatile unsigned int *)0xe403f800 ) = 1;//*( (volatile unsigned int *)0xe403f900 ) = 1;}//>>>>>Body

⌨️ 快捷键说明

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