mini2440使用uboot(详细)
UBOOT命令详解

常用U-boot命令详解(z)2010-09-30 15:05:52| 分类:学习心得体会|字号订阅U-boot发展到现在,他的命令行模式已经非常接近Linux下的shell了,在我编译的U-boot-2009.11中的命令行模式模式下支持“Tab”键的命令补全和命令的历史记录功能。
而且如果你输入的命令的前几个字符和别的命令不重复,那么你就只需要打这几个字符即可,比如我想看这个U-boot的版本号,命令就是“ version”,但是在所有的命令中没有其他任何一个的命令是由“v”开头的,所以只需要输入“v”即可。
[u-boot@MINI2440]# versionU-Boot 2009.11 ( 4月04 2010 - 12:09:25)[u-boot@MINI2440]# vU-Boot 2009.11 ( 4月04 2010 - 12:09:25)[u-boot@MINI2440]# baseBase Address: 0x00000000[u-boot@MINI2440]# baBase Address: 0x00000000由于U-boot支持的命令实在太多,一个一个细讲不现实,也没有必要。
所以下面我挑一些烧写和引导常用命令介绍一下,其他的命令大家就举一反三,或者“help”吧!(1)获取帮助命令:help 或?功能:查看当前U-boot版本中支持的所有命令。
[u-boot@MINI2440]#help?- alias for'help'askenv - get environment variables from stdinbase - print or set address offsetbdinfo - print Board Info structurebmp - manipulate BMP image databoot - boot default, i.e., run 'bootcmd'bootd - boot default, i.e., run 'bootcmd'bootelf - Boot from an ELF image in memorybootm - boot application image from memorybootp - boot image via network using BOOTP/TFTP protocolbootvx - Boot vxWorks from an ELF imagecmp - memory compareconinfo - print console devices and informationcp - memory copycrc32 - checksum calculationdate - get/set/reset date &timedcache - enable or disable data cachedhcp - boot image via network using DHCP/TFTP protocol echo - echo args to consoleeditenv - edit environment variableeeprom - EEPROM sub-systemerase - erase FLASH memoryexit-exit scriptfatinfo - print information about filesystemfatload - load binary file from a dos filesystemfatls -list files in a directory (default/)flinfo - print FLASH memory informationfsinfo - print information about filesystemsfsload - load binary file from a filesystem imagego - start application at address 'addr'help - print online helpi2c - I2C sub-systemicache - enable or disable instruction cacheiminfo - print header information for application image imls -list all images found in flashimxtract- extract a part of a multi-imageitest -return true/false on integer compareloadb - load binary file over serial line(kermit mode) loads - load S-Record file over serial lineloadx - load binary file over serial line(xmodem mode) loady - load binary file over serial line(ymodem mode) loop - infinite loop on address rangels -list files in a directory (default/)md - memory displaymm - memory modify (auto-incrementing address)mmc - MMC sub-systemmtest - simple RAM read/write testmw - memory write(fill)nand - NAND sub-systemnboot - boot from NAND devicenfs - boot image via network using NFS protocolnm - memory modify (constant address)ping -send ICMP ECHO_REQUEST to network hostprintenv- print environment variablesprotect - enable or disable FLASH write protection rarpboot- boot image via network using RARP/TFTP protocol reginfo - print register informationreset- Perform RESET of the CPUrun - run commands in an environment variablesaveenv - save environment variables to persistent storage setenv -set environment variablesshowvar - print local hushshell variablessleep- delay execution for some timesource - run script from memorytest- minimal test like /bin/shtftpboot- boot image via network using TFTP protocolunzip - unzip a memory regionusb - USB sub-systemusbboot - boot from USB deviceversion - print monitor version以bmp指令为例:Usage:bmp info <imageAddr>- display image infobmp display <imageAddr>[x y]- display image at x,y[u-boot@MINI2440]# h bmbmp - manipulate BMP image dataUsage:bmp info <imageAddr>- display image infobmp display <imageAddr>[x y]- display image at x,y(2)环境变量(environment variables,简称ENV)与相关指令和shell类似,U-Boot也有环境变量。
Mini2440 Uboot移植

第一部分根据uboot-2008.10,移植出能在mini2440 nor flash上运行的uboot1 修改Makefile:在uboot-2008.10顶层目录中的Makefile中,参考smdk2410_config,添加新的配置选项。
# add,flyrizmini2440_config : unconfig@$(MKCONFIG) $(@:_config=) arm arm920t mini2440 NULL s3c24x02 修改cpu/arm920t/start.S:2.1添加支持S3C2440的编译条件/* #if defined(CONFIG_S3C2400)||defined(CONFIG_S3C2410) *//*modify,flyriz*/#if defined(CONFIG_S3C2400)||defined(CONFIG_S3C2410)||defined(CONFIG_S3C2440) 2.2添加S3C2440寄存器的定义#else# define pWTCON 0x53000000# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */# define INTSUBMSK 0x4A00001C# define CLKDIVN 0x4C000014 /* clock divisor register */# endif/*add,flyriz,for 2440,register define*/#define CLK_CTL_BASE 0x4C000000#define MDIV_405 0x7f<<12#define PSDIV_405 0x21#define UPLL_MDIV_48 0x38<<12#define UPLL_PSDIV_48 0x22#define MDIV_200 0xa1<<12#define PSDIV_200 0x31/****************************/2.3修改中断禁止代码# if defined(CONFIG_S3C2410)ldr r1, =0x3ffldr r0, =INTSUBMSKstr r1, [r0]# endif/*add,flyriz*/# if defined(CONFIG_S3C2440)ldr r1, =0x7fff /* S3C2440有15个子中断[0...14] */ldr r0, =INTSUBMSKstr r1, [r0]# endif2.4 修改时钟设置/********************* FCLK:HCLK:PCLK = 1:2:4 ** default FCLK is 120 MHz ! *ldr r0, =CLKDIVNmov r1, #3str r1, [r0]#endif * CONFIG_S3C2400 || CONFIG_S3C2410 *********************//*modify,flyriz*/#if defined(CONFIG_S3C2440)/*FCLK:HCLK:PCLK=1:4:8*/ldr r0,=CLKDIVNmov r1,#5str r1,[r0]mrc p15,0,r1,c1,c0,0 /* CP15中的寄存器C1是一个控制寄存器,用于配置MMU中的一些操作 */orr r1,r1,#0xc0000000mcr p15,0,r1,c1,c0,0mov r1,#CLK_CTL_BASE /* 0x4C000000 LOCKTIME:PLL lock time counter */mov r2,#UPLL_MDIV_48add r2,r2,#UPLL_PSDIV_48str r2,[r1,#0x08] /* 0x4C000008 UPLLCON=0x38<<12||0x22,output 48MHz */mov r2,#MDIV_405add r2,r2,#PSDIV_405str r2,[r1,#0x04] /* 0x4C000004 MPLLCON=0x7f<<12||0x21,output 405MHz */ #elseldr r0,=CLKDIVNmov r1,#3str r1,[r0]mrc p15,0,r1,c1,c0,0orr r1,r1,#0xc0000000mcr p15,0,r1,c1,c0,0mov r1,#CLK_CTL_BASEmov r2,#MDIV_200add r2,r2,#PSDIV_200str r2,[r1,#0x04]#endif#endif /*CONFIG_S3C2400||CONFIG_S3C2410||CONFIG_S3C2440*//**********************************************************/3 修改cpu/arm920t/s3c24x0/interrupts.c3.1 在条件编译的宏定义里加入对s3c2440的支持:/* #if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) *//*modify,flyriz*/#if defined(CONFIG_S3C2400)||defined(CONFIG_S3C2410)||defined(CONFIG_S3C2440)||defined(CONFIG_TRAB)/* #elif defined(CONFIG_S3C2410) *//*modify,flyriz*/#elif defined(CONFIG_S3C2410)||defined(CONFIG_S3C2440)3.2 在get_tbclk函数中,添加对mini2440的支持:#if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB)tbclk = timer_load_val * 100;#elif defined(CONFIG_SBC2410X) || \defined(CONFIG_SMDK2410) || \defined(CONFIG_MINI2440) || \defined(CONFIG_VCMA9) /*modify,flyriz,add:CONFIG_MINI2440*/tbclk = CFG_HZ; /*get_tbclk函数的作用?CFG_HZ又是什么?*/4 修改cpu/arm920t/s3c24x0/speed.c4.1 在条件编译的宏定义里加入对s3c2440的支持:/*#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410)|| defined (CONFIG_TRAB)*//*modify,flyriz*/#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_S3C2440) || defined (CONFIG_TRAB) /*#elif defined(CONFIG_S3C2410)*//*modify,flyriz*/#elif defined(CONFIG_S3C2410)||defined(CONFIG_S3C2440)4.2 修改get_PLLCLK函数:m = ((r & 0xFF000) >> 12) + 8;p = ((r & 0x003F0) >> 4) + 2;s = r & 0x3;/*add,flyriz*/#if defined(CONFIG_S3C2440)if(pllreg==MPLL)return ((CONFIG_SYS_CLK_FREQ*m*2)/(p<<s)); /*S3C2440中,UPLL与MPLL的计算公式不同*/ else if(pllreg==UPLL)#endif4.3 修改get_HCLK函数:ulong get_HCLK(void){S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();/*return ((clk_power->CLKDIVN&0x2)?get_FCLK()/2:get_FCLK()); delete,flyriz*//*add,flyriz*/#if defined(CONFIG_S3C2440)if(clk_power->CLKDIVN & 0x6){if((clk_power->CLKDIVN & 0x6)==2)return (get_FCLK()/2);if((clk_power->CLKDIVN & 0x6)==6)return ((clk_power->CAMDIVN&0x100)?get_FCLK()/6:get_FCLK()/3);if((clk_power->CLKDIVN & 0x6)==4)return ((clk_power->CAMDIVN&0x200)?get_FCLK()/8:get_FCLK()/4);return (get_FCLK());}else return (get_FCLK());#elsereturn ((clk_power->CLKDIVN&0x2)?get_FCLK()/2:get_FCLK());#endif}5 修改include/asm-arm/mach-types.h,添加mini2440的机器ID(必须与内核提供的ID保持一致):#define MACH_TYPE_GENEVA 1873#define MACH_TYPE_MINI2440 1999 /*add,flyriz,mini2440机器ID,必须与内核提供的ID相同*/6 修改cpu/arm920t/s3c24x0/serial.c/*#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB)*//*modify,flyriz*/#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_S3C2440) || defined (CONFIG_TRAB) /*#elif defined(CONFIG_S3C2410)*//*modify,flyriz*/#elif defined(CONFIG_S3C2410)||defined(CONFIG_S3C2440)7 修改drivers/rtc/s3c24x0_rtc.c/* #elif defined(CONFIG_S3C2410) */#elif defined(CONFIG_S3C2410)||defined(CONFIG_S3C2440) /*modify,flyriz*/8 修改include/s3c24x0.h/*#ifdef CONFIG_S3C2410*/#if defined(CONFIG_S3C2410)||defined(CONFIG_S3C2440) /*modify,flyriz*/(所有ifdef CONFIG_S3C2410全部替换)/* CLOCK & POWER MANAGEMENT (see S3C2400 manual chapter 6) *//* (see S3C2410 manual chapter 7) */typedef struct {S3C24X0_REG32 LOCKTIME;S3C24X0_REG32 MPLLCON;S3C24X0_REG32 UPLLCON;S3C24X0_REG32 CLKCON;S3C24X0_REG32 CLKSLOW;S3C24X0_REG32 CLKDIVN;/*add,flyriz*/#if defined(CONFIG_S3C2440)S3C24X0_REG32 CAMDIVN; /*增加CAMDIVN的定义*/#endif} /*__attribute__((__packed__))*/ S3C24X0_CLOCK_POWER;9 为开发板新建一个目录在board目录中新建一个目录mini2440,将board/smdk2410下的所有文件拷贝到board/mini2440中,然后对mini2440中的文件做修改:将smdk2410.c改为mini2440.c;将Makefile中的代码COBJS :=smdk2410.o flash.o 改为COBJS :=mini2440.o flash.o10 修改board/mini2440/mini2440.c10.1 修改PLL的配置/*****************#elif FCLK_SPEED==1 // Fout = 202.8MHz#define M_MDIV 0xA1#define M_PDIV 0x3#define M_SDIV 0x1#endif#define USB_CLOCK 1*//*modify,flyriz*/#elif FCLK_SPEED==1#if defined(CONFIG_S3C2410)/*Fout=202.8MHz*/#define M_MDIV 0xA1#define M_PDIV 0x3#define M_SDIV 0x1#endif#if defined(CONFIG_S3C2440)/*Fout=405MHz*/#define M_MDIV 0x7f#define M_PDIV 0x2#define M_SDIV 0x1#endif#endif#define USB_CLOCK 1/*****************/10.2 修改UPLL的配置/***************#if USB_CLOCK==0#define U_M_MDIV 0xA1#define U_M_PDIV 0x3#define U_M_SDIV 0x1#elif USB_CLOCK==1#define U_M_MDIV 0x48#define U_M_PDIV 0x3#define U_M_SDIV 0x2#endif*//*modify,flyriz*/#if USB_CLOCK==0#define U_M_MDIV 0xA1#define U_M_PDIV 0x3#define U_M_SDIV 0x1#elif USB_CLOCK==1#if defined(CONFIG_S3C2410) #define U_M_MDIV 0x48#define U_M_PDIV 0x3#endif#if defined(CONFIG_S3C2440) #define U_M_MDIV 0x38#define U_M_PDIV 0x2#endif#define U_M_SDIV 0x2#endif/*****************/10.3 修改board_init函数,以引导内核/* arch number of SMDK2410-Board *//* gd->bd->bi_arch_number = MACH_TYPE_SMDK2410; *//*modify,flyriz*/gd->bd->bi_arch_number = MACH_TYPE_MINI2440;11 修改board/mini2440/lowlevel_init.S中REFRESH的刷新周期/* REFRESH parameter */#define REFEN 0x1 /* Refresh enable */#define TREFMD 0x0 /* CBR(CAS before RAS)/Auto refresh *//* #define Trp 0x0 2clk *//*modify,flyriz*/#define Trp 0x2 /* 4clk */#define Trc 0x3 /* 7clk */#define Tchr 0x2 /* 3clk *//* #define REFCNT 1113 period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) *//*modify,flyriz*/#define REFCNT 1012/**************************************/12 添加并修改配置文件为开发板添加新的配置文件,复制include/configs/smdk2410.h,另存为include/configs/mini2440.h,并对其进行修改12.1 添加s3c2440的宏定义#define CONFIG_ARM920T 1 /* This is an ARM920T Core *//* #define CONFIG_S3C2410 1 in a SAMSUNG S3C2410 SoC *//* #define CONFIG_SMDK2410 1 on a SAMSUNG SMDK2410 Board *//*modify,flyriz*/#define CONFIG_S3C2440 1#define CONFIG_MINI2440 112.2 修改命令提示符#defineCFG_LONGHELP /* undef to save memory *//* #define CFG_PROMPT "SMDK2410 # " Monitor Command Prompt *//*modify,flyriz*/#define CFG_PROMPT "Mini2440 # "一个具备基本功能的UBOOT代码修改部分已经完成。
2440超详细U-BOOT(UBoot介绍+H-jtag使用+Uboot使用)

凌FL2440超详细U-BOOT作业(UBoot介绍+H-jtag使用+Uboot使用)Bootloader是高端嵌入式系统开发不可或缺的部分。
它是在操作系统内核启动之前运行的一段小程序。
通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。
现在主流的bootloader有U-BOOT、vivi、Eboot等。
本次作业先做Uboot的烧写吧。
希望通过这个帖子,能让更多的初学者朋友了解一些UBoot的知识,也希望高手朋友对我的不足予以斧正。
首先说一下什么是Uboot:U-Boot,全称Universal Boot Loader,是遵循GPL条款的开放源码项目。
从FAD SROM、8xxROM、PPCBOOT逐步发展演化而来。
其源码目录、编译形式与Linux内核很相似,事实上,不少U-Boot源码就是相应的Linux内核源程序的简化,尤其是一些设备的驱动程序,这从U-Boot源码的注释中能体现这一点。
但是U-Boot不仅仅支持嵌入式Linu x系统的引导,当前,它还支持NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS嵌入式操作系统。
其目前要支持的目标操作系统是OpenBSD, NetBSD, FreeBSD,4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks, LynxOS, pSOS, QNX, RTEMS, ARTOS。
这是U-Boot中Universal的一层含义,另外一层含义则是U-Boot除了支持PowerPC系列的处理器外,还能支持MIPS、x86、ARM、NIOS、XScale等诸多常用系列的处理器。
这两个特点正是U-Boot项目的开发目标,即支持尽可能多的嵌入式处理器和嵌入式操作系统。
构建MINI2440开发板 Ubuntu linux常见问题

构建MINI2440开发板Ubuntu开发环境-串口配置及使用2012-06-14 10:52:15来源: 作者: 【大中小】浏览:2次评论:0条做嵌入式开发,调试开发板最常使用的工具就是串口和网口,本文主要介绍在Ubuntu系统如何安装和设置串口软件(minicom和kermit)连接MINI2440开发板。
本文假设你已经在电脑上安装了Ubuntu系统。
对于现今大多数的笔记本而言,主板上一般都没有配置接口。
我们可以在网上购买到USB口转串口接口,网上有很多种类型的USB转接口,可以根据价格选择一个合适的就行。
这里使用的是基于PL2303芯片的USB 转接口。
1. 连接MINI2440开发板将USB串口转接器插上开发板和电脑后,在终端上敲dmesg命令,可以查看转接口已经被PC识别,如下图所示:从上图中我们可以看到我们所连接的串口设备是ttyUSB0,可以通过命令ls -l /dev/ttyUSB*来查看相关的信息。
至此,我们已经顺利的将串口连接到Ubuntu系统上了。
这里顺便提起一下,我在Windows下使用USB 转串口时,要先从网上下载一个安装PL-2302 USB Serial Driver,安装该驱动以后,才可以正常使用,而Linux 内核中已经支持PL2303芯片,所以不需要自行安装。
下面就会介绍minicom和kermit的使用。
2. minicom安装及设置Ubuntu系统中默认是没有安装minicom软件,所以我们首先自己需要安装,可以使用apt-get 命令来安装,如下图所示:安装完成以后,我们运行minicom -s命令进行一些初始配置,如下截图:参数的设置如下图所示,这里需要注意的一点是一定要把Hardware Flow Control也设置成None,我开始时就是因为没有设置这一项导致串口一直连不上去。
最后Save setup as dfl并退出,再次输入minicom命令,可以看到已经成功的连到了MINI2440开发板,如下图所示。
Uboot启动流程

U-B o o t启动过程(国嵌)开发板上电后,执行U-Boot的第一条指令,然后顺序执行U-Boot启动函数。
看一下board/smdk2410/u-boot.lds这个链接脚本,可以知道目标程序的各部分链接顺序。
第一个要链接的是cpu/arm920t/start.o,那么U-Boot的入口指令一定位于这个程序中。
下面分两阶段介绍启动流程:第一阶段1.cpu/arm920t/start.S这个汇编程序是U-Boot的入口程序,开头就是复位向量的代码。
_start: b reset //复位向量ldr pc, _undefined_instructionldr pc, _software_interruptldr pc, _prefetch_abortldr pc, _data_abortldr pc, _not_usedldr pc, _irq //中断向量ldr pc, _fiq //中断向量…/* the actual reset code */reset: //复位启动子程序/* 设置CPU为SVC32模式 */mrs r0,cpsrbic r0,r0,#0x1forr r0,r0,#0xd3msr cpsr,r0/* 关闭看门狗 */…… ……relocate: /* 把U-Boot重新定位到RAM */adr r0, _start /* r0是代码的当前位置 */ldr r1, _TEXT_BASE /*_TEXT_BASE是RAM中的地址 */cmp r0, r1 /* 比较r0和r1,判断当前是从Flash启动,还是RAM */ beq stack_setup /* 如果r0等于r1,跳过重定位代码 *//* 准备重新定位代码 */ldr r2, _armboot_startldr r3, _bss_startsub r2, r3, r2 /* r2 得到armboot的大小 */add r2, r0, r2 /* r2 得到要复制代码的末尾地址 */copy_loop: /* 重新定位代码 */ldmia r0!, {r3-r10} /*从源地址[r0]复制 */stmia r1!, {r3-r10} /* 复制到目的地址[r1] */cmp r0, r2 /* 复制数据块直到源数据末尾地址[r2] */ble copy_loop/* 初始化堆栈等 */stack_setup:ldr r0, _TEXT_BASE /* 上面是128 KiB重定位的u-boot */sub r0, r0, #CFG_MALLOC_LEN /* 向下是内存分配空间 */sub r0, r0, #CFG_GBL_DATA_SIZE /* 然后是bdinfo结构体地址空间 */#ifdef CONFIG_USE_IRQsub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)#endifsub sp, r0, #12 /* 为abort-stack预留3个字 */clear_bss:ldr r0, _bss_start /* 找到bss段起始地址 */ldr r1, _bss_end /* bss段末尾地址 */mov r2, #0x00000000 /* 清零 */clbss_l:str r2, [r0]/* bss段地址空间清零循环... */add r0, r0, #4cmp r0, r1bne clbss_l/* 跳转到start_armboot函数入口,_start_armboot字保存函数入口指针 */ldr pc, _start_armboot_start_armboot: .word start_armboot //start_armboot函数在lib_arm/board.c 中实现第二阶段2.lib_arm/board.cstart_armboot是U-Boot执行的第一个C语言函数,完成系统初始化工作,进入主循环,处理用户输入的命令。
J-link V7烧写flash

