还剩27页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
u-boot-
1.
3.4移植到S3C2440(带有某些解析)移植u-boot-
1.
3.4到S3C2440一.预备知识
1.首先,U-Boot
1.
3.4还没有支持s3c2440,移植仍是用2410的文件稍作修改而成的
2.2440和2410的区别2440和2410的区别主要是2440的主频更高,增加了摄像头接口和AC‘97音频接口;寄存器方面,除了新增模块的寄存器外,移植所要注意的是NANDFlASH控制器的寄存器有较大的变化、芯片的时钟频率控制寄存器(芯片PLL的寄存器)有一定的变化其他寄存器基本是兼容的
3.你__板的boot方式是什么,__板上电以后是怎么执行的一般来说三星的__板有三种启动方式nand、nor、ram具体用那一种方式来启动决定于CPU的0M[0:1]这两个引脚,具体请参考S3C2440的datasheetnand对于2440来说,CPU是不给nand-flash分配地址空间的,nand-flash只相当于CPU的一个外设,S3C2440做了一个从nand-flash启动的机制__板一上电,CPU就自动__nand-flash里面的前4K-Bytes内容到S3C2440内部集成的SDRAM,然后把4K内容所在的RAM映射到S3C2440的0地址,从0地址开始执行这4K的内容主要负责下面这些工作初始化中断矢量、设定CPU的工作模式为SVC32模式、屏蔽看门狗、屏蔽中断、初始化时钟、把整个u-boot重定向到外部SDRAM、跳到主要的C函数入口nor:早期的时候利用nor-flash启动的方式比较多,就是把u-boot烧写到nor-flash里面,直接把nor-flash映射到S3C2440的0地址,上电从0地址开始执行ram:直接把u-boot放到外部SDRAM上跑,这一般debug时候用到
4.u-boot程序的入口地址问题要理解程序的入口地址,自然想到的是连接文件,首先看看__板相对于某个__板的连接文件/board/你的__板/u-boot.lds看一个2410的例子ENTRY_startSECTIONS{.=0x00000000;.=ALIGN4;.text:{cpu/ar__20t/start.o.text*.text}.=ALIGN4;.rodata:{*.rodata}.=ALIGN4;.data:{*.data}.=ALIGN4;.got:{*.got}__u_boot_cmd_start=.;.u_boot_cmd:{*.u_boot_cmd}__u_boot_cmd_end=.;.=ALIGN4;__bss_start=.;.bss:{*.bss}_end=.;}1从ENTRY_start可以看出u-boot的入口函数是_start这个没错2从.=0x00000000也许可以看出_start的地址是0x00000000事实并不是这样的,这里的0x00000000没效,在连接的时候最终会被TETX_BASE所代替的,具体请参考u-boot根目录下的config.mk.3网上很多说法是_start=TEXT_BASE,我想这种说法也是正确的,但没有说具体原因本人的理解是这样的,TEXT_BASE表示text段的起始地址,而从.text:{cpu/ar__20t/start.o.text*.text}看,放在text段的第一个文件就是start.c编译后的内容,而start.c中的第一个函数就是_start,所以_start应该是放在text段的起始位置,因此说_start=TEXT_BASE也不为过
5.一直不明白的U-BOOT是怎样从4Ksteppingstone跳到RAM中执行的,现在终于明白了关键在于ldrpc_start_armboot_start_armboot:.wordstart_armboot这两条语句,ldrpc_start_armboot指令把_start_armboot这个标签的地方存放的内容也即是start_armboot移到PC寄存器里面,start_armboot是一个函数地址,在编译的时候给分配了一个绝对地址,所以上面语句实际上是完成了一个绝对地址的跳转而我一直不明白的___在start.S里面有很多BLB跳转语句都没有跳出4Ksteppingstone,原因是他们都是相对于PC的便宜的跳转,而不是绝对地址的跳转还有要补充一下LDRMOVLDR伪指令的区别LDRR00x12345678//把地址0x12345678存放的内容放到R0里面MOVR0#x//把立即数x放到R0里面,x必须是一个8bits的数移到偶数次得到的数LDRR0=0x12345678//把立即数0x12345678放到R0里面
6.在移植u-boot-
1.
3.3以上版本的时候要注意在u-boot
1.
3.3及以上版本__kefile有一定的变化,使得对于24x0处理器从nand启动的遇到问题也就是网上有人说的无法运行过lowlevel_init其实这个问题是由于编译器将我们自己添加的用于nandboot的子函数nand_read_ll放到了4K之后造成的(到这不理解的话,请仔细看看24x0处理器nandboot原理)我是在运行失败后,利用mini2440的4个LED调试发现u-boot根本没有完成自我拷贝,然后看了uboot根目录下的System.__p文件就可知道原因解决办法其实很简单将__LIBS:=$subst$o__$LIBS$subst$o__$LIBBOARD改为__LIBS:=$subst$o__$LIBBOARD$subst$o__$LIBS
7.然后说一下跳转指令ARM有两种跳转方式
(1)movpc跳转地址〉这种向程序计数器PC直接写跳转地址,能在4GB连续空间内任意跳转
(2)通过BBLBLXBX可以完成在当前指令向前或者向后32MB的地址空间的跳转(___是32MB呢?寄存器是32位的,此时的值是24位有符号数,所以32MB)B是最简单的跳转指令要注意的是,跳转指令的实际值不是绝对地址,而是相对地址——是相对当前PC值的一个偏移量,它的值由汇编器计算得出BL非常常用它在跳转之前会在寄存器LRR14中保存PC的当前内容BL的经典用法如下blNEXT;跳转到NEXT……NEXT……movpclr;从子程序返回二.开始上机移植红色字体为添加的内容,蓝色字体为修改的内容,下同给自己的__板取名为qljt
24401.随便找个目录解压u-boot,$tar–xjvfu-boot-
1.
3.
4.tar.gz
22.进入u-boot目录修改__kefile你要编译u-boot那当然少不了配置啦$cdu-boot-
1.
3.4[uboot@localhostu-boot-
1.
3.4]$vim__kefile修改内容如下__LIBS:=$subst$o__$LIBS$subst$o__$LIBBOARD改为__LIBS:=$subst$o__$LIBBOARD$subst$o__$LIBS__c2410x_config:unconfig@$MKCONFIG$@:_config=armar__20t__c2410xNULLs3c24x0qljt2440_config:unconfig@$MKCONFIG$@:_config=armar__20tqljt2440qljts3c24x0/*各项的意思如下:qljt2440_config:这个名字是将来你配置板子时候用到的名字,参见__keqljt2440_config命令arm:CPU的架构ARCHar__20t:CPU的类型CPU,其对应于cpu/ar__20t子目录qljt2440:__板的型号BOARD,对应于board/qljt/qljt2440目录qljt:__者/或经销商venders3c24x0:片上系统SOC*/
4.在/board子目录中建立自己的__板qljt2440目录由于我在上一步板子的__者/或经销商vender中填了qljt,所以__板qljt2440目录一定要建在/board子目录中的qljt目录下,否则编译会出错[uboot@localhostu-boot-
1.
3.4]$cdboard[uboot@localhostboard]$mkdirqljtqljt/qljt2440[uboot@localhostboard]$cp-arf__c2410x/*qljt/qljt2440/[uboot@localhostboard]$cdqljt/qljt2440/[uboot@localhostqljt2440]$mv__c2410x.cqljt
2440.c[uboot@localhostqljt2440]$ls可以看到下面这些文件config.mkflash.clowlevel_init.s__kefileqljt
2440.cu-boot.lds[uboot@localhostqljt2440]$vim__kefileCO__S:=qljt
2440.oflash.o
5.在include/configs/中建立__板所需要的配置头文件[uboot@localhostqljt2440]$cd../../..[uboot@localhostu-boot-
1.
3.4]$cpinclude/configs/__c2410x.hinclude/configs/qljt
2440.h
6.测试交叉编译能否成功
(1)配置[uboot@localhostu-boot-
1.
3.4]$__keqljt2440_configConfigureforqljt2440board…2测试编译[uboot@localhostu-boot-
1.
3.4]$__ke详细信息如下编译信息最后两行arm-linux-o__copy--gap-fill=0xff-Osrecu-bootu-boot.srecarm-linux-o__copy--gap-fill=0xff-Obinaryu-bootu-boot.bin到此交叉编译成功三.开始针对自己的__板移植
1.修改/cpu/ar__20t/start.S
1.1修改寄存器地址定义#ifdefinedCONFIG_S3C2400||definedCONFIG_S3C2410||definedCONFIG_S3C2440/*turnoffthewatchdog*/#ifdefinedCONFIG_S3C2400#definepWTCON0x15300000#defineINTMSK0x14400008/*Interupt-Controllerbaseaddresses*/#defineCLKDIVN0x14800014/*clockdivisorregister*/#else#definepWTCON0x53000000/*该地址用来屏蔽看门狗*/#defineINTMSK0x4A000008/*Interupt-Controllerbaseaddresses该地址用来屏蔽中断*/#defineINTSUBMSK0x4A00001C/*该地址用来屏蔽子中断*/#defineCLKDIVN0x4C000014/*clockdivisorregister该地址用来决定FCLK、HCLK、PCLK的比例*/#defineCLK_CTL_BASE0x4c000000/*qljt从S3C2440A.pdf中可以看出该寄存器是存放Mpll和Upll的P254*/#ifdefinedCONFIG_S3C2440#defineMDIV_4050x7f12/*qljt参见P255表,同时要知道本__板的Fin是12MHz,需要的Fclk也就是Mpll是405MHz*/#definePSDIV_4050x21/*qljt同上,同时设定PDIV和SDIV的值,PDIV和SDIV参见S3C2440A.pdf*/#endif#endif
1.2修改中断禁止部分#ifdefinedCONFIG_S3C2410ldrr1=0x7ff//根据2410芯片手册,INTSUBMSK有11位可用,//vivi也是0x7ff,不知___U-Boot一直没改过来但是由于芯片复位默认//所有的终端都是被屏蔽的,所以这个不影响工作ldrr0=INTSUBMSKstrr1[r0]#endif#ifdefinedCONFIG_S3C2440ldrr1=0x7fff//根据2440芯片手册,INTSUBMSK有15位可用ldrr0=INTSUBMSKstrr1[r0]#endif
1.3修改时钟设置/*时钟控制逻辑单元能够产生s3c2440需要的时钟__,包括CPU使用的主频FCLKAHB总线使用的HCLKAPB总线设备使用的PCLK,2440里面的两个锁相环PLL,其中一个对应FCLK、HCLK、PCLK,另外一个对应UCLK48MHz*//*注意AHP、APB总线的简介参见“AHB与APB总线.doc”*//*FCLK:HCLK:PCLK=1:4:8*/ldrr0=CLKDIVNmovr1#5strr1[r0]/*这三条协处理器命令确实不知道什么意思,在ATXJGYBC_ql.pdf中搜p15和c1,只知道它们执行以后会把协处理器p15的寄存器c1的最高两位置1,但c1的最高两位是没有意义啊,弄不懂它的真正意思不过我却知道这三条语句是从哪里出来的,详细请参考s3c2440的datasheet和s3c2440datasheet中的R1_nF和R1_iA.doc*/mrcp150r1c1c00/*readctrlregisterqljt*/orrr1r1#0xc0000000/*Asynchronousqljt改变总线模式为异步模式网上某位朋友说不知到在哪里看到过如果FCLK与HCLK不同的话就要选择这种模式的*/mcrp150r1c1c00/*writectrlregisterqljt*/#ifdefinedCONFIG_S3C2440//(2440的主频可达533MHz,但听说设到533MHz时系统//很不稳定,不知是不是SDRAM和总线配置的影响,所以现在先设到//405MHz,以后在改进)/*nowCPUclockis
405.00Mhzqljt*/movr1#CLK_CTL_BASE/*qljt*/movr2#MDIV_405/*mpll_405mhzqljt*/addr2r2#PSDIV_405/*mpll_405mhzqljt*/strr2[r1#0x04]/*MPLLCONqljt实际上是设置寄存器CLK_CTL_BASE+0x04=0x4c000004的值*/#endif#endif/*CONFIG_S3C2400||CONFIG_S3C2410||CONFIG_S3C2440*/
1.4将从Flash启动改成从NANDFlash启动(特别注意这和2410的程序有不同,不可混用!!!是拷贝vivi的代码)将以下U-Boot的重定向语句段@#ifndefCONFIG_AT91R__200#if0#ifndefCONFIG_SKIP_RELOCATE_UBOOTrelocate:/*relocateU-BoottoRAM*/adrr0_start/*r0-currentpositionofcode*/ldrr1_TEXT_BASE/*testifwerunfromflashorRAM*/cmpr0r1/*dontrelocduringdebug*/beqstack_setupldrr2_armboot_startldrr3_bss_startsubr2r3r2/*r2-sizeofarmboot*/addr2r0r2/*r2-sour__endaddress*/copy_loop:ldmiar0!{r3-r10}/*copyfromsour__address[r0]*/stmiar1!{r3-r10}/*copytotargetaddress[r1]*/cmpr0r2/*untilsour__endaddreee[r2]*/blecopy_loop#endif/*CONFIG_SKIP_RELOCATE_UBOOT*/#endif/*CONFIG_AT91R__200*/然后添加/*下载了一个vivi源代码看了一下,还真的有下面哪一段代码*/#ifdefCONFIG_S3C2440_NAND_BOOT@qljt@@@@@@@@@@@@@@@@SSSSSSSSSSSSS@resetNAND/*往下四段内容都是针对S3C2440的关于NAND-FLASH的寄存器的设置,具体有什么作用,看了datasheet,有些明白有些不明白*/movr1#NAND_CTL_BASEldrr2=712|78|74|00strr2[r1#oNFCONF]/*这些宏是在include/configs/qljt
2440.h中被定义的*/ldrr2[r1#oNFCONF]/*还是弄不懂___上面一句str以后还要有这句的ldr命令?why?难道是多余的?*/ldrr2=14|01|10@Activelow__Controlstrr2[r1#oNFCONT]ldrr2[r1#oNFCONT]ldrr2=0x6@RnBClearstrr2[r1#oNFSTAT]ldrr2[r1#oNFSTAT]movr2#0xff@RESETcom__ndstrbr2[r1#oNFCMD]/*delay一段时间*/movr3#0@waitnand1:addr3r3#0x1cmpr3#0xabltnand1/*等待nand-flash的复位完毕__*/nand2:ldrr2[r1#oNFSTAT]@waitreadytstr2#0x4beqnand2ldrr2[r1#oNFCONT]orrr2r2#0x2@FlashMemoryChipDisable/*在这里先Displayfansh__先,在C函数中对falsh进行*/strr2[r1#oNFCONT]/*操作的时候才enable,___这样操作不太清楚*//*下面这段用来初始化栈指针sp和帧指针fp至于它们的定义和作用参考文件夹”栈指针sp和帧指针fp”里面的内容记住它们都是与函数调用时候相关的简单来讲就是子函数被调用以后是通过指针的相对位置来查找调用参数和局部变量的,但是由于sp经常变化,所以需要fp来协助*/@getreadytocallCfunctionsfornand_readldrspDW_STACK_START@setupstackpointer/*sp是指堆栈指针*/movfp#0@nopreviousframesofp=0@copyU-BoottoRAM/*vivi里面应该是有一段是针对gpio的程序,也许使用来debug用的__灯,这里省略了*//*TEXT_BASE是uboot自己的入口地址,在u-boot-
1.
3.4-board/qljt/qljt2440的config.mk中定义有趣的是外___逆向思维很厉害,它们很灵活地把它放在SDRAM的最后0x80000地方,也就是0x33F80000*/ldrr0=TEXT_BASE/*r0:把u-boot__到ram的那个位置*/movr1#0x0/*r1:从falsh的那个位置开始__*/movr2#0x20000/*r2:__多大的内容*/blnand_read_ll/*跳到执行uboot__的程序入口这个函数从哪里来?也是来自vivi的,没办法*/tstr0#0x0/*这里特别注意r0的值是指nand_read_ll执行完以后的返回值,而不是上面ldrr0=TEXT_BASE的值,初学者往往在这里想不通*/beqok_nand_readbad_nand_read:/*如果读nand_read失败的话,那么sorry,重来,或者检查硬件*/loop2:bloop2@infiniteloopok_nand_read:@verify/*计算机就是好,很容易就可以检测我们放在SDRAM中的u-boot是不是flash中的uboot本__板使用的是nand-falsh的启动方式,板子一上电并不是马上进入SDRAM执行程序的是这样的板子一上电,S3C2440自动把nand-falsh中从0地址开始的4Kbytes__到S3C2440集成的某个缓冲区里面起始地址是0x00,从那里开始执行,那4K程序负责把整个uboot__到SDRAM,然后才跳到SDRAM开始正真的UBOOT这个技术是有个专业名字的我忘记了*//*下面这段程序的作用就是用开始执行的4Kbytes程序跟我们__到SDRAM中的uboot的前4K程序进行比较,从而校验*/movr0#0ldrr1=TEXT_BASEmovr2#0x400@4bytes*1024=4K-bytesgo_next:ldrr3[r0]#4ldrr4[r1]#4teqr3r4bnenot__tchsubsr2r2#4beqstack_setupbnego_nextnot__tch:loop3:bloop3@infiniteloop#endif@CONFIG_S3C2440_NAND_BOOT@qljt@@@@@@@@@@@@@@@@@@EEEEEEEEE
1.5在跳到C函数执行前,也就是跳出start.S前,添加几个LED灯的控制,说明程序跑到这里了,移植的第一阶段完成了/*本__板上面有四个LED灯,分别接到CPU的GPIO_F[4:7]这四个引脚上*/#ifdefinedCONFIG_S3C2440@LED1onu-bootstage1isok!movr1#GPIO_CTL_BASEaddr1r1#oGPIO_Fldrr2=0x5500strr2[r1#oGPIO_CON]movr2#0xffstrr2[r1#oGPIO_UP]movr2#0xdfstrr2[r1#oGPIO_DAT]#endif
1.6在“_start_armboot:.wordstart_armboot”后加入#ifdefinedCONFIG_S3C2440_NAND_BOOT.align2/*这里我一直不明白___是.align2因为如果按照ARM的规则,意思是按照2的2次方=4bit的方式对齐,那么就是半个字节对齐,有可能吗?*/DW_STACK_START:.wordSTACK_BASE+STACK_SIZE-4/*从这里可以看出该堆栈是从高地址向低地址增长的注意这里的STACK_BASE和STACK_SIZE还没定义,在
1.1节中定义*/#endif
2.修改include/configs/qljt
2440.__件,在结尾处添加如下内容(注意s3c2410与s3c2440的NandFlash控制器寄存器不同,不能混用!!)....../**NandflashBoot*/#defineCONFIG_S3C2440_NAND_BOOT1#defineSTACK_BASE0x33f00000#defineSTACK_SIZE0x8000/*NANDFlashController*/#defineNAND_CTL_BASE0x4E000000/*Offset*/#defineoNFCONF0x00/*这些宏是在start.S中被调用的*/#defineoNFCONT0x04#defineoNFCMD0x08#defineoNFADDR0x0c#defineoNFDATA0x10#defineoNFSTAT0x20#defineoNFECC0x2c/*GPIO*/#defineGPIO_CTL_BASE0x56000000#defineoGPIO_F0x50#defineoGPIO_CON0x0/*R/WConfiguresthepinsoftheport*/#defineoGPIO_DAT0x4/*R/WDataregisterforport*/#defineoGPIO_UP0x8/*R/WPull-updisableregister*/#endif/*__CONFIG_H*/
3.在board/qljt/qljt2440加入NANDFlash读函数文件,拷贝vivi中的nand_read.c文件到此文件夹即可,基本上大陆上移植的都是这样做的,在此把该文件的内容贴出来,目的是对一些难理解的代码进行解析#includeconfig.h#define__REGbx*volatileunsignedchar*x#define__REGix*volatileunsignedint*x#defineNF_BASE0x4e000000#defineNFCONF__REGiNF_BASE+0x0#defineNFCONT__REGiNF_BASE+0x4#defineNFCMD__REGbNF_BASE+0x8#defineNFADDR__REGbNF_BASE+0xC#defineNFDATA__REGbNF_BASE+0x10#defineNFSTAT__REGbNF_BASE+0x20//#defineGPDAT__REGiGPIO_CTL_BASE+oGPIO_F+oGPIO_DAT#defineNAND_CHIP_ENABLENFCONT=~11#defineNAND_CHIP_DISABLENFCONT|=11#defineNAND_CLEAR_RBNFSTAT|=12#defineNAND_DETECT_RB{while!NFSTAT12;}#defineBUSY4inlinevoidwait_idlevoid{while!NFSTATBUSY;NFSTAT|=BUSY;}#defineNAND_SECTOR_SIZE512#defineNAND_BLOCK___SKNAND_SECTOR_SIZE-1/*lowlevelnandreadfunction*//*下面nand_read_ll的三个参数来自start.S里面调用nand_read_ll前的r
0、r
1、r2*/intnand_read_llunsignedchar*bufunsignedlongstart_addrintsize{intij;/*下面这个if保证对flash的读操作是从某一页的页头开始的,从直观来看是保证start_addr[0:8]位都为0,___呢?因为本flash的一页的大小位512-bytes,也就是从0x0到0x1ff*/ifstart_addrNAND_BLOCK___SK||sizeNAND_BLOCK___SK{return-1;/*invalidalig__ent*/}NAND_CHIP_ENABLE;fori=start_addr;istart_addr+size;{/*READ0*/NAND_CLEAR_RB;/*到此应该可以明白s3c2440nandflash相关寄存器的确切含义了,就是说s3c2440里面已经集成了对nandflash操作的相关寄存器,只要你的nandflash接线符合s3c2440datasheet的接法,就可以随便使用s3c2440对于nandflash的相关寄存器,例如如果你想像nandflash写一个命令,那么只要对命令寄存器写入你的命令就可以了,s3c2440可以自动帮你完成所有的时序动作,写地址也是一样反过来说如果没有了对nandflash的支持,那么我们对nandfalsh的操作就会增加好多对I/O口的控制,例如对CLEALE的控制s3c2440已经帮我们完成了这部分工作了*/NFCMD=0;/*WriteAddress*//*下面这个送地址的过程可以说是这段程序里最难懂的一部分了,难就难于___送进nandflash的地址忽略了bit8,纵观整个fori循环,i并不是一个随机的地址,而应该是每一页的首地址其实nandflash并不是忽略了bit8这个地址,而是bit8早就被定下来了,什么时候定下来,就是上面的NFCMD=0;语句,本flashK9F1208U0B支持从半页开始读取,从而它有两个读的命令,分别是0x00从一页的上半页开始读和0x01从一页的下半页开始读,当取0x00时,bit8=0,当取0x01时bit8=
1.*/NFADDR=i0xff;NFADDR=i90xff;NFADDR=i170xff;NFADDR=i250xff;NAND_DETECT_RB;forj=0;jNAND_SECTOR_SIZE;j++i++{*buf=NFDATA0xff;/*每读一次NANDFLASH就往IO口送下一个byte,直到送完NAND_SECTOR_SIZE个为止*/buf++;}}NAND_CHIP_DISABLE;return0;}
4.修改board/qljt/qljt2440/__kefile文件,让刚刚添加的nand_read.c编译进来......CO__S:=qljt
2440.onand_read.oflash.o....../*===========================================================到这里,应该是可以编译通过的,否则就是编辑的时候出现了错误===========================================================*/
5.修改board/qljt/qljt2440/lowlevel_init.S文件依照__板的内存区的配置情况修改board/qljt/qljt2440/lowlevel_init.S文件,:....../*REFRESHparameter下面这6个配置都可以参考s3c2440AdatasheetP210的REFRESH寄存器*/#defineREFEN0x1/*Refreshenable*/#defineTREFMD0x0/*CBRCASbeforeRAS/Autorefresh*/#defineTrp0x01/*3clk这个值可以参考本版子上的SDRAM的datasheet*/#defineTrc0x3/*也就是SDRAMdatasheet里面的Tsrc7clk本来这个地方是Trc,但从lowlevel_init.S里面的调用来看,应该是寄存器REFRESH的Tsrc才对,好多地方都没有改过来,我我觉得只是个名字而已,不影响结果注意如果这里改了,那么下面这句中的Trc也要改为相应的Tsrc.wordREFEN23+TREFMD22+Trp20+Trc18+Tchr16+REFCNT*/#defineTchr0x2/*3clk,这个从lowlevel_init.S里面的调用来看是属于REFRESH的保留位,不知道为什么还要给他赋值*/#defineREFCNT____/*这个值的算法参考s3c2440AdatasheetP210的RefreshCounter*//*下面不厌其烦地解析一下lowlevel_init.S这个原文件*/#defineBWSCON0x48000000……#defineTchr0x2/*3clk*/#defineREFCNT0x0459/**************************************//*
1.要知道上面这些配置的最终会被用到下面__RDATA这个数据池里面,所以必须要明白__RDATA这个数据池是用来干什么的,__RDATA后面每一个.word后面防止的数据都是将要写入BWSCON开始的寄存器的,总共有13个.work它们后面放置的值将会分别别写入0x
48000000、0x
48000004、0x48000008…一直到0x48000030共13个寄存器*//*
2.上面那些配置的值是怎样决定的呢,详细请参考s3c2440A和你所用SDRAM的datasheet细心找总是能找到的*//*
3.而上面的那些配置值最终是通过下面lowlevel_init后面的这段函数写到寄存器里面的,下面对该段函数逐一分析*/_TEXT_BASE:.wordTEXT_BASE.globllowlevel_initlowlevel_init:/*memorycontrolconfiguration*//*__ker0relativethecurrentlocationsothatit*//*reads__RDATAoutofFLASHratherthanmemory!*/ldrr0=__RDATAldrr1_TEXT_BASEsubr0r0r1/*其实明白了前三条语句这段程序就不难懂了,归根到底就是___将__RDATA的值减去_TEXT_BASE的值?原因是这样的我们使用的是从nandflashboot的方式,目前程序仍然在4K-bytes‘Steppingstone’这里___突然冒出个Steppingstone’这个就是我前面提到从nandflash引导的方法,但不知道名字,后来重新看s3c2440Adatasheet的nandflash那一章的开头才知道上面运行,在__RDATA后面的的内容仍然在Steppingstone里面但是__RDATA的值是相对于_TEXT_BASE值的地址,而且_TEXT_BASE是放置u-boot的开始地方,所以用__RDATA-_TEXT_BASE就可以得到__RDATA后面内容在Steppingstone里面相对于地址0x00000000的放置的所在地方相对于0x00的地址值*//*从这三条语句可以看出前人为了实现从nandflash启动可谓费尽心思啊!*/ldrr1=BWSCON/*BusWidthStatusController*/addr2r0#13*4/*总共13个寄存器*/0:ldrr3[r0]#4strr3[r1]#4cmpr2r0bne0b/*everythingisfinenow*/movpclr.ltorg/*数据缓冲池,上网可以查得资料*//*theliteralpoolsorigin*/__RDATA:…….wordREFEN23+TREFMD22+Trp20+Trc18+Tchr16+REFCNT.word0xb
2.word0x30/*需要注意的是CASLatency的值在这里直接配置*/.word0x30/*===========================================================到这里,应该是可以编译通过的,否则就是编辑的时候出现了错误===========================================================*/6修改/board/qljt/qljt2440/qljt
2440.c,修改这个文件主要针对下面两点1GPIO的控制2PLL,毕竟s3c2410跟s3c2440不同修改其对GPIO和PLL的配置请参阅__C2440的硬件说明和2440芯片手册......#elifFCLK_SPEED==1/*Fout=405MHz*///#defineM_MDIV0x5c//#defineM_PDIV0x4//#defineM_SDIV0x0#defineM_MDIV0x7f#defineM_PDIV0x2#defineM_SDIV0x1#elifU___CLOCK==1//#defineU_M_MDIV0x48//#defineU_M_PDIV0x3#defineU_M_MDIV0x38#defineU_M_PDIV0x2#defineU_M_SDIV0x
2....../*setuptheI/Oports*/gpio-GPACON=0x007FFFFF;//gpio-GPFCON=0x000055AA;gpio-GPFCON=0x5500;/*forLED*/....../*archnumberofS3C2440-Board*/gd-bd-bi_arch_number=__CH_TYPE_S3C2440;/*adressofbootparameters*/gd-bd-bi_boot_params=0x30000100;icache_enable;dcache_enable;gpio-GPFDAT=0xbf;/*forLED*///intboard_initvoid设置完成后,LED1和LED2会亮起!return0;}/*===========================================================到这里,应该是可以编译通过的,否则就是编辑的时候出现了错误===========================================================*/
7.为了实现NANDFlash的读写,再次修改/include/configs/qljt
2440.h....../**HighLevelConfigurationOptions*easytochange*/#defineCONFIG_AR__20T1/*ThisisanAR__20TCore*///#defineCONFIG_S3C24101/*inaSAMSUNGS3C2410SoC*///#defineCONFIG___C2410X1/*onafriendly-arm__C-2410XBoard*/#defineCONFIG_S3C24401/*在前面很多地方调用到CONFIG_S3C2440他是在这里定义*/#defineCONFIG_qljt24401/*针对一些本__板配置的宏控制*/....../************************************************************Com__nddefinition***********************************************************/#defineCONFIG_CMD_DHCP#defineCONFIG_CMD_ELF#defineCONFIG_CMD_PING#defineCONFIG_CMD_NAND#defineCONFIG_CMD_NET#defineCONFIG_CMD_ENV/*thismustbeincludedAFTERthedefinitionofCONFIG_COM__NDSifany*/#includecmd_confdefs.h#defineCFG_LONGHELP/*undeftos__ememory*/#defineCFG_PROMPT[qljt2440]#/*这个就是你启动__板后命令行显示的内容了*//*MonitorCom__ndPrompt*/#defineCFG_CBSIZE256/*ConsoleI/OBufferSize*/......#defineCFG_LOAD_ADDR0x30008000/*以后linuxkernel就要放在这里执行*//*defaultloadaddress*/......//#defineCFG_ENV_IS_IN_FLASH1/这里的flash应该是指nor了,都不知道外国人___这么默认/#defineCFG_ENV_IS_IN_NAND1/*定义这个宏的目的是为了调用nandflash类型的s__eenv因为还有其它类型存储器的s__eenv,在u-boot中查看s__eenv的定义,有多少中定义就有多少种*//*在linux对nandflash分区的时候,给u-boot分配256k的空间0~0x40000其中u-boot.bin[0x0~0x30000]占192K而u-boot的参数[0x30000~0x40000]占64k*/#defineCFG_ENV_OFFSET0x30000#defineCFG_ENV_SIZE0x_____/*注意网上很多地方都有关于CONFIG_CMD_NAND、CFG_NAND_LEGACY、drivers/mtd/nand/nand.c中的nand_init函数以及board/qljt/qljt2440/qljt
2440.c中的nand_init函数这四个东西的关系,但大多说的不清不楚,我把它门的关系用表格一一列出来,请参考附录*/#defineCFG_NAND_LEGACY1/*----------------------------------------------------------------------*NANDflashsettings*/#ifdefinedCONFIG_CMD_NAND#defineCFG_NAND_BASE0x4E000000/*这个鬼东西在drivers/mtd/nand/nand.c中被调用它是NAND控制寄存器的__址*//*NandFlash控制器在SFR区起始寄存器地址*/#defineCFG___X_NAND_DEVI__1/*支持的最在NandFlash数据*/#defineSECTORSIZE512/*1页的大小*/#defineNAND_SECTOR_SIZESECTORSIZE/*这两个东西好像也是多余的,备用吧,在次文章搜一下就知道其它用到的地方也有定义*/#defineNAND_BLOCK___SK511/*本flash一个block的大小-1*//*页掩码*/#defineADDR_COLUMN1/*意思是你所用的nandflash的Column地址占多少个字节*//*一个字节的Column地址*/#defineADDR_PAGE3/*意思是你所用的nandflash的rowpage地址占多少个字节*//*3字节的页块地址!!!!!*/#defineADDR_COLUMN_PAGE4/*意思是你所用的nandflash的column地址+page地址共占多少个字节*//*总共4字节的页块地址!!!!!*/#defineNAND_ChipID_UNKNOWN0x00/*未知芯片的ID号*/#defineNAND___X_FLOORS1/*怎样算一floor*/#defineNAND___X_CHIPS1/*NandFlash命令层底层接口函数*/#definerNFCONF*volatileunsignedint*0x4e000000#definerNFCONT*volatileunsignedint*0x4e000004#definerNFCMD*volatileunsignedchar*0x4e000008#definerNFADDR*volatileunsignedchar*0x4e00000c#definerNFDATA*volatileunsignedchar*0x4e000010#definerNFSTAT*volatileunsignedint*0x4e000020#definerNFECC*volatileunsignedint*0x4e00002c/*下面部分内容是修改的*//*NandFlash命令层底层接口函数*//*#defineNAND_WAIT_READYnandNF_WaitRB#defineNAND_DISABLE___nandNF_Set__NF___HIGH#defineNAND_ENABLE___nandNF_Set__NF___LOW#defineWRITE_NAND_COM__NDdadrNF_Cmdd#defineWRITE_NAND_COM__NDWdadrNF_CmdWd#defineWRITE_NAND_ADDRESSdadrNF_Addrd#defineWRITE_NANDdadrNF_Writed#defineREAD_NANDadrNF_Read*/#defineWRITE_NAND_ADDRESSdadr{rNFADDR=d;}#defineWRITE_NANDdadr{rNFDATA=d;}#defineREAD_NANDadrrNFDATA#defineNAND_WAIT_READYnand{while!rNFSTAT10;}#defineWRITE_NAND_COM__NDdadr{rNFCMD=d;}#defineWRITE_NAND_COM__NDWdadrNF_CmdWd#ifdefinedCONFIG_S3C2440#defineNAND_DISABLE___nand{rNFCONT|=11;}#defineNAND_ENABLE___nand{rNFCONT=~11;}#endif#ifdefinedCONFIG_S3C2410#defineNAND_DISABLE___nand{rNFCONF|=111;}#defineNAND_ENABLE___nand{rNFCONF=~111;}#endif/*允许NandFlash写校验打开下面宏定义*/#defineCONFIG_MTD_NAND_VERIFY_WRITE
1......#endif/*__CONFIG_H*/
8.在/board/qljt/qljt2440/qljt
2440.c文件的末尾添加对NandFlash的初始化函数(在后面NandFlash的操作都要用到)#ifdefinedCONFIG_CMD_NAND/*大概在145行*/typedefenum{NF___LOWNF___HIGH}NF___STATE;staticinlinevoidNF_Confu16conf{S3C2410_NAND*constnand=S3C2410_GetBase_NAND;nand-NFCONF=conf;}staticinlinevoidNF_Cmdu8cmd{S3C2410_NAND*constnand=S3C2410_GetBase_NAND;nand-NFCMD=cmd;}staticinlinevoidNF_CmdWu8cmd{NF_Cmdcmd;udelay1;}staticinlinevoidNF_Addru8addr{S3C2410_NAND*constnand=S3C2410_GetBase_NAND;nand-NFADDR=addr;}staticinlinevoidNF_WaitRBvoid{S3C2410_NAND*constnand=S3C2410_GetBase_NAND;while!nand-NFSTAT10;}staticinlinevoidNF_Writeu8data{S3C2410_NAND*constnand=S3C2410_GetBase_NAND;nand-NFDATA=data;}staticinlineu8NF_Readvoid{S3C2410_NAND*constnand=S3C2410_GetBase_NAND;returnnand-NFDATA;}staticinlineu32NF_Read_ECCvoid{S3C2410_NAND*constnand=S3C2410_GetBase_NAND;returnnand-NFECC;}#ifdefinedCONFIG_S3C2440staticinlinevoidNF_Contu16cont{S3C2410_NAND*constnand=S3C2410_GetBase_NAND;nand-NFCONT=cont;}staticinlinevoidNF_Set__NF___STATEs{S3C2410_NAND*constnand=S3C2410_GetBase_NAND;switchs{caseNF___LOW:nand-NFCONT=~11;break;caseNF___HIGH:nand-NFCONT|=11;break;}}staticinlinevoidNF_Init_ECCvoid{S3C2410_NAND*constnand=S3C2410_GetBase_NAND;nand-NFCONT|=14;}#elsestaticinlinevoidNF_Set__NF___STATEs{S3C2410_NAND*constnand=S3C2410_GetBase_NAND;switchs{caseNF___LOW:nand-NFCONF=~111;break;caseNF___HIGH:nand-NFCONF|=111;break;}}staticinlinevoidNF_Init_ECCvoid{S3C2410_NAND*constnand=S3C2410_GetBase_NAND;nand-NFCONF|=112;}#endif/*对应#ifdefinedCONFIG_S3C2440*/staticinlinevoidNF_Initvoid{#if0#defineTACLS0#defineTWRPH03#defineTWRPH10#else#defineTACLS0#defineTWRPH04#defineTWRPH12#endif#ifdefinedCONFIG_S3C2440NF_ConfTACLS12|TWRPH08|TWRPH14;NF_Cont013|012|010|09|08|06|05|14|01|10;#elseNF_Conf115|014|013|112|111|TACLS8|TWRPH04|TWRPH10;/*nand-NFCONF=115|114|113|112|111|TACLS8|TWRPH04|TWRPH10;*//*11111xxxrxxxrxxx*//*En512B4stepECCRnF__=HtACLStWRPH0tWRPH1*/#endifNF_Reset;}#endif
9.cpu\ar__20t\s3c24x0\Nand.c,很多人说u-boot-
1.
3.4已经不支持CFG_NAND_LEGACY了,但其实还是支持的,定义了CFG_NAND_LEGACY后Nand.c要做如下修改#errorU-BootlegacyNANDsupportnot__ailableforS3C2410改成//#errorU-BootlegacyNANDsupportnot__ailableforS3C2410/*===========================================================到这里,编译是不能通过的,原因上一节中CONFIG_S3C2410这个宏定义被注释掉,下面要用CONFIG_S3C2440这个宏打开CONFIG_S3C2410所打开的内容===========================================================*/
10.在S3C2440与s3c2410能够共用的文件中添加“CONFIG_S3C2440”,使得原来s3c2410的代码可以编译进来
(1)/include/common.__件的第492行/*一些公用的常用函数,例如get_fclk*/#ifdefinedCONFIG_S3C2400||definedCONFIG_S3C2410||definedCONFIG_LH7A40X||definedCONFIG_S3C2440
(2)/include/s3c24x
0.h文件的第
85、
95、
99、
110、
148、404行/*一些关于S3C2440寄存器的结构体*/#ifdefinedCONFIG_S3C2410||definedCONFIG_S3C2440
(3)/cpu/ar__20t/s3c24x0/interrupts.c文件的第33行/*主要把一些头文件包含进去*/#ifdefinedCONFIG_S3C2400||definedCONFIG_S3C2410||definedCONFIG_TRAB||definedCONFIG_S3C2440第38行#elifdefinedCONFIG_S3C2410||definedCONFIG_S3C2440
(4)/cpu/ar__20t/s3c24x0/serial.c文件的第22行/*主要把一些头文件包含进去*/#ifdefinedCONFIG_S3C2400||definedCONFIG_S3C2410||definedCONFIG_TRAB||definedCONFIG_S3C2440第26行#elifdefinedCONFIG_S3C2410||definedCONFIG_S3C2440
(5)/cpu/ar__20t/s3c24x0/speed.c文件的第33行#ifdefinedCONFIG_S3C2400||definedCONFIG_S3C2410||definedCONFIG_TRAB||definedCONFIG_S3C2440第37行#elifdefinedCONFIG_S3C2410||definedCONFIG_S3C2440顺便修改源代码,以匹配s3c2440staticulongget_PLLCLKintpllreg{......m=r0xFF00012+8;p=r0x003F04+2;s=r0x3;//qljt/*这两个PLL的算法参见S3C2440datasheet的254页*/#ifdefinedCONFIG_S3C2440ifpllreg==MPLLreturnCONFIG_SYS_CLK_FREQ*m*2/ps;/*CONFIG_SYS_CLK_FREQ在qljt
2440.h中定义*/elseifpllreg==UPLL#endif//qljtreturnCONFIG_SYS_CLK_FREQ*m/ps;}....../*returnFCLKfrequency*/ulongget_FCLKvoid{returnget_PLLCLKMPLL;}/*returnHCLKfrequency*/ulongget_HCLKvoid{S3C24X0_CLOCK_POWER*constclk_power=S3C24X0_GetBase_CLOCK_POWER;/*看看s3c2410与s3c2440的datasheet就知道s3c2440的HCLK可选择的值多很多*/ifclk_power-CLKDIVN0x6{/*这里注意编译的时候发现CLKDIVN,这个将会在12节解决*/ifclk_power-CLKDIVN0x6==2returnget_FCLK/2;ifclk_power-CLKDIVN0x6==6returnclk_power-CAMDIVN0x100get_FCLK/6:get_FCLK/3;/*注意这里的CAMDIVN还没有被定义,在/include/s3c24x
0.h中定义*/ifclk_power-CLKDIVN0x6==4returnclk_power-CAMDIVN0x200get_FCLK/8:get_FCLK/4;returnget_FCLK;}else{returnget_FCLK;}//returnclk_power-CLKDIVN0x2get_FCLK/2:get_FCLK;}......
(6)/cpu/ar__20t/s3c24x0/u___ohci.c文件的第45行#elifdefinedCONFIG_S3C2410||definedCONFIG_S3C2440
(7)drivers/rtc/s3c24x0_rtc.c文件的第35行#elifdefinedCONFIG_S3C2410||definedCONFIG_S3C2440
(8)在文件中添加“definedCONFIG_qljt2440”,使得原来__C2410X__板的代码可以编译进来,/cpu/ar__20t/s3c24x0/interrupts.c文件的第181行#elifdefinedCONFIG___C2410X||\definedCONFIG___DK2410||\definedCONFIG_VC__9||definedCONFIG_qljt2440tbclk=CFG_HZ;/*对于CFG_HZ的值,结合uboot的说明和s3c2440的datasheet就比较容易理解*/#else
(9)/cpu/ar__20t/s3c24x0/u__.c文件的第31行#elifdefinedCONFIG_S3C2410||definedCONFIG_S3C2440
(10)/cpu/ar__20t/s3c24x0/i2c.c文件的第35行#elifdefinedCONFIG_S3C2410||definedCONFIG_S3C2440第
66、
85、
142、
150、174行将“#ifdefCONFIG_S3C2410”改为#ifdefinedCONFIG_S3C2410||definedCONFIG_S3C2440
(11)drivers/u__/u___ohci.c文件的第68行附近#ifdefinedCONFIG_AR__20T||\definedCONFIG_S3C2400||\definedCONFIG_S3C2410||\definedCONFIG_S3C2440||\definedCONFIG_440EP||\definedCONFIG_PCI_OHCI||\definedCONFIG_MPC
520011.在/include/s3c24x
0.h中加入2440的NANDFLASH寄存器定义和CAMDIVN定义typedefstruct{S3C24X0_REG32LOCKTIME;S3C24X0_REG32MPLLCON;S3C24X0_REG32UPLLCON;S3C24X0_REG32CLKCON;S3C24X0_REG32CLKSLOW;S3C24X0_REG32CLKDIVN;S3C24X0_REG32CAMDIVN;}S3C24X0_CLOCK_POWER;......#ifdefinedCONFIG_S3C2410//2440的NANDFLASH寄存器typedefstruct{S3C24X0_REG32NFCONF;S3C24X0_REG32NFCMD;S3C24X0_REG32NFADDR;S3C24X0_REG32NFDATA;S3C24X0_REG32NFSTAT;S3C24X0_REG32NFECC;}S3C2410_NAND;#endif#ifdefinedCONFIG_S3C2440typedefstruct{S3C24X0_REG32NFCONF;S3C24X0_REG32NFCONT;S3C24X0_REG32NFCMD;S3C24X0_REG32NFADDR;S3C24X0_REG32NFDATA;S3C24X0_REG32NFMECC0;S3C24X0_REG32NFMECC1;S3C24X0_REG32NFSECC;S3C24X0_REG32NFSTAT;S3C24X0_REG32NFESTAT0;S3C24X0_REG32NFESTAT1;S3C24X0_REG32NFECC;}S3C2410_NAND;#endif
12.修改/lib_arm中的board.c......#includecommon.h#includecom__nd.h#include__lloc.h#includedevi__s.h#includeversion.h#includenet.h#includes3c
2410.h......
13.修改common/env_nand.c......#ifdefCONFIG_INFERNO#errorCONFIG_INFERNOnotsupportedyet#endifintnand_legacy_rwstructnand_chip*nandintcmdsize_tstartsize_tlensize_t*retlenu_char*buf;externstructnand_chipnand_dev_desc[CFG___X_NAND_DEVI__];externintnand_legacy_erasestructnand_chip*nandsize_tofssize_tlenintclean;/*infoforNANDchipsdefinedindrivers/nand/nand.c*/nand_info_tnand_info[CFG___X_NAND_DEVI__];......#else/*!CFG_ENV_OFFSET_REDUND*/ints__eenvvoid{size_ttotal;intret=0;nand_erase_options_tnand_erase_options;nand_erase_options.length=CFG_ENV_RANGE;nand_erase_options.quiet=0;nand_erase_options.jffs2=0;nand_erase_options.scrub=0;nand_erase_options.offset=CFG_ENV_OFFSET;ifCFG_ENV_RANGECFG_ENV_SIZEreturn1;putsErasingNand...\n;/*在248行附近*///ifnand_erase_optsnand_info
[0]nand_erase_optionsifnand_legacy_erasenand_dev_desc+0CFG_ENV_OFFSETCFG_ENV_SIZE0return1;putsWritingtoNand...;total=CFG_ENV_SIZE;/*在254行附近*///ifwriteenvCFG_ENV_OFFSETu_char*env_ptr{//putsFAILED!\n;//return1;//}ret=nand_legacy_rwnand_dev_desc+00x00|0x02CFG_ENV_OFFSETCFG_ENV_SIZEtotalu_char*env_ptr;ifret||total!=CFG_ENV_SIZEreturn1;putsdone\n;returnret;}#else/*!CFG_ENV_OFFSET_REDUND*/......./**ThelegacyNANDcodes__edtheenviro__entinthefirstNANDdevi__i.e.*nand_dev_desc+
0.Thisisalsothebeh__iourusingthenewNANDcode.*/voidenv_relocate_specvoid{#if!definedENV_IS_EMBEDDEDsize_ttotal;intret;total=CFG_ENV_SIZE;/*在360行附近*///ret=readenvCFG_ENV_OFFSETu_char*env_ptr;ret=nand_legacy_rwnand_dev_desc+00x01|0x02CFG_ENV_OFFSETCFG_ENV_SIZEtotalu_char*env_ptr;/*editedbyyaoyi20090___
1.
3.4是先进入到readenv而非直接调用nand_legacy_rw因此干脆就不用到readenv了,直接注释掉,添加以上代码*/ifret||total!=CFG_ENV_SIZEreturnuse_default;ifcrc320env_ptr-dataENV_SIZE!=env_ptr-crcreturnuse_default;#endif/*!ENV_IS_EMBEDDED*/}/*u-boot运行至第二阶段进入start_armboot函数其中nand_init函数是对nandflash的最初初始化函数Nand_init函数在两个文件中实现其调用与CFG_NAND_LEGACY宏有关,如果没有定义这个宏,系统调用drivers/nand/nand.c中的nand_init;否则调用自己在board/qljt/qljt2440/qljt
2440.c中的nand_init函数这里我选择第二种方式*/
14.修改include/nand.h.......//#ifndefCFG_NAND_LEGACY#includelinux/mtd/compat.h#includelinux/mtd/mtd.h#includelinux/mtd/nand.h.......//#endif/*!CFG_NAND_LEGACY*//*===========================================================到这里,应该是可以编译通过的,否则就是编辑的时候出现了错误===========================================================*/
9、在include/linux/mtd/nand_ids.h的结构体nand_flash_ids加入/*至于这个结构体的值怎么得来,有待研究*/staticstructnand_flash_devnand_flash_ids[]={....../*结构体nand_flash_dev在doc
2000.h中定义*//*厂家型号,生产商编号,本模块的编号,总共容纳地址的位数,存储页字节数是否为256,地址需要多少字节数减一行列地址总共,擦除1个block的大小,是否为16位总线*/{SamsungKM29N16000NAND_MFR_SAMSUNG0x6421120x10000}{SamsungK9F1208U0BNAND_MFR_SAMSUNG0x7626030x40000}{Samsungunknown4MbNAND_MFR_SAMSUNG0x6b22020x20000}......};/*下面说说上面结构体的8个参数是怎么得出来的,以便日后再次移植的时候会更换nandflash*//*
1.“厂家型号”这个从nandflash的datasheet就可以直接找到了吧
2.生产商的编号也就是datasheet里面的__kercode,它也同时被存放在nandflash里面的IDnandflash应该有一个读ID命令的信息里面)
3.本模块的编号也就是datasheet里面的devi__code,跟__kercode一样它也被放到ID信息里面
4.总共容纳的地址位数也就是有效的地址位数针对于本flashK9F1208U0M可以参考它的datasheet第7页
5.一页所存储的字节数是否为256个针对于本flashK9F1208U0M可以参考它的datasheet第7页
6.地址需要多少字节数减一行列地址总共举个例子可能更容易明白,第4点中可以知道本flashK9F1208U0M有26位,而对本flash地址的写入每次只能写8位,所以至少要写4次才能把26位地址写入本flash,4次的写入针对于编程来说就是[0:3],所以本falsh相对于该结构体的该变量的值是
3.
7.擦除1个block的大小简单来说就是1个block的大小,本flash1block=32pages,1page=512bytes所以1block=512x32=16k-bytes,也就是0x
40008.是否为16位总线本flash地址和数据总线共用,都是8位的,所以上面值为0*/
15.修改/lib_arm中的board.c添加几个debug信息(这一步可以不用修改)......#includecommon.h#includecom__nd.h#include__lloc.h#includedevi__s.h#includeversion.h#includenet.h......staticintdisplay_bannervoid{S3C24X0_GPIO*constgpio=S3C24X0_GetBase_GPIO;gpio-GPFDAT=0x8f;//qljtninja//在串口初始化和console初始化完成,串口输出信息之前,LED
1、LED
2、LED3会亮起!printf\n\n%s\n\nversion_string;debugU-Bootcode:%08lX-%08lXBSS:-%08lX\n_armboot_start_bss_start_bss_end;printfU-Bootcode:%08lX-%08lXBSS:-%08lX\n//qljt_armboot_start_bss_start_bss_end;//qljt#ifdefCONFIG_MODEM_SUPPORTdebugModemSupportenabled\n;#endif#ifdefCONFIG_USE_IRQdebugIRQStack:%08lx\nIRQ_STACK_START;debugFIQStack:%08lx\nFIQ_STACK_START;#endifreturn0;}......voidstart_armbootvoid{init_fnc_t**init_fnc_ptr;char*s;#ifndefCFG_NO_FLASHulongsize;#endif#ifdefinedCONFIG_VFD||definedCONFIG_LCDunsignedlongaddr;#endifS3C24X0_GPIO*constgpio=S3C24X0_GetBase_GPIO;......gpio-GPFDAT=0x7f;//qljtninja//在进入命令提示符之前,四个LED会同时亮起!/*__in_loopcanreturntoretryautobootifsojustrunitagain.*/for;;{__in_loop;}/*NOTREACHED-nowayoutofcom__ndloopex__ptbooting*/}/*===========================================================到这里,应该是可以编译通过的,否则就是编辑的时候出现了错误===========================================================*/
16.裁减flash的支持(这一步也可以不执行)1在board/qljt/qljt2440/flash.c的头部加上#if0,尾部加上#endif2在include/configs/__
2440.h加上#undefCONFIG_CMD_FLASH#undefCONFIG_CMD_IMLS….#defineCFG_NO_FLASH13在common/cmd_bootm.c的”#include”语句后加上#ifdefCONFIG_CMD_IMLS#undefCONFIG_CMD_IMLS#endif附录一.U-boot的命令默认配置存放在/include/config_cmd_default.h里,可以修改该文件或者在__
2440.h里添加#undef里裁减不需要的内容二.
1.在u-boot-
1.
3.2前不含u-boot-
1.
3.2nand_init函数的调用关系,它的调用是被“CONFIG_COM__NDSCFG_CMD_NAND”和“CFG_NAND_LEGACY”控制的,1表示该值为真,0表示该值为假CONFIG_COM__NDSCFG_CMD_NANDCFG_NAND_LEGACY/drivers/mtd/nand/nand.c中的nand_init函数/board/qljt/qljt2440/qljt
2440.c中的nand_init函数
00000100101111012.在u-boot-
1.
3.2后含u-boot-
1.
3.2nand_init函数的调用关系,它的调用是被“CONFIG_CMD_NAND”和“CFG_NAND_LEGACY”控制的,1表示该值为真,0表示该值为假CONFIG_CMD_NANDCFG_NAND_LEGACY/drivers/mtd/nand/nand.c中的nand_init函数/board/qljt/qljt2440/qljt
2440.c中的nand_init函数0000010010111101。