📄 mxc_nb.c
字号:
/* * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//*! * @file mxc_nb.c * * @brief SPL source file for NANDBoot. * * NANDboot is used for booting from NAND flash.\n * NAND Flash can be configured as a booting device. This requires an * Initial Program Loader (IPL) to be written on the first block of the * NAND Flash which performs the initial booting operations. Since IPL has * the size limit, it loads Secondary Program Loader (SPL) which initializes * the system and loads the OS. \n * This file contians the SPL which gets loaded by the IPL * * @ingroup NANDboot */#include "mxc_nb.h"#include "mxc_nb_uart.h"extern badblock_list[];/* Block 1 (16K offset) of the 8 bit 32 MB NAND flash contains the kernel image */#define KERNEL_START_BLOCK 1 /*! * This function initially does the watchdog and UART initialization. It then * displays messages on the terminal. It displays menu at the terminal which * provides different options for the kernel loading and then waits for user * inputs. For executing the Linux kernel it calls the \b jump_to_kernel * assembly routine. */void mxcnb_spl(void){ volatile U32 *pmem = DESTN_ADDR; U32 *pflash = SOURCE_ADDR; U8 *pcmdline = CMDLINE_ADDR; U8 hexstr[20]; int addr, i = 0, timeout = MENU_TIMEOUT; U8 boot_option, ch; U32 kernel_start_block = KERNEL_START_BLOCK; *(volatile U32 *)(CCM_BASE_ADDR + 0x20) = 0x00300C30; *(volatile U32 *)(CCM_BASE_ADDR + 0x24) = 0x00FF3FF0; *(volatile U32 *)(CCM_BASE_ADDR + 0x28) = 0xFFFFC300;#ifdef MX21 mx2_init(); _reg_CRM_PCDR0=(_reg_CRM_PCDR0&0xffff0fff)|0x00007000; for(i=0;i<100000;i++);#endif /* Initialize Watchdog Timer */ mxcnb_wd_init(); /* Initialize UART */ mxcnb_uart_init(); /* service WDOG Timer */ mxcnb_wd_reset(); #if UNIT_TEST mxcnb_uart_unit_test();#endif mxcnb_scan_badblocks(); /* Display message */ mxcnb_outstring("\n\nLinux 2.6 Freescale MXC processor \n");menu: mxcnb_outstring("\n\nChoose an option from below:\n\n"); mxcnb_outstring("1. Load kernel to RAM and then boot from [0x"); mxcnb_puthex(pmem); mxcnb_outstring("]\n"); mxcnb_wd_reset();#if (CHANGE_KERNEL_LOADING_ADDRESS == 1) mxcnb_outstring("2. Change kernel loading address [0x"); mxcnb_puthex(pmem); mxcnb_outstring("]\n");#endif #if (CHANGE_COMMAND_LINE_OPTION == 1) mxcnb_outstring("3. Enter command line option for kernel\n"); #endif #if (CHANGE_COMMAND_LINE_ADDRESS == 1) mxcnb_outstring("4. Change command line option address [0x"); mxcnb_puthex(pcmdline); mxcnb_outstring("]\n");#endif mxcnb_outstring("\n Please enter selection -> "); mxcnb_wd_reset(); #ifndef BOOT_TIME /* Loop to receive input from user */ do { mxcnb_outstring("\b "); if(!mxcnb_timeout(timeout)) { boot_option = mxcnb_getdata(); mxcnb_putdata(boot_option); if (boot_option >= 0x20) { mxcnb_putdata('\b'); mxcnb_putdata(boot_option); } } else { boot_option = '1'; mxcnb_outstring("Timeout occured \n\n"); } } while ((boot_option < '1') || (boot_option > '4'));#else boot_option = '1';#endif mxcnb_wd_reset(); mxcnb_outstring("\n\n"); switch (boot_option) { /* Case to copy kernel to RAM from NAND flash and boot */ case '1': mxcnb_outstring("-->Booting from RAM...\n");#ifdef BOOT_TIME mxcnb_outstring("Before copy kernel, EPIT value: "); mxcnb_puthex(*(volatile unsigned long*)(EPIT1_BASE_ADDR + 0x10)); mxcnb_outstring("\n");#endif if (!mxc_nfb_copykernel((U16*)pmem, kernel_start_block)) { mxcnb_outstring("Bad kernel...exiting...\n"); goto menu; } mxcnb_wd_reset();#ifdef MX21 mx21_module_init();#endif#ifdef BOOT_TIME mxcnb_outstring("After copy kernel, EPIT value: "); mxcnb_puthex(*(volatile unsigned long*)(EPIT1_BASE_ADDR + 0x10)); mxcnb_outstring("\n");#endif mxcnb_outstring("-->Starting kernel...\n"); jump_to_kernel(0, PROC_ID, pcmdline, pmem); break;#if (CHANGE_KERNEL_LOADING_ADDRESS ==1) /* Case for providing Linux kernel destination address */ case '2' : mxcnb_outstring("-->Address (4 bytes hex): 0x"); mxcnb_wd_reset(); addr = mxcnb_gethex(hexstr); if (addr == -1) { mxcnb_outstring( "\n-Invalid Linux kernel destination address"); goto menu; } pmem = (U32*)addr; mxcnb_puthex(addr); mxcnb_wd_reset(); goto menu; break; #endif#if (CHANGE_COMMAND_LINE_OPTION == 1) /* Case to enter new command line option */ case '3': mxcnb_setup_taglist(); goto menu; break;#endif /* Case to change the address location for command line argument */#if (CHANGE_COMMAND_LINE_ADDRESS == 1) case '4': mxcnb_outstring( "-->New command line address (4 bytes hex): 0x"); mxcnb_wd_reset(); addr = (int)mxcnb_gethex(hexstr); if (addr == -1) { mxcnb_outstring( "\n-Invalid Linux kernel location address"); goto menu; } pcmdline = (U8*)addr; mxcnb_puthex(addr); mxcnb_wd_reset(); goto menu; break;#endif /* default case */ default: mxcnb_outstring("Invalid Entry"); goto menu; break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -