S3C2440_uboot2010.06_启动菜单移植手册
- 格式:pdf
- 大小:295.54 KB
- 文档页数:4
首先:在汇编中初始化堆栈,中断向量表,MMU,时钟,串口等,然后跳到C语言的Main 函数。
这部分代码小于4K,放在block0。
这个Main函数用来将第二段代码拷备到DRAM 中并执行。
其次:进入第二段代码。
第二段代码也是先在汇编中初始化堆栈,中断向量表等,然后跳到C语言的Main函数。
这部分代码就不用有4K限制了,具体大小由第一段代码决定,因为它本身由第一段代码来搬运。
这个Main函数用来显示开机图片以及进度条。
然后视串口接收信息运行带有USB下载NK的Eboot或是读取NK映像,启动WINCE系统。
最后:进入第三段代码。
这段代码用于通过USB将PC上的NK.nb0或NK.bin文件下载进NANDFLASH并运行。
可见,扬创公司光bootloader就分成了三个部分,即3个bin文件组成。
然后分别将这三段二进制代码下载进分别从block0,block2,block8(block12)开始的三块。
具体烧写手段采用老掉牙的giveio烧写,就是曾经大名鼎鼎的SJF2440了,相信不少嵌入式高手都用过,哈哈。
如果不小心将bootloader弄丢了,再重烧一片,得等上好几分钟,足够你到外面跑上几千米再回来这么长了。
尽管如此,我们的扬创公司仍然拿他们的代码当宝,死活不肯开源。
要知道对于买你们板子的人,都是来学习的呀!学习嵌入式系统,bootloader是最基础也是进入嵌入式行业的敲门砖,没有了代码,无疑给学习添加了很大的麻烦,而扬创官方回答却是:用户开发产品用不着修改bootloader.我看扬创没开发过东西,不了解行情。
不说这么多废话了,说多了无益,让我们一起来揭开bootloader的神秘的面纱吧!先说下我移植的bootloader的功能,以及烧录时间,和扬创的做下对比。
第一次下载bootloader到NANDFLASH的方法:方法一:通过扬创的老掉牙的方法,先在ADS1.2里面生成bootloader.bin文件,然后用SJF2440烧写工具,配合giveio将BIN文件烧写进从block0开始的块。
S3C2440移植uboot之新建单板_时钟_SDRAM_串口上一节S3C2440移植uboot之启动过程概述我们我们分析了uboot启动流程,这节将开始新建一块单板支持S3C2440。
目录•1.新建单板o 1.1 将2410的单板文件夹拷贝成2440:o 1.2 将2410的头文件拷贝成2440•2.修改boards.cfg,使uboot支持2440单板:•3.修改uboot系统时钟•4.烧写修改后的uboot•5.烧写uboot,发现串口已有数据,但是乱码o 5.1进入arch\arm\cpu\arm920t\s3c24x0\Speed.c下的get_HCLK ()函数:o 5.2编译测试o 5.3所以就直接去掉该文件,不让编译器编译即可,步骤如下所示:1.新建单板1.1 将2410的单板文件夹拷贝成2440:cd /work/system/u-boot-2012.04.01/board/samsungcp smdk2410 smdk2440 -rf1.2 将2410的头文件拷贝成2440cd ../../include/configs/cp smdk2410.h smdk2440.h修改2440文件夹下的smdk2410.c和Makefile文件2.修改boards.cfg,使uboot支持2440单板:仿照smdk2410 arm arm920t - sa msung s3c24x0添加:smdk2440 arm arm920t - sa msung s3c24x0使用make smdk2440_config命令(命令便会调用include/configs/smdk2440.h和board/samsung/smdk2440里的文件来配置uboot)同样的,在windows下把u-boot-2012.04.01.tar_2\u-boot-2012.04.01\board\samsung下的smdk2410拷贝成smdk2440,把u-boot-2012.04.01.tar_2\u-boot-2012.04.01\include\configs smdk2410.h复制为smdk2440.h。
S3C2440移植uboot之支持NAND启动上一节S3C2440移植uboot之新建单板_时钟_SDRAM_串口移植uboot初始化了时钟,配置了支持串口,这一节我们继续修改uboot支持NAND启动。
目录•1.去掉 "-pie"选项•2.修改之前的init.c•3.修改start.s重定位部分•4.修改链接脚本•5.报错修改•6.重新修改链接地址1.去掉 "-pie"选项参考之前uboot使用的start.S, init.c来修改uboot代码新的uboot链接地址位于0,且在arm-linux-ld时加了"-pie"选项, 使得u-boot.bin里多了"*(.rel*)", "*(.dynsym)",从而程序非常大,不利于从NAND启动(重定位之前的启动代码应该少于4K).所以接下来修改代码,并取消"-pie"选项.使用grep "-pie" * -nR找到:arch/arm/config.mk:75:LDFLAGS_u-boot += -pie // LDFLAGS: arm-linux-ld的参数所以屏蔽arch/arm/config.mk文件的"LDFLAGS_u-boot += -pie"这行即可2.修改之前的init.c将以前写uboot里的init.c放入board/samsung/smdk2440目录, 并检查是否有同名函数名,若函数只在同文件使用,则添加static.并修改Makefile 增加对init.c的支持vi board/samsung/smdk2440/Makefile修改include/configs/smdk2440.h文件,将CONFIG_SYS_TEXT_BASE宏改为0x33f80000,也就是uboot重定位后的位置, 这里留了512K空间供给uboot重定位修改完的代码如下所示/* NAND FLASH控制器 */#define NFCONF (*((volatile unsigned long *)0x4E000000)) #define NFCONT (*((volatile unsigned long *)0x4E000004)) #define NFCMMD (*((volatile unsigned char *)0x4E000008)) #define NFADDR (*((volatile unsigned char *)0x4E00000C)) #define NFDATA (*((volatile unsigned char *)0x4E000010))#define NFSTAT (*((volatile unsigned char *)0x4E000020))/* GPIO */#define GPHCON (*(volatile unsigned long *)0x56000070)#define GPHUP (*(volatile unsigned long *)0x56000078)/* UART registers*/#define ULCON0 (*(volatile unsigned long *)0x50000000)#define UCON0 (*(volatile unsigned long *)0x50000004)#define UFCON0 (*(volatile unsigned long *)0x50000008)#define UMCON0 (*(volatile unsigned long *)0x5000000c)#define UTRSTAT0 (*(volatile unsigned long*)0x50000010)#define UTXH0 (*(volatile unsigned char *)0x50000020)#define URXH0 (*(volatile unsigned char *)0x50000024)#define UBRDIV0 (*(volatile unsigned long *)0x50000028)#define TXD0READY (1<<2)void nand_read_ll(unsigned int addr, unsigned char *buf, unsigned int len);static int isBootFromNorFlash(void){volatile int *p = (volatile int *)0;int val;val = *p;*p = 0x12345678;if (*p == 0x12345678){/* 写成功, 是nand启动 */*p = val;return 0;}else{/* NOR不能像内存一样写 */return 1;}}void copy_code_to_sdram(unsigned char *src, unsigned char *dest, unsigned int len){int i = 0;/* 如果是NOR启动 */if (isBootFromNorFlash()){while (i < len){dest[i] = src[i];i++;}}else{//nand_init();nand_read_ll((unsigned int)src, dest, len);}}void clear_bss(void){extern int __bss_start, __bss_end__;int *p = &__bss_start;for (; p < &__bss_end__; p++)*p = 0;}void nand_init_ll(void){#define TACLS 0#define TWRPH0 1#define TWRPH1 0/* 设置时序 */NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4); /* 使能NAND Flash控制器, 初始化ECC, 禁止片选 */ NFCONT = (1<<4)|(1<<1)|(1<<0);}static void nand_select(void){NFCONT &= ~(1<<1);}static void nand_deselect(void){NFCONT |= (1<<1);}static void nand_cmd(unsigned char cmd){volatile int i;NFCMMD = cmd;for (i = 0; i < 10; i++);}static void nand_addr(unsigned int addr) {unsigned int col = addr % 2048; unsigned int page = addr / 2048; volatile int i;NFADDR = col & 0xff;for (i = 0; i < 10; i++);NFADDR = (col >> 8) & 0xff;for (i = 0; i < 10; i++);NFADDR = page & 0xff;for (i = 0; i < 10; i++);NFADDR = (page >> 8) & 0xff;for (i = 0; i < 10; i++);NFADDR = (page >> 16) & 0xff;for (i = 0; i < 10; i++);}static void nand_wait_ready(void){while (!(NFSTAT & 1));}static unsigned char nand_data(void) {return NFDATA;}void nand_read_ll(unsigned int addr, unsigned char *buf, unsigned int len){int col = addr % 2048;int i = 0;/* 1. 选中 */nand_select();while (i < len){/* 2. 发出读命令00h */nand_cmd(0x00);/* 3. 发出地址(分5步发出) */nand_addr(addr);/* 4. 发出读命令30h */nand_cmd(0x30);/* 5. 判断状态 */nand_wait_ready();/* 6. 读数据 */for (; (col < 2048) && (i < len); col++){buf[i] = nand_data();i++;addr++;}col = 0;}/* 7. 取消选中 */nand_deselect();}3.修改start.s重定位部分修改arch/arm/cpu/arm920t/start.S,更改重定位代码。
U-Boot移植(3)增加对S3C2440的⽀持昨天跟张⽼师去打乒乓球了,还没写完今天接着写。
6、S3C2440是S3C2410的改进版,它们的操作基本相似,只是在系统时钟的设置、NAND Flash控制器的操作等⽅⾯有⼀些⼩差别。
⽽下⾯我要做的就是令⼀个U-Boot⼆进制代码既可以在S3C2410上运⾏,也可以在S3C2440上运⾏。
虽说我的板也是S3C2410的,但是增加S3C2440的U-Boot练习,可以提⾼我们的能⼒,为后⾯的学习打下基础。
GSTATUS1寄存器的值:0x32410000表⽰S3C2410,0x32410002表⽰S3C2440。
S3C2410:FCLK=200MHZ;S3C2440:FCLK=400MHZ,UCLK=48MHZ;搞清楚之后,下⾯我们就可以开始了。
⾸先先在board/100ask24x0/100ask24x0.c 中的前⾯定义如下⼀些值:我的开发板输⼊时钟为12MHZ,如果你的开发板时钟和我的不⼀样的话,可以根据以前代码中的公式计算,然后修改系统时钟,这在include/configs/100ask24x0.h中的宏CONFIG_SYS_CLK_FREQ中定义。
接下来,就是使⽤不同的宏设置系统时钟,包括S3C2410、S3C2440。
7、在后⾯设置串⼝波特率时需要获得系统时钟,就是在U-Boot的第⼆个阶段,即是lib_arm/board.c中start_armboot函数调⽤serial_init函数初始化串⼝时,会调⽤get_PCLK、get_HCLK、get_PLLCLK等函数,这需要我们作相应的修改。
⾸先要在board_init函数的开关增加如下⼀⾏,才能使⽤变量gd,因为识别出S3C2410和S3C2440,设置了机器类型ID:gd->bd->bi_arch_number 。
接着在get_PLLCLK函数中增加如下:由于分频系数设置⽅法也不⼀样,get_HCLK、get_PCLK也需要修改。
一、移植环境∙主机:VMWare6.5--Fedora 9∙开发板:自制开发板CPU:S3C2440;SDRAM:HY57V561620FTP-H;NOR flash:SST_39VF1601(2M);NAND flash:K9F1G08U0B(128M);网卡芯片:DM9000EP∙编译器:arm-linux-gcc-4.3.2∙u-boot:u-boot-2009.08∙linux kernel:linux-2.6.30∙busybox:busybox-1.13.3二、博客地址/liuqiqi677如有错误,欢迎指正。
三、参考资料主要参考了黄刚的博客/u3/101649/,他的博客写得相当不错,将嵌入式开发各个阶段的知识以边做边学的方式,辅以图片、解释,清晰地呈现给读者,能够让读者把握主线,对嵌入式开发有整体的了解。
强烈推荐!!!四、问题及解决方法7、Fedora9的bug,“No network connection”我的虚拟机采用桥接的方式与Windows连接,并且在Fedora9中能够ping通Windows XP,但是右上角的网络连接图标无论是否手动激活网卡都会一直提示"No network connection",如图7所示,显示一把红色小叉。
图7 网络连接图标显示无连接这个问题之前一直存在,但是没有找到解决方法,就搁置下来了。
后来,我想用tftp将linux内核下载到开发板上,但是一直不能成功,我就怀疑是不是网络部分没有配置好,因此又去仔细研究了一下,终于发现问题所在!这实际上是Fedora 9 的一个bug。
(以前的版本没用过不清楚)造成这个问题的原因是Network Configuration 图形设置界面的默认选项值与/etc/sysconfig/network-scripts/ifcfg-eth0 配置文件的默认值不一致。
刚装完系统的情况下:在Network Configuration 中,编辑Device 下的eth0,会发现"Controlled by NetworkManager" 是不打勾的。
CPU S3C2440A 主频400MHz,最高533MHzSDRAM hy57v561620ftp-h 2片16bit 32M 串联,最高100MHz Nand Flash K9F1208U00-PCB064M ×8bit Nor Flash AM29LV160DB-90EC 2M ×16bitLCD HST-TPA3.5F 3.5英寸真彩色TFT电阻式触摸屏LCD NET CARDCS8900A-CQ3Z10M 网卡控制芯片16bit 数据传输表1实验板的主要硬件组成图1U-boot 的整体结构1Uboot 移植环境准备1.1移植平台的硬件组成硬件平台是ARM9的体系结构,ARM920T 的CPU ,SOC 芯片是三星的S3C2440,支持Nand Flash 与NorFlash 的可选启动方式,其主要硬件资源如表1所示[1]。
支持Nand Flash 与Nor Flash 启动,可以通过跳线来选择启动方式。
Nand Flash 启动时,最开始4KB 数据被硬拷贝到内部Boot Internal SRAM,且被映射到nGCS0的片选空间0x0000,0000—0x0800,0000;Nor Flash 方式启动时,它直接被映射到nGCS0的片选空间。
所以,在U -boot 移植时,要考虑将Uboot 烧写到Nor flash 上还是Nand Flash 上。
1.2Uboot 工作原理Uboot 的整体结构如图1所示。
从图1可以看出,这种分层结构的Uboot 分模块化了,给移植带来了很大的方便。
由于协议层与应用层是与目标硬件无关的,因此移植工作主要集中在物理层和驱动层上面的修改。
而Uboot 支持串口下载、网络下载,并提供了很多交互式命令。
整个Uboot 编译、连接过程如下:(1)创建编译环境在MAKEFILE 中会调用根目录下Uboot 在S3C2440上的移植卢伟,潘炼(武汉科技大学信息科学与工程学院自动化系,湖北武汉434200)摘要:通过分析Uboot 的文件结构及其启动流程,详细给出了Uboot 在基于ARM920T 开发板上的移植方案,包括编译、调试全过程,最终能够在Uboot 命令方式下加载映像文件,完成Linux 内核与yaffs 映像文件的调试,具有Bootloader 移植的通用性。
一、Uboot移植前的准备1、修改makefile、配置文件在配置文件之前,需要修改makeflie相关内容:修改如下:(1)修改编译器,这里我们的makefile已经设置为arm-linux-无需再修改,如下所示:ifeq ($(ARCH),arm)CROSS_COMPILE = arm-linux-Endif(2)添加fl2440的配置项,如下所示:fl2440_config:unconfig@$(MKCONFIG) $(@:_config=) arm arm920t fl2440 step s3c24x0注意:在添加的fl2440_config的第二行,必须以Table开头,不能有任何多余的符号,否则极易导致编译错误。
Uboot支持多种处理器和平台,在编译uboot之前需要对其进行配置,使其支持我们自己的开发平台。
在执行编译make之前,需要进行配置即make fl2440_config。
通过查看顶层目录的makeflie文件,通过以下语句:MKCONFIG := $(SRCTREE)/mkconfig得出实际执行的命令为:./mkconfig fl2440 arm arm920t fl2440 step s3c24x0执行完这句后,产生如下结果:(1)开发板名称为fl2440;(2)将include中的头文件连接到同平台相关的头文件中,这里的连接为:asm->asm-armarch->arch-s3c24x0proc->proc-armv(3)创建顶层Makefile包含的文件inclued/config.mk,该文件内容如下ARCH = armCPU = arm920tBOARD = fl2440VENDOR = stepSOC = s3c24x0(4)创建开发板相关头文件include/config.h,该文件中包含了对开发板的相关配置,如下所示:#include <configs/fl2440.h>从上面可以知道,在将uboot配置为适合自己的平台的时候,需要在路径/include/configs下添加配置头文件fl2440.h。