1. 简要说明JLink的调试功能、烧写Flash的功能都很强大,但是对于S3C2410、S3C2440的Flash操作有些麻烦:烧写Nor Flash时需要设置SDRAM,否则速率很慢;烧写Nand Flash只是从理论上能够达到,但是还没有人直接实现这点。
本文使用一个间接的方法来实现对S3C2410、S3C2440开发板的Nor、Nand Flas h的烧写。
原理为:JLink可以很方便地读写内存、启动程序,那么可以把一个特制的程序下载到开发板上的SDRAM去,并运行它,然后使用这个程序来烧写。
2. 操作步骤2.1 连接硬件对于大多数的S3C2410、S3C2440开发板而言,它们所用的JTAG接口一般有3种(如图1所示),其中前两种用得比较多。
(原文件名:3种jtag.JPG)引用图片但是市面上的JLink,大多只支持第3种JTAG接口,所以需要用到转接板。
或者直接使用JLink的变种,如图2所示的两种改进版JLink:(原文件名:2种jlink.JPG)引用图片以mini2440为例,如图3接好JTAG线。
(原文件名:JLink_2440.jpg)引用图片2.2 运行J-Link commanderJ-Link commander启动界面如图4所示,(如果没有发现检测到CPU,就在里面执行usb命令连接JLink,再执行r命令识别处理器)。
(原文件名:JLINK启动界面.JPG)引用图片2.3 下载运行特制的程序对于S3C2410、S3C2440处理器,它们内部有4K的SRAM,当使用Nor Flash启动时,地址为0x40000000;当使用Nand Flash启动时,地址为0。
对于S3C2410、S3C2440开发板,一般都外接64M的SDRAM。
SDRAM能被使用之前,需要经过初始化。
所以,先把一个init.bin下载到内部SRAM去运行,它执行SDRAM的初始化;然后再下载一个比较大的程序,比如u-boot到SDRAM去动行,它将实现对Nor、N and Flash的操作。
uboot启动流程
U-Boot工作过程U-Boot启动内核的过程可以分为两个阶段,两个阶段的功能如下:(1)第一阶段的功能硬件设备初始化加载U-Boot第二阶段代码到RAM空间设置好栈跳转到第二阶段代码入口(2)第二阶段的功能初始化本阶段使用的硬件设备检测系统内存映射将内核从Flash读取到RAM中为内核设置启动参数调用内核1.1.1 U-Boot启动第一阶段代码分析第一阶段对应的文件是cpu/arm920t/和board/samsung/mini2440/。
U-Boot启动第一阶段流程如下:图 U-Boot启动第一阶段流程根据cpu/arm920t/中指定的连接方式:ENTRY(_start)SECTIONS{. = 0x00000000;. = ALIGN(4);.text :{cpu/arm920t/ (.text)board/samsung/mini2440/ (.text)board/samsung/mini2440/ (.text)*(.text)}… …}第一个链接的是cpu/arm920t/,因此的入口代码在cpu/arm920t/中,其源代码在cpu/arm920t/中。
下面我们来分析cpu/arm920t/的执行。
1. 硬件设备初始化(1)设置异常向量cpu/arm920t/开头有如下的代码:.globl _start_start: b start_code /* 复位*/ldr pc, _undefined_instruction /*未定义指令向量 */ldr pc, _software_interrupt /* 软件中断向量 */ldr pc, _prefetch_abort /* 预取指令异常向量 */ldr pc, _data_abort /* 数据操作异常向量 */ldr pc, _not_used /* 未使用 */ldr pc, _irq /* irq中断向量 */ldr pc, _fiq /* fiq中断向量 */ /* 中断向量表入口地址 */_undefined_instruction: .word undefined_instruction_software_interrupt: .word software_interrupt_prefetch_abort: .word prefetch_abort_data_abort: .word data_abort_not_used: .word not_used_irq: .word irq_fiq: .word fiq.balignl 16,0xdeadbeef以上代码设置了ARM异常向量表,各个异常向量介绍如下:表 ARM异常向量表在cpu/arm920t/中还有这些异常对应的异常处理程序。
uboot 命令详解
u-boot 技术文档1.U boot 命令详解1.1查看帮助命令使用help 或者?1.2环境变量打印环境变量:printenv设置环境变量:setenv(不会保存)保存环境变量:saveenv这个时候就有了1.3nandflash命令使用nand查看nandflash 所有指令擦除nand erase1.4norflash命令查看Flash信息命令: flinfo加/解写保护命令: protect擦除命令: erase1.5内存命令nm1.5USB指令使用help usb 查看usb具体指令使用usb 启动使用usb tree查看信息f atls usb 0 罗列u盘信息1.5.1实例演练usb指令烧写1.6实例演练ftp指令烧写环境变量中体现了开发板上的IP地址为192.168.0.2,网关为192.168.0.1,要求电上的tftp 服务器的IP为192.168.0.1;运行电脑上tftp服务器,指定好根目录,将内核和根文件系统放在根目录下。
注:线接上后,电脑上的本地连接可能是显示网络电缆没插好,这很正常!在使用过程中它们会自动去连接!<2>分别下载内核和根文件系统到内存0x30008000开始的空间先检查坏块nand bad再擦除坏块清理某个区域0x560000 0x3b22c00将根文件系统加载到0x30008000然后再将根文件系统写到0x560000 0x3b22c00这个位置然后重启:重复上面的步骤:nand erase 0x60000 0x267000将内核文件保存到0x60000 0x267000这块区域运行1.8系统重启指令2.U boot 内核移植在cpu/arm920t/start.S中添加以下代码在修改并添加为以下代码在include/configs/mini2440.h修改为如下:将以下代码修改为:将以下代码修改为:将以下代码修改为:在drivers/mtd/nand/s3c2410_nand.h 在最后下面代码上添加如下带码:。
mini 2440启动代码1
上接mini2440开发板中启动代码2440INIT.S分析(1);配置UPLL ;//Configure UPLL Fin=12.0MHz UFout=48MHzldr r0,=UPLLCONldr r1,=((U_MDIV<<12)+(U_PDIV<<4)+U_SDIV)str r1,[r0]nop ; Caution: After UPLL setting, at least 7-clocksnop ; delay must be inserted for setting hardware be completed.nopnopnopnopnop;配置MPLL;//Configure MPLL Fin=12.0MHz MFout=304.8MHz一定要使最后的频率为16.9344MHz,不然你甭想用USB接口了ldr r0,=MPLLCONldr r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV)str r1,[r0]];检查是否从SLEEP模式中恢复ldr r1,=GSTATUS2ldr r0,[r1]tst r0,#0x2;如果是从SLEEP模式中恢复, 转跳到SLEEP_WAKEUP.bne WAKEUP_SLEEPEXPORT StartPointAfterSleepWakeUp ;导出符号StartPointAfterSleepWakeUp StartPointAfterSleepWakeUp;===================================================================== ==========;设置内存控制器等寄存器的值,因为这些寄存器是连续排列的,所以采用如下办法对这些;寄存器进行连续设置.其中用到了SMRDA TA的数据,这在代码后面有定义;===================================================================== ==========;ldr r0,=SMRDATAadrl r0, SMRDATA ;be careful!, hzhldr r1,=BWSCON ;BWSCON 地址add r2, r0, #52 ; SMRDATA数据的结束地址,共有52字节的数据ldr r3, [r0], #4str r3, [r1], #4cmp r2, r0bne %B0;===================================================================== ===========;如果EINT0 产生(这中断就是我们按键产生的), 就清除SDRAM ,不过好像没人会在这个时候按;===================================================================== ===========; check if EIN0 button is pressedldr r0,=GPFCONldr r1,=0x0str r1,[r0]ldr r0,=GPFUPldr r1,=0xffstr r1,[r0]ldr r1,=GPFDATldr r0,[r1]bic r0,r0,#(0x1e<<1) ; bit cleartst r0,#0x1bne %F1 ;如果没有按,就跳到后面的1标号处; 这就是清零内存的代码ldr r0,=GPFCONldr r1,=0x55aastr r1,[r0]; ldr r0,=GPFUP; ldr r1,=0xff; str r1,[r0]ldr r0,=GPFDATldr r1,=0x0str r1,[r0] ;LED=****mov r1,#0mov r2,#0mov r3,#0mov r4,#0mov r5,#0mov r6,#0mov r7,#0mov r8,#0ldr r9,=0x4000000 ;64MBldr r0,=0x30000000stmia r0!,{r1-r8}subs r9,r9,#32bne %B0;到这就结束了.1bl InitStacks ;初始化堆栈;bl Led_Test ;又是LED,注掉了;===================================================================== ==; 哈哈,下面又有看头了,这个初始化程序好像被名曰hzh的高手改过; 能在NOR NAND 还有内存中运行,当然了,在内存中运行最简单了.; 在NOR NAND中运行的话都要先把自己拷到内存中.; 此外,还记得上面提到的|Image$$RO$$Base|,|Image$$RO$$Limit|...吗?; 这就是拷贝的依据了!!!;===================================================================== ====ldr r0, =BWSCONldr r0, [r0]ands r0, r0, #6 ;OM[1:0] != 0, 从NOR FLash启动或直接在内存运行bne copy_proc_beg ;不读取NAND FLASHadr r0, ResetEntry ;OM[1:0] == 0, 为从NAND FLash启动cmp r0, #0 ;再比较入口是否为0地址处;===================================================================== =====;如果不是,则表示主板设置了从NAND启动,但这个程序由于其它原因,;并没有从NAND启动,这种情况最有可能的原因就是用仿真器.;===================================================================== =====bne copy_proc_beg ;这种情况也不读取NAND FLASH.;nop ;如果是0才是真正从NAND 启动,因为其4k 被复制到0地址开始的stepingstone 内部sram中; 注意adr得到的是相对地址,非绝对地址== if use Multi-ice,;===========================================================nand_boot_beg ;这一段代码完成从NAND读代码到RAM mov r5, #NFCONF ;首先设定NAND的一些控制寄存器;set timing valueldr r0, =(7<<12)|(7<<8)|(7<<4)str r0, [r5];enable controlldr r0, =(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0)str r0, [r5, #4]bl ReadNandID ;按着读取NAND的ID号,结果保存在r5里mov r6, #0 ;r6设初值0.ldr r0, =0xec73 ;期望的NAND ID号cmp r5, r0 ;这里进行比较beq %F1 ;相等的话就跳到下一个1标号处ldr r0, =0xec75 ;这是另一个期望值cmp r5, r0beq %F1 ;相等的话就跳到下一个1标号处mov r6, #1 ;不相等了,设置r6=1.1bl ReadNandStatus ;读取NAND状态,结果放在r1里mov r8, #0 ;r8设初值0,意义为页号ldr r9, =ResetEntry ;r9设初值为初始化程序入口地址;===================================================================== ====; 注意,在这里使用的是ldr伪指令,而不是上面用的adr伪指令,它加载的是ResetEntry; 的决对地址,也就是我们期望的RAM中的地址,在这里,它和|Image$$RO$$Base|一样; 也就是说,我如我们编译程序时RO BASE指定的地址在RAM里,而把生成的文件拷到; NAND里运行,由ldr加载的r9的值还是定位在内存.;===================================================================== ====2ands r0, r8, #0x1f ;凡r8为0x1f(32)的整数倍-1,eq有效,ne无效bne %F3 ;这句的意思是对每个块(32页)进行检错mov r0, r8 ;r8->r0bl CheckBadBlk ;检查NAND的坏区cmp r0, #0 ;比较r0和0addne r8, r8, #32 ;存在坏块的话就跳过这个坏块bne %F4 ;没有的话就跳到标号4处3mov r0, r8 ;当前页号->r0mov r1, r9 ;当前目标地址->r1bl ReadNandPage ;读取该页的NAND数据到RAMadd r9, r9, #512 ;每一页的大小是512Bytesadd r8, r8, #1 ;r8指向下一页4cmp r8, #256 ;比较是否读完256页即128KBytesbcc %B2 ;如果r8小于256(没读完),就返回前面的标号2处mov r5, #NFCONF ;DsNandFlashldr r0, [r5, #4]bic r0, r0, #1str r0, [r5, #4]ldr pc, =copy_proc_beg ;调用copy_proc_beg;===========================================================copy_proc_begadr r0, ResetEntry ;ResetEntry值->r0ldr r2, BaseOfROM ;BaseOfROM值(后面有定义)->r2cmp r0, r2 ;比较r0和r2ldreq r0, TopOfROM ;如果相等的话(在内存运行),TopOfROM->r0beq InitRam ;同时跳到InitRam;=========================================================;下面这个是针对代码在NOR FLASH时的拷贝方法;功能为把从ResetEntry起,TopOfROM-BaseOfROM大小的数据拷到BaseOfROM;TopOfROM和BaseOfROM为|Image$$RO$$Limit|和|Image$$RO$$Base|;|Image$$RO$$Limit|和|Image$$RO$$Base|由连接器生成;为生成的代码的代码段运行时的起启和终止地址;BaseOfBSS和BaseOfZero为|Image$$RW$$Base|和|Image$$ZI$$Base|;|Image$$RW$$Base|和|Image$$ZI$$Base|也是由连接器生成;两者之间就是初始化数据的存放地放;=======================================================ldr r3, TopOfROMldmia r0!, {r4-r7}stmia r2!, {r4-r7}cmp r2, r3bcc %B0sub r2, r2, r3 ;r2=BaseOfROM-TopOfROM=(-)代码长度sub r0, r0, r2 ;r0=ResetEntry-(-)代码长度=ResetEntry+代码长度InitRamldr r2, BaseOfBSS ;BaseOfBSS->r2ldr r3, BaseOfZero ;BaseOfZero->r3cmp r2, r3 ;比较BaseOfBSS和BaseOfZeroldrcc r1, [r0], #4 ;要是r21 ; means Fclk:Hclk is not 1:1.; bl MMU_SetAsyncBusMode; |; bl MMU_SetFastBusMode ; default value.; ];bl Led_Test;===========================================================; 进入C语言前的最后一步了,就是把我们用说查二级向量表; 的中断例程安装到一级向量表(异常向量表)里.ldr r0,=HandleIRQ ;This routine is neededldr r1,=IsrIRQ ;if there is not 'subs pc,lr,#4' at 0x18, 0x1cstr r1,[r0]; ;Copy and paste RW data/zero initialized data; ldr r0, =|Image$$RO$$Limit| ; Get pointer to ROM data; ldr r1, =|Image$$RW$$Base| ; and RAM copy; ldr r3, =|Image$$ZI$$Base|;; ;Zero init base => top of initialised data; cmp r0, r1 ; Check that they are different; beq %F2;1; cmp r1, r3 ; Copy init data; ldrcc r2, [r0], #4 ;--> LDRCC r2, [r0] + ADD r0, r0, #4; strcc r2, [r1], #4 ;--> STRCC r2, [r1] + ADD r1, r1, #4; bcc %B1;2; ldr r1, =|Image$$ZI$$Limit| ; Top of zero init segment; mov r2, #0;3; cmp r3, r1 ; Zero init; strcc r2, [r3], #4; bcc %B3;*****************************************************************************;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!; 妈呀,终说见到艳阳天了!!!!!!!!!!; 跳到C语言的main函数处了.;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;***************************************************************************** [ :LNOT:THUMBCODEbl Main ;Do not use main() because ......;ldr pc, =Main ;hzhb .][ THUMBCODE ;for start-up code for Thumb modeorr lr,pc,#1bx lrCODE16bl Main ;Do not use main() because ......b .CODE32]; initializing stacksInitStacks;Do not use DRAM,such as stmfd,ldmfd......;SVCstack is initialized before;Under toolkit ver 2.5, 'msr cpsr,r1' can be used instead of 'msr cpsr_cxsf,r1'mrs r0,cpsrbic r0,r0,#MODEMASKorr r1,r0,#UNDEFMODE|NOINTmsr cpsr_cxsf,r1 ;UndefModeldr sp,=UndefStack ; UndefStack=0x33FF_5C00orr r1,r0,#ABORTMODE|NOINTmsr cpsr_cxsf,r1 ;AbortModeldr sp,=AbortStack ; AbortStack=0x33FF_6000orr r1,r0,#IRQMODE|NOINTmsr cpsr_cxsf,r1 ;IRQModeldr sp,=IRQStack ; IRQStack=0x33FF_7000orr r1,r0,#FIQMODE|NOINTmsr cpsr_cxsf,r1 ;FIQModeldr sp,=FIQStack ; FIQStack=0x33FF_8000bic r0,r0,#MODEMASK|NOINTorr r1,r0,#SVCMODEmsr cpsr_cxsf,r1 ;SVCModeldr sp,=SVCStack ; SVCStack=0x33FF_5800;USER mode has not be initialized.mov pc,lr;The LR register will not be valid if the current mode is not SVC mode.;=========================================================== ReadNandIDmov r7,#NFCONFldr r0,[r7,#4] ;NFChipEn();bic r0,r0,#2str r0,[r7,#4]mov r0,#0x90 ;WrNFCmd(RdIDCMD);strb r0,[r7,#8]mov r4,#0 ;WrNFAddr(0);strb r4,[r7,#0xc]1 ;while(NFIsBusy());ldr r0,[r7,#0x20]tst r0,#1beq %B1ldrb r0,[r7,#0x10] ;id = RdNFDat()<<8;mov r0,r0,lsl #8ldrb r1,[r7,#0x10] ;id |= RdNFDat();orr r5,r1,r0ldr r0,[r7,#4] ;NFChipDs();orr r0,r0,#2str r0,[r7,#4]mov pc,lrReadNandStatusmov r7,#NFCONFldr r0,[r7,#4] ;NFChipEn();bic r0,r0,#2str r0,[r7,#4]mov r0,#0x70 ;WrNFCmd(QUERYCMD);strb r0,[r7,#8]ldrb r1,[r7,#0x10] ;r1 = RdNFDat();ldr r0,[r7,#4] ;NFChipDs();orr r0,r0,#2str r0,[r7,#4]mov pc,lrWaitNandBusymov r0,#0x70 ;WrNFCmd(QUERYCMD);mov r1,#NFCONFstrb r0,[r1,#8]1 ;while(!(RdNFDat()&0x40));ldrb r0,[r1,#0x10]tst r0,#0x40beq %B1mov r0,#0 ;WrNFCmd(READCMD0);strb r0,[r1,#8]mov pc,lrCheckBadBlkmov r7, lrmov r5, #NFCONFbic r0,r0,#0x1f ;addr &= ~0x1f;ldr r1,[r5,#4] ;NFChipEn()bic r1,r1,#2str r1,[r5,#4]mov r1,#0x50 ;WrNFCmd(READCMD2)strb r1,[r5,#8]mov r1, #5;6 ;6->5strb r1,[r5,#0xc] ;WrNFAddr(5);(6) 6->5strb r0,[r5,#0xc] ;WrNFAddr(addr)mov r1,r0,lsr #8 ;WrNFAddr(addr>>8)strb r1,[r5,#0xc]cmp r6,#0 ;if(NandAddr)movne r0,r0,lsr #16 ;WrNFAddr(addr>>16)strneb r0,[r5,#0xc]; bl WaitNandBusy ;WaitNFBusy();do not use WaitNandBusy, after WaitNandBusy will read part A! mov r0, #1001subs r0, r0, #1bne %B12ldr r0, [r5, #0x20]tst r0, #1beq %B2ldrb r0, [r5,#0x10] ;RdNFDat()sub r0, r0, #0xffmov r1,#0 ;WrNFCmd(READCMD0) strb r1,[r5,#8]ldr r1,[r5,#4] ;NFChipDs()orr r1,r1,#2str r1,[r5,#4]mov pc, r7ReadNandPagemov r7,lrmov r4,r1mov r5,#NFCONFldr r1,[r5,#4] ;NFChipEn()bic r1,r1,#2str r1,[r5,#4]mov r1,#0 ;WrNFCmd(READCMD0) strb r1,[r5,#8]strb r1,[r5,#0xc] ;WrNFAddr(0)strb r0,[r5,#0xc] ;WrNFAddr(addr)mov r1,r0,lsr #8 ;WrNFAddr(addr>>8) strb r1,[r5,#0xc]cmp r6,#0 ;if(NandAddr)movne r0,r0,lsr #16 ;WrNFAddr(addr>>16) strneb r0,[r5,#0xc]ldr r0,[r5,#4] ;InitEcc()orr r0,r0,#0x10str r0,[r5,#4]bl WaitNandBusy ;WaitNFBusy()mov r0,#0 ;for(i=0; i<512; i++)1ldrb r1,[r5,#0x10] ;buf[i] = RdNFDat() strb r1,[r4,r0]add r0,r0,#1bic r0,r0,#0x10000cmp r0,#0x200bcc %B1ldr r0,[r5,#4] ;NFChipDs()orr r0,r0,#2str r0,[r5,#4]mov pc,r7;--------------------LED testEXPORT Led_TestLed_Testmov r0, #0x56000000mov r1, #0x5500str r1, [r0, #0x50]mov r1, #0x50str r1, [r0, #0x54]mov r2, #0x1000001subs r2, r2, #1bne %B1mov r1, #0xa0str r1, [r0, #0x54]mov r2, #0x1000002subs r2, r2, #1bne %B2b %B0mov pc, lr;=========================================================== LTORG;GCS0->SST39VF1601;GCS1->16c550;GCS2->IDE;GCS3->CS8900;GCS4->DM9000;GCS5->CF Card;GCS6->SDRAM;GCS7->unusedSMRDA TA DATA; Memory configuration should be optimized for best performance; The following parameter is not optimized.; Memory access cycle parameter strategy; 1) The memory settings is safe parameters even at HCLK=75Mhz.; 2) SDRAM refresh period is for HCLK<=75Mhz.DCD(0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5 _BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))DCD((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+ (B0_PMC)) ;GCS0DCD((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+ (B1_PMC)) ;GCS1DCD((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+ (B2_PMC)) ;GCS2DCD((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+ (B3_PMC)) ;GCS3DCD((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+ (B4_PMC)) ;GCS4DCD((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+ (B5_PMC)) ;GCS5DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) ;GCS6DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) ;GCS7DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Tsrc<<18)+(Tchr<<16)+REFCNT)DCD 0x32 ;SCLK power saving mode, BANKSIZE 128M/128MDCD 0x30 ;MRSR6 CL=3clkDCD 0x30 ;MRSR7 CL=3clkBaseOfROM DCD |Image$$RO$$Base|TopOfROM DCD |Image$$RO$$Limit|BaseOfBSS DCD |Image$$RW$$Base|BaseOfZero DCD |Image$$ZI$$Base|EndOfBSS DCD |Image$$ZI$$Limit|ALIGN; for entering power down mode; 1. SDRAM should be in self-refresh mode.; 2. All interrupt should be maksked for SDRAM/DRAM self-refresh.; 3. LCD controller should be disabled for SDRAM/DRAM self-refresh.; 4. The I-cache may have to be turned on.; 5. The location of the following code may have not to be changed.;void EnterPWDN(int CLKCON);EnterPWDNmov r2,r0 ;r2=rCLKCONtst r0,#0x8 ;SLEEP mode?bne ENTER_SLEEPENTER_STOPldr r0,=REFRESHldr r3,[r0] ;r3=rREFRESHmov r1, r3orr r1, r1, #BIT_SELFREFRESHstr r1, [r0] ;Enable SDRAM self-refreshmov r1,#16 ;wait until self-refresh is issued. may not be needed.0 subs r1,r1,#1bne %B0ldr r0,=CLKCON ;enter STOP mode.str r2,[r0]mov r1,#320 subs r1,r1,#1 ;1) wait until the STOP mode is in effect.bne %B0 ;2) Or wait here until the CPU&Peripherals will be turned-off; Entering SLEEP mode, only the reset by wake-up is available.ldr r0,=REFRESH ;exit from SDRAM self refresh mode.str r3,[r0]MOV_PC_LRENTER_SLEEP;NOTE.;1) rGSTATUS3 should have the return address after wake-up from SLEEP mode. ldr r0,=REFRESHldr r1,[r0] ;r1=rREFRESHorr r1, r1, #BIT_SELFREFRESHstr r1, [r0] ;Enable SDRAM self-refreshmov r1,#16 ;Wait until self-refresh is issued,which may not be needed.0 subs r1,r1,#1bne %B0ldr r1,=MISCCRldr r0,[r1]orr r0,r0,#(7<<17) ;Set SCLK0=0, SCLK1=0, SCKE=0.str r0,[r1]ldr r0,=CLKCON ; Enter sleep modestr r2,[r0]b . ;CPU will die here.WAKEUP_SLEEP;Release SCLKn after wake-up from the SLEEP mode.ldr r1,=MISCCRldr r0,[r1]bic r0,r0,#(7<<17) ;SCLK0:0->SCLK, SCLK1:0->SCLK, SCKE:0->=SCKE. str r0,[r1];Set memory control registersldr r0,=SMRDATA ;be careful!, hzhldr r1,=BWSCON ;BWSCON Addressadd r2, r0, #52 ;End address of SMRDATAldr r3, [r0], #4str r3, [r1], #4cmp r2, r0bne %B0mov r1,#2560 subs r1,r1,#1 ;1) wait until the SelfRefresh is released.bne %B0ldr r1,=GSTATUS3 ;GSTA TUS3 has the start address just after SLEEP wake-up ldr r0,[r1]mov pc,r0;===================================================================== ; Clock division test; Assemble code, because VSYNC time is very short;===================================================================== EXPORT CLKDIV124EXPORT CLKDIV144CLKDIV124ldr r0, = CLKDIVNldr r1, = 0x3 ; 0x3 = 1:2:4str r1, [r0]; wait until clock is stablenopnopnopnopnopldr r0, = REFRESHldr r1, [r0]bic r1, r1, #0xffbic r1, r1, #(0x7<<8)orr r1, r1, #0x470 ; REFCNT135str r1, [r0]nopnopnopnopnopmov pc, lrCLKDIV144ldr r0, = CLKDIVNldr r1, = 0x4 ; 0x4 = 1:4:4str r1, [r0]; wait until clock is stablenopnopnopnopnopldr r0, = REFRESHldr r1, [r0]bic r1, r1, #0xffbic r1, r1, #(0x7<<8)orr r1, r1, #0x630 ; REFCNT675 - 1520str r1, [r0]nopnopnopnopnopmov pc, lrALIGNAREA RamData, DATA, READWRITE^ _ISR_STARTADDRESS ; _ISR_STARTADDRESS=0x33FF_FF00 HandleReset # 4HandleUndef # 4HandleSWI # 4HandlePabort # 4HandleDabort # 4HandleReserved # 4HandleIRQ # 4HandleFIQ # 4;Do not use the label 'IntVectorTable',;The value of IntVectorTable is different with the address you think it may be. ;IntVectorTable;@0x33FF_FF20HandleEINT0 # 4HandleEINT1 # 4HandleEINT2 # 4HandleEINT3 # 4HandleEINT4_7 # 4HandleEINT8_23 # 4HandleCAM # 4 ; Added for 2440.HandleBATFLT # 4HandleTICK # 4HandleWDT # 4HandleTIMER0 # 4HandleTIMER1 # 4HandleTIMER2 # 4HandleTIMER3 # 4HandleTIMER4 # 4HandleUART2 # 4;@0x33FF_FF60HandleLCD # 4HandleDMA0 # 4HandleDMA1 # 4HandleDMA2 # 4HandleDMA3 # 4HandleMMC # 4HandleSPI0 # 4HandleUART1 # 4HandleNFCON # 4 ; Added for 2440. HandleUSBD # 4HandleUSBH # 4HandleIIC # 4HandleUART0 # 4HandleSPI1 # 4HandleRTC # 4HandleADC # 4;@0x33FF_FFA0END。
uboot2009移植
嵌入式Linux之我行——u-boot-2009.08在2440上的移植详解(一)(2009-11-27 10:46)分类:Bootloader移植篇嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。
一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便。
如有错误之处,谢请指正。
共享资源,欢迎转载:一、移植环境主机:VMWare--Fedora 9开发板:Mini2440--64MB Nand,Kernel:2.6.30.4编译器:arm-linux-gcc-4.3.2.tgzu-boot:u-boot-2009.08.tar.bz2二、移植步骤本次移植的功能特点包括:支持Nand Flash读写支持从Nor/Nand Flash启动支持CS8900或者DM9000网卡支持Yaffs文件系统支持USB下载(还未实现)1.了解u-boot主要的目录结构和启动流程,如下图。
u-boot的stage1代码通常放在cpu/xxxx/start.S文件中,他用汇编语言写成;u-boot的stage2代码通常放在lib_xxxx/board.c文件中,他用C语言写成。
各个部分的流程图如下:2. 建立自己的开发板项目并测试编译。
目前u-boot对很多CPU直接支持,可以查看board目录的一些子目录,如:board/samsung/目录下就是对三星一些ARM处理器的支持,有smdk2400、smdk2410和smdk6400,但没有2440,所以我们就在这里建立自己的开发板项目。
1)因2440和2410的资源差不多,主频和外设有点差别,所以我们就在board/samsung/下建立自己开发板的项目,取名叫my2440#tar -jxvf u-boot-2009.08.tar.bz2 //解压源码#cd u-boot-2009.08/board/samsung/ //进入目录#mkdir my2440 //创建my2440文件夹2)因2440和2410的资源差不多,所以就以2410项目的代码作为模板,以后再修改#cp -rf smdk2410/* my2440/ //将2410下所有的代码复制到2440下#cd my2440 //进入my2440目录#mv smdk2410.c my2440.c //将my2440下的smdk2410.c改名为my2440.c#cd ../../../ //回到u-boot根目录#cp include/configs/smdk2410.h include/configs/my2440.h//建立2440头文件#gedit board/samsung/my2440/Makefile //修改my2440下Makefile的编译项,如下:COBJS :=my2440.o flash.o //因在my2440下我们将smdk2410.c改名为my2440.c3)修改u-boot跟目录下的Makefile文件。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
mini2440使用uboot(详细)文章出处:/swgshj/archive/2010/04/20/5502121.aspx文章写于2010.4.17,总结了友善之臂的mini2440开发板使用自带uboot的具体方法,希望能对正在使用mini2440开发板,而且又想使用uboot引导系统的朋友们有所帮助。
Google一下会发现网上类似的帖子不少,但是对mini2440开发板是哪一个版本都没有具体的说明,个人感觉mini2440开发板的版本是经常更新的,可能不同的版本的开发板在移植uboot时会稍有不同,因此这里我把自己使用的开发板的详细信息都罗列一下,希望网友少走弯路。
另外,要感谢illidan和Martin两位的文章:/2009/05/mini2440使用u-boot//bbs/viewthread.php?tid=14使用的mini2440开发板的详细信息:kernel:linux-2.6.29-mini2440-20090708.tgzgcc:arm-linux-gcc-4.3.2.tgzuboot:bootloader.tgz(该压缩包内含有u-boot-1.1.6)roots:root_qtopia-64M.img问题源于:(1)使用128M NAND Flash mini2440开发板的用户都知道,此时开发板附带的supervivi-64M和supervivi-128M都不再支持“空格”进入supervivi的menu菜单,而是改成了使用开发板上的k1~k6任何一个按键触发进入menu(而我需要空格键触发menu的方式);(2)开发板附带的supervivi不支持网络下载kernel和root(文件系统)。
具体的修改步骤如下:注1:arm-linux-gcc的安装方法见《mini2440-um-20090817.pdf》第5.3小节。
注2:mini2440开发板附带的uboot源码已经是经过移植的,适用s3c2440处理器,我们只需要修改一些uboot参数即可。
一、修改uboot源码(1)解压出源码创建工作目录mkdir /tmp/workspacecd /tmp/workspace解压mini2440开发板光盘附带的uboot源码,bootloader.tgz同时包含了u-boot-1.1.6和vivi 的源码tar -xvf bootloader.tgzcd u-boot-1.1.6(2)修改u-boot-1.1.6/include/configs/open24x0.h文件修改NAND FLASH MTD分区表:56 /*57 #define MTDPARTS_DEFAULT "mtdparts=nandflash0:2m@0(kernel)," \58 "8m(jffs2)," \59 "-(yaffs)"60 */61 #define MTDPARTS_DEFAULT "mtdparts=nandflash0:" \62 "256k@0(boot)," \63 "64k(env)," \64 "2m(kernel)," \65 "-(yaffs)"注:该分区表一定要与内核中的分区表一致,后面我会给出kernel中分区表的修改。
修改内核启动参数:把“mtdblock2”改为“mtdblock3”133 //#define CONFIG_BOOTARGS "noinitrd root=/dev/mtdblock2init=/linuxrc console=ttySAC0"134 #define CONFIG_BOOTARGS "noinitrd root=/dev/mtdblock3init=/linuxrc console=ttySAC0"注:此处一定要改,否则文件系统会加载失败(此处是让我最痛苦的地方,费了大量时间才找到这个症结所在)修改env参数保存位置:221 //#define CFG_ENV_IS_IN_FLASH 1222 #define CFG_ENV_IS_IN_NAND 1223 #define CFG_ENV_OFFSET 0x40000224 #define CFG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */注1:env是uboot引导系统时用到的一系列参数,是可修改的,如果不改动此处,env修改后,即使执行saveenv命令,断电后也会丢失。
注2:注意一下223和224行,这两行定义了env保存在nand flash的具体位置,与MTD 分区表中的"64k(env)," 是对应的(64K=0x40000 - 0x10000)。
(3)修改u-boot-1.1.6/include/asm-arm/mach-types.h文件修改machine ID377 //#define MACH_TYPE_S3C2440 362378 #define MACH_TYPE_S3C2440 1999注1:查看linux-2.6.29/include/asm/mach-types.h会发现machine ID为19991985 #define MACH_TYPE_MINI2440 1999注2:对于此处的修改Martin给出了他的经验:“查看u-boot-1.1.6/board/open24×0/open24×0.c与linux-2.6.29/include/asm/mach-types.h,发现Machine ID果然设置的不对。
mini2440的ID是1999,而u-boot中设置的是三星官方的362。
改完,刷写,重启。
依然不灵。
这就有点土了。
没有仿真器,没有打印信息,我和mini2440之间又不能通过脑电波交流…冥思苦想中,我进入了准无意识状态,大脑在迷惘,手指在不停地用NOR或者NAND启动mini2440。
突然,我感到有什么东西不对。
隐隐约约的,我似乎看到了什么东西,不应该出现的东西。
定定神,一行一行地翻看串口console日志,貌似每一行都很正常,但最后我停在了SuperVIVI启动的一行语句上面:”Machine ID: 782″。
782?为什么会是782?我grep了一下linux-2.6.29/include/asm/mach-types.h,782是MACH_TYPE_PNX4008。
先不想那么多,改成782试试。
改完,刷写,重启。
Kernel成功启动了。
回过头研究782,不由哑然失笑。
原来是这个linux-2.6.29移植的有点潦草,defconfig中的宏定义前后不一致,使得Machine ID没有设置为预想的值。
好吧,这个问题就留在这里吧,也是一种不和谐美。
”注3:Martin用的可能是较老的mini2440开发板,我这一版已经解决了他提的这个问题,如果跟我的kernel一样,应该改为1999。
(4)修改uboot功能菜单,增加tftp下载功能选项修改u-boot-1.1.6/common/cmd_menu.c文件,在原文件中添加146~149行:142 void main_menu_usage(void)143 {144 printf("\r\n##### uboot for mini2440 #####\r\n");145146 printf("[1] TFTP Install U-boot\r\n");147 printf("[2] TFTP Install Linux kernel\r\n");148 printf("[3] TFTP Install JFFS2 root\r\n");149 printf("[4] TFTP Install YAFFS root\r\n");150 printf(" Download u-boot\r\n");151152 #ifdef CONFIG_SURPORT_WINCE153 printf("[e] Download Eboot\r\n");154 #endif155 printf("[k] Download Linux kernel\r\n");156 #ifdef CONFIG_SURPORT_WINCE157 printf("[w] Download WinCE NK.bin\r\n");158 #endif159 printf("[j] Download JFFS2 image\r\n");160 printf("[y] Download Y AFFS image\r\n");161 printf("[d] Download to SDRAM & Run\r\n");162 printf(" Boot the system\r\n");163 printf("[f] Format the Nand Flash\r\n");164 printf("[s] Set the boot parameters\r\n");165 printf("[r] Reboot u-boot\r\n");166 printf("[q] Quit from menu\r\n");167 printf("Enter your selection: ");168 }在原文件menu_shell函数中添加200~235行171 void menu_shell(void)172 {173 char c;174 char cmd_buf[200];175 char *p = NULL;176 unsigned long size;177 unsigned long offset;178 struct mtd_info *mtd = &nand_info[nand_curr_device];179180 while (1)181 {182 main_menu_usage();183 c = awaitkey(-1, NULL);184 printf("%c\n", c);185 switch (c)186 {187 case 'u':188 {189 if (bBootFrmNORFlash())190 {191 strcpy(cmd_buf, "usbslave 1 0x30000000; protect off all; erase 0 +$(filesize); cp.b 0x30000000 0 $(filesize)");192 }193 else194 {195 strcpy(cmd_buf, "usbslave 1 0x30000000; nand erase bios; nand write.jffs2 0x30000000 bios $(filesize)");196 }197 run_command(cmd_buf, 0);198 break;199 }200 case '1':201 {202 if (bBootFrmNORFlash())203 {204 strcpy(cmd_buf, "tftp 0x30000000 u-boot.bin; protect off all; erase 0 +$(filesize); cp.b 0x30000000 0 $(filesize)");205 }206 else207 {208 strcpy(cmd_buf, "tftp 0x30000000 u-boot.bin; nand erase boot; nand write.jffs2 0x30000000 boot $(filesize)");209 }210 run_command(cmd_buf, 0);211 break;212 }213 case '2':214 {215 strcpy(cmd_buf, "tftp 0x30000000 uImage; nand erase kernel; nand write.jffs2 0x30000000 kernel $(filesize)");216 run_command(cmd_buf, 0);217 #ifdef CONFIG_SURPORT_WINCE218 if (!TOC_Read())219 TOC_Erase();220 #endif221 break;222 }223 case '3':224 {225 strcpy(cmd_buf, "tftp 0x30000000 rootfs.jffs2; nand erase jffs2; nand write.jffs2 0x30000000 jffs2 $(filesize)");226 run_command(cmd_buf, 0);227 break;228 }229230 case '4':231 {232 strcpy(cmd_buf, "tftp 0x30000000 rootfs.yaffs; nand erase yaffs; nand write.yaffs 0x30000000 yaffs $(filesize)");233 run_command(cmd_buf, 0);234 break;235 }236237 #ifdef CONFIG_SURPORT_WINCE238 case 'e':239 {240 offset = EBOOT_BLOCK * mtd->erasesize;241 size = EBOOT_BLOCK_SIZE * mtd->erasesize;242 sprintf(cmd_buf, "nand erase 0x%x 0x%x; usbslave 1 0x30000000; nand write 0x30000000 0x%x $(filesize)", offset, size, offset);243 run_command(cmd_buf, 0);244 break;245 }246 #endif247248 case 'k':249 {250 strcpy(cmd_buf, "usbslave 1 0x30000000; nand erase kernel; nand write.jffs2 0x30000000 kernel $(filesize)");251 run_command(cmd_buf, 0);252 #ifdef CONFIG_SURPORT_WINCE253 if (!TOC_Read())254 TOC_Erase();255 #endif256 break;257 }(5)重新编译cd /tmp/workspace/u-boot-1.1.6make cleanmake distcleanmake编译完成后会在tmp/workspace/u-boot-1.1.6目录下发现u-boot.bin文件,即是我们需要的uboot镜像文件。