UBoot移植详细教程
- 格式:doc
- 大小:76.50 KB
- 文档页数:18
烧写ARM开发板系统教程-----uboot、内核以及⽂件系统⼀、sd启动将u-boot镜像写⼊SD卡,将SD卡通过读卡器接上电脑(或直接插⼊笔记本卡槽),通过"cat /proc/partitions"找出SD卡对应的设备,我的设备节点是/dev/sdb.(内存卡的节点)。
当有多个交叉编译器是,不⽅便设置环境变量时,可以在编译命令中指定交叉编译器,具体如下:在源码中操作以下步骤:make distcleanmake ARCH=arm CROSS_COMPILE=/opt/FriendlyARM/toolschain/4.5.1/bin/arm-none-linux-gnueabi- mrpropermake ARCH=arm CROSS_COMPILE=/opt/FriendlyARM/toolschain/4.5.1/bin/arm-none-linux-gnueabi- tiny210_configmake ARCH=arm CROSS_COMPILE=/opt/FriendlyARM/toolschain/4.5.1/bin/arm-none-linux-gnueabi- all spl编译出tiny210-uboot.bin,注意交叉编译⼯具路径执⾏下⾯的命令$sudo dd iflag=dsync oflag=dsync if=tiny210-uboot.bin of=/dev/sdb seek=1把内存卡插⼊开发板,使⽤串⼝⼯具设置环境变量:setenv gatewayip 192.168.1.1(电脑⽹关)setenv ipaddr 192.168.1.102(开发板ip,不要与虚拟机和电脑ip冲突)setenv netmask 255.255.255.0setenv serverip 192.168.1.10(虚拟机ip)saveenv⼆、nand启动烧写Uboot:通过SD卡启动的u-boot for tiny210 将u-boot镜像写⼊nandflash在虚拟机下重启tftp sudo service tftpd-hpa restart开发板终端下执⾏下⾯的命令:[FriendlyLEG-TINY210]# tftp 21000000 tiny210-uboot.bin[FriendlyLEG-TINY210]# nand erase.chip[FriendlyLEG-TINY210]# nand write 21000000 0 3c1f4 (写⼊长度)内核的烧写位置是0x600000开始的区域,⽂件系统烧写位置为0xe00000开始的区域。
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中烧录方法
在嵌入式系统开发中,U-Boot是一个常用的引导加载程序,用
于引导嵌入式设备的操作系统。
烧录U-Boot到嵌入式设备通常涉及
以下几种方法:
1. 串口烧录,通过串口连接嵌入式设备和主机,使用串口通信
工具(如minicom、putty等)将U-Boot固件通过串口传输到设备
的存储器中。
这种方法需要设备具备串口接口,并且需要主机具备
串口通信工具和相应的串口线缆。
2. TFTP烧录,使用TFTP(Trivial File Transfer Protocol)通过网络将U-Boot固件传输到嵌入式设备的存储器中。
在设备启动时,U-Boot会尝试从网络上的TFTP服务器下载固件。
这种方法需
要设备处于能够访问网络的环境中,并且需要在网络中设置好TFTP
服务器。
3. SD卡烧录,将U-Boot固件写入SD卡,然后将SD卡插入嵌
入式设备,设备在启动时会读取SD卡中的U-Boot固件。
这种方法
需要主机具备SD卡写入工具,如dd命令或Win32 Disk Imager等。
4. JTAG烧录,使用JTAG(Joint Test Action Group)接口连接嵌入式设备和主机,通过专用的JTAG调试器将U-Boot固件烧录到设备的存储器中。
这种方法通常需要专门的硬件设备和相应的调试软件。
在选择烧录方法时,需要根据具体的嵌入式设备和开发环境来决定,确保选择的方法能够有效、安全地将U-Boot固件烧录到设备中,并且需要注意备份设备中原有的U-Boot固件以防止意外情况发生。
希望这些信息能够帮助你更好地理解在U-Boot中的烧录方法。
以前移植过华为C8812的,觉得移植内容差不多,所以决定试试,毕竟N881E也有一批用户,下面列出我的一些办法,看看对中兴机子是否可行我以前移植华为的办法如下移植百度的应用层和framework 框架层(system/app system/framework system/tts这三个文件夹我用的是百度云N880E的底包)移植lib,不删减添加东西,但是其中的modules使用官方包的,用BeyondCompare 3比较多出来的用百度云的包移植system/bin 和system/xbin 文件夹全部用官方的移植system/media 文件夹整个文件夹必须使用百度的移植system/usr 文件夹把百度的keychars 和keylayout 两个文件删除,替换为官方包中的这两个文件夹移植system/etc 文件夹必须将百度云的文件夹中firmware 文件夹删除,替换为官方包中的firmware文件夹修改build.prop必须使用官方包中官方的build.prop,但是必须在build.prop 任意位置加入如下几行(对比了N880E百度和N881E官方的build.prop,发现百度修改和添加了一下prop,移植时如果官方的build.prop有这个属性,替换,没有则增加即可):ro.baidu.build.hardware=N881Ero.baidu.build.hardware.version=1.0ro.baidu.build.software=yi_3.0ro.baidu.build.version.release=2.1ro.product.manufacturer=Baidupersist.sys.emmc=/mnt/sdcard2ro.config.notification_sound=Ding.mp3ro.config.ringtone=Echo.mp3ro.config.alarm_alert=alarm.mp3删除以下几个属性ro.operator.optr=ro.operator.spec=ro.operator.seg=移植boot.imgboot.img 启动镜像必须使用自己手机的。
csvM X28_DDR2_regis…1.xlsx101.25KB16100: 1*16 32200: 2*32 16400: 4*16 16800: 8*16 32400: 4*32 16160: 16*16表格信息:*上面需要准确填写的是行列地址总线宽度,bank数,CS数,数据总线宽度,时钟频率。
*tFAW不小于tRRD4倍,所以设置40ns。
*tRPA:如果数据手册不能找到tRPA,那么这么位置填入tRP。
*CASLAT:设置CAS LATCH周期,这个周期在ddr初始化时由ddr控制器对ddr设置。
*根据信号线计算ram大小,如下2 ^ (1cs + 3bank + 15row + 12col + 1datapath width) = 4GB:2、下载源码与建立baseline:2.1 源码下载略。
2.2 选择一个相近的平台,编写试编译通过:./setenv.shmake mx28evk_defconfigmake u-boot.sb*这里的sb文件是加密文件,而elftosb工具生成的可以通过-z参数选择是否加密。
*如果编译器是32位,但是系统是64位,那么安装32位兼容库即可:sudo apt install libc6-dev-i386 lib32z12.3 复制文件与修改配置:cp configs/mx28evk_defconfig configs/imx280a_defconfigcp configs/mx28evk_defconfig configs/imx280a_mmc_defconfigmkdir board/zlg/ && cp -rf board/freescale/mx28evk/ board/zlg/imx280a/ mv board/zlg/imx280a/mx28evk.c board/zlg/imx280a/imx280a.cvim board/zlg/imx280a/Kconfigvim board/zlg/imx280a/Makefilecp include/configs/mx28evk.h include/configs/imx280a.hvim include/configs/imx280a.h*vim ./arch/arm/include/asm/mach-types.h*从mx28手册可以得到内存起始物理地址:*删掉FEC,USB,SPI,LCD及额外环境变量的配置。
s5pv210 uboot-2012-10的移植s5pv210 uboot-2012-10移植(一) 之分析Alex Ling的linaro-2011.10 for mini210好久好久前就买了s5pv210的开发板,一直都是东搞搞西搞搞,一点收获也没有,这次下决心来移植最新的uboot到u-boot-2012.10上,并通过这个博客记录下来以防时间长给忘了,我的开发板是QT210的。
s5pv210的启动分为BL0,BL1,BL2,BL0是出厂的时候就固化在IROM里的,所以我们的uboot就要实现BL1和BL2,BL1在uboot里叫做u-boot-spl.bin,BL2就是我们很熟悉的u-boot.bin了。
在移植之前,我们先看下Alex Ling 的linaro-2011.10 for mini210的UBOOT是怎么实现的。
这里主要还是分析SPL部分,u-boot.bin是如何生成的现在资料很多,也很复杂,我这个菜鸟也是一知半解的,所以就不分析了。
1.顶层的Makefile,从中可以知道,我们要想生成u-boot-spl.bin就必须配置COFNIG_SPL,那么u-boot-spl.bin依赖什么呢,我们继续[plain]view plaincopy1.ALL-$(CONFIG_SPL) += $(obj)spl/u-boot-spl.bin2.3.all: $(ALL-y)搜索发现,是进入到uboot顶层目录的spl目录下执行Makefile的[plain]view plaincopy1.$(obj)spl/u-boot-spl.bin: depend2. $(MAKE) -C spl all2.打开spl/Makefile分析,一开始就给我们导出CONFIG_SPL_BUILD[plain]view plaincopy1.CONFIG_SPL_BUILD := y2.export CONFIG_SPL_BUILD然后分析目标,因为我们的平台是三星的,所以,会有两个目标,一个是不带头信息的u-boot-spl.bin,一个是$(obj)$(BOARD)-spl.bin。
TP LINK 703N V1.X 4M 原版无拆机无TTL刷不死u-boot 教程703N V1.6测试OK1.将机器恢复出厂设置2.在机器的升级界面刷入openwrt-ar71xx-generic-tl-wr703n-v1-squashfs-factory固件,如果已经是openwrt的请刷openwrt-ar71xx-generic-tl-wr703n-v1-squashfs-sysupgrade3.升级成功后浏览器登陆路由修改初始密码〔同时会关闭telnet而开启SSH〕4.secureCRT登陆路由〔用户名root,密码为你刚刚修改的密码〕,运行cd /tmp,再运行dd if=/dev/mtd0 of=/tmp/uboot.bin(备份原始uboot),以及dd if=/dev/mtd4 of=/tmp/art.bin(备份原始art)5.winscp登陆路由进入/tmp将备份的原厂uboot及art拷贝到电脑进行备份。
6.winscp删除uboot.bin及art.bin,另外将不死uboot(不死uboot-tplink703n-EC-88-8F-12-34-56-20220817.bin)通过winscp拷贝到路由的/tmp7.secureCRT运行cd /tmp进入/tmp目录,再运行mtd -rwrite uboot-tplink703n-EC-88-8F-12-34-56-20220817.bin u-boot,刷完机器会自动重启,此时机器已经是不死uboot了8.重新开启路由电源前,按住路由上面的reset开关,等机器的LED灯闪烁第四次的时候松开手,机器进入刷机模式,可以升级固件,uboot等,注意,固件大小应该是 3.75MB(3,932,160 字节), uboot大小是128KB。
以上就是升级过程。
uboot一、uboot是ppcboot和armboot合并而成,现在主流的bootloader为uboot和redboot二、bootm addr_kernel addr_initrd三、移植uboot时最好(一定)要找到一个自己板子的原形(即自己的板子是在这个板子上做一些修改而来的)的版本,这样就可以事半功倍。
这样要修改的地方就比较少,也比较容易了。
uboot支持很多平台,与一个具体平台相关的主要有三个地方:1、./include/configs/xxxxx.h, 主要定义了flash、sdram的起始地址等信息,一般要修改flash的起始地址、大小,有时候会有位宽等。
2、./board/xxxxx/*,这个目录下主要有两三个.c文件,主要为该平台的初始化和flash操作的函数。
有时候flash的操作需要修改,不过一般都是找一个现有的支持该flash的驱动,一般情况在uboot 别的./board/平台下就会有现成的,拷贝过了就可以了。
3、./cpu/xxxxxx/arch_xxx/xxxxxx/*, 一般是此cpu的初始等函数。
四、具体移植的时候最多涉及到的会是./include/configs/xxxx.h,如果有现成的平台(uboot现在支持绝大部分我们常用的平台),可能只需要对着原来的xxxx.h文件,修改几个我们在硬件上修改了的地方,一般会是flash的起始地址、大小;内存大小(内存的起始地址应该都是0);uboot设置信息保存的地址和长度;console 口和它的波特率;默认的设置;uboot的入口地址等(具体情况可能会有一些变化),如果不是从相同的平台移植,可能会比较麻烦,因为这时候要修改一些和此cpu相关的一些寄存器、频率和内存等硬件方面的东西了(也在这个xxxx.h中),虽然这时改动的地方也不多,但是会很痛苦,因为经常不知道要改哪里或者改为多少。
所以可能需要参考cpu的datasheet和到网上找一些资料了并且慢慢试了。
U-BOOT-2016.07移植(第三篇) 代码重定位2016年09月08日19:32:08Funkunux阅读数4101版权声明:本文为[FUNKUNUX]原创文章,转载请注明原文地址。
https:///funkunho/article/details/52474373U-BOOT-2016.07移植(第一篇) 初步分析U-BOOT-2016.07移植(第二篇) 添加单板U-BOOT-2016.07移植(第三篇) 代码重定位目录•U-BOOT-201607移植第一篇初步分析•U-BOOT-201607移植第二篇添加单板•U-BOOT-201607移植第三篇代码重定位•目录o分析board_init_f▪ 1 common board_fc 1035 1067▪ 2 common board_fc 829 1033▪ 3 内存分配图o分析relocate_code▪ 1 archarmlibcrt0S 95 122▪ 2 archarmlibrelocateS 79 1301. 分析board_init_f()在我写的第一篇文章中,已经对u-boot-2016.07的启动流程有了初步的了解,现在我们开始分析crt0.S中,_main 函数在设置好栈和GD后调用的board_init_f(),从而了解u-boot是如何对内存空间进行分配,然后进行重定位的。
1.1 common/ board_f.c (1035 ~ 1067):void board_init_f(ulong boot_flags){#ifdef CONFIG_SYS_GENERIC_GLOBAL_DATA //没有定义这个宏,不关心/** For some archtectures, global data is initialized and used before* calling this function. The data should be preserved. For others,* CONFIG_SYS_GENERIC_GLOBAL_DATA should be defined and use the stack* here to host global data until relocation.*/gd_t data;gd = &data;/** Clear global data before it is accessed at debug print* in initcall_run_list. Otherwise the debug print probably* get the wrong vaule of gd->have_console.*/zero_global_data();#endifgd->flags = boot_flags;gd->have_console = 0;if (initcall_run_list(init_sequence_f)) //调用initcall_run_list函数,//这个函数在lib/initcall.c中定义,//作用就是调用init_sequence_f函数数组中//存放的各初始化函数hang();#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \ //我们有定义CONFIG_ARM,不关心!defined(CONFIG_EFI_APP)/* NOTREACHED - jump_to_copy() does not return */hang();#endif}• 1• 2••36 下面我们分析init_sequence_f数组中的各函数1.2 common/ board_f.c (829 ~ 1033):这里我直接将被宏开关关掉的函数剔除掉,留下最终会被调用的函数:static init_fnc_t init_sequence_f[] = {setup_mon_len, //gd->mon_len = (ulong)&__bss_end - CONFIG_SYS_MONITOR_BASE;//CONFIG_SYS_MONITOR_BASE = _start = 0//设置gd->mon_len为编译出来的u-boot.bin+bss段的大小arch_cpu_init, /* basic arch cpu dependent setup *///这个函数应该是留给移植人员使用的,里面什么都没做,而且被__weak修饰,//所以我们可以在别的地方重新定义这个函数来取代它arch_cpu_init_dm, //同上mark_bootstage, /* need timer, go after init dm */#if defined(CONFIG_BOARD_EARLY_INIT_F)board_early_init_f, //在smdk2440.c中定义,初始化CPU时钟和各种IO(待修改)#endif/* TODO: can any of this go into arch_cpu_init()? */#if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || \defined(CONFIG_BLACKFIN) || defined(CONFIG_NDS32) || \defined(CONFIG_SPARC)timer_init, /* 初始化定时器*/#endifenv_init, /* 初始化环境变量*/init_baud_rate, /* 初始化波特率为: 115200 */serial_init, /* 设置串口通讯*/console_init_f, /* stage 1 init of console */display_options, /* 打印版本信息,你可以修改include/version.h中的CONFIG_IDENT_STRING选项,* 加入你的身份信息*/display_text_info, /* show debugging info if required *///打印bss段信息及text_base,//需要#define DEBUGprint_cpuinfo, /* 打印CPUID和时钟频率*/INIT_FUNC_WATCHDOG_INITINIT_FUNC_WATCHDOG_RESETannounce_dram_init, //输出"DRAM: " 然后在下面进行SDRAM参数设置/* TODO: unify all these dram functions? */#if defined(CONFIG_ARM) || defined(CONFIG_X86) || defined(CONFIG_NDS32) || \defined(CONFIG_MICROBLAZE) || defined(CONFIG_AVR32)dram_init, /* 在smdk2440.c中定义,配置SDRAM大小,大家可根据实际进行修改*/#endifINIT_FUNC_WATCHDOG_RESETINIT_FUNC_WATCHDOG_RESETINIT_FUNC_WATCHDOG_RESET/** Now that we have DRAM mapped and working, we can* relocate the code and continue running from DRAM.** Reserve memory at end of RAM for (top down in that order):* - area that won't get touched by U-Boot and Linux (optional)* - kernel log buffer* - protected RAM* - LCD framebuffer* - monitor code* - board info struct*/setup_dest_addr, //将gd->relocaddr、gd->ram_top指向SDRAM最顶端reserve_round_4k, //gd->relocaddr 4K对齐#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) && \defined(CONFIG_ARM)reserve_mmu, //gd->arch.tlb_size = PGTABLE_SIZE; 预留16kb的MMU页表//gd->relocaddr -= gd->arch.tlb_size;//gd->relocaddr &= ~(0x10000 - 1); 64kb对齐//gd->arch.tlb_addr = gd->relocaddr;#endifreserve_trace,#if !defined(CONFIG_BLACKFIN)reserve_uboot, //gd->relocaddr -= gd->mon_len; 一开始设置的u-boot.bin + bss段长度//gd->relocaddr &= ~(4096 - 1); 4k对齐,这是最终重定位地址//gd->start_addr_sp = gd->relocaddr; 设置重定位后的栈指针#endif#ifndef CONFIG_SPL_BUILDreserve_malloc, //gd->start_addr_sp = gd->start_addr_sp - TOTAL_MALLOC_LEN;//预留4MB MALLOC内存池reserve_board, //gd->start_addr_sp -= sizeof(bd_t); 预留空间给重定位后的gd_t->bd//gd->bd = (bd_t *)gd->start_addr_sp; 指定重定位bd地址//memset(gd->bd, '\0', sizeof(bd_t)); 清零#endifsetup_machine, //gd->bd->bi_arch_number = CONFIG_MACH_TYPE;//对于S3C2440来说就是MACH_TYPE_S3C2440 (arch/arm/include/asm/mach-types.h) reserve_global_data, //gd->start_addr_sp -= sizeof(gd_t);//gd->new_gd = (gd_t *)gd->start_addr_sp; 指定重定位GD地址reserve_fdt,reserve_arch,reserve_stacks, //gd->start_addr_sp -= 16; 栈指针16字节对齐//gd->start_addr_sp &= ~0xf;setup_dram_config, //gd->bd->bi_dram[i].start = addr; 设置sdram地址和大小//gd->bd->bi_dram[i].size = size;show_dram_config, //打印SDRAM大小,与上面的announce_dram_init相对应display_new_sp, //若#define DEBUG 则打印新的栈地址INIT_FUNC_WATCHDOG_RESETreloc_fdt,setup_reloc, //gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE; 计算重定位偏移地址//memcpy(gd->new_gd, (char *)gd, sizeof(gd_t));//将原来的gd复制到重定位后的gd地址上去NULL,};• 1• 2• 3• 4• 5• 6•7•8•9•10•11•12•13•14•15•16•17•18•19•20•21•22•23•24•25•26•27•28•29•30•31•32•33•34•35•36•37•38•39•40•41•42•44 •45 •46 •47 •48 •49 •50 •51 •52 •53 •54 •55 •56 •57 •58 •59 •60 •61 •62 •63 •64 •65 •66 •67 •68 •69 •70 •71 •72 •73 •74 •75 •76 •77 •78 •79 •80 •81 •82 •83 •84 •85 •86 •87 •88 •89 •90•92•93•94 1.3 内存分配图根据1.1、1.2的分析,可以得出以下的内存分配图:2. 分析relocate_code2.1 arch/arm/lib/crt0.S (95 ~ 122)同样,这里将无关紧要的宏开关去掉ldr sp, [r9, #GD_START_ADDR_SP] /* sp = gd->start_addr_sp */bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ldr r9, [r9, #GD_BD] /* r9 = gd->bd */sub r9, r9, #GD_SIZE /* new GD is below bd *//** 上面这一段代码是将board_init_f中设置好的start_addr_sp地址值赋给栈指针,使其指向重定位后的栈顶* 8字节对齐后,将r9设为新的GD地址(对照内存分配图: gd地址=bd地址-sizeof(gd_t))*/adr lr, here //设置返回地址为下面的here,重定位到sdram后返回here运行ldr r0, [r9, #GD_RELOC_OFF] /* r0 = gd->reloc_off 取重定位地址偏移值*/add lr, lr, r0 //返回地址加偏移地址等于重定位后在sdram中的here地址ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr 传入参数为重定位地址*/b relocate_code //跳到arch/arm/lib/relocate.S中执行here: //返回后跳到sdram中运行• 1• 2• 3• 4• 52.2 arch/arm/lib/relocate.S (79 ~ 130)ENTRY(relocate_code)ldr r1, =__image_copy_start /* r1 <- SRC &__image_copy_start 这是u-boot.bin起始链接地址,* 定义在u-boot.lds中(编译后在顶层目录生成)* 原文件是arch/arm/cpu/u-boot.lds,大家可以自行分析*/subs r4, r0, r1/* r4 <- relocation offset r0是crt0.S中传入的重定位地址,* 这里是算出偏移值*/beq relocate_done /* skip relocation 如果r4为0,则认为重定位已完成*/ldr r2, =__image_copy_end /* r2 <- SRC &__image_copy_end 同第一条指令,在u-boot.lds中定义*/ copy_loop:/* r1是源地址__image_copy_start,r0是目的地址relocaddr,* size = __image_copy_start - __image_copy_end*/ldmia r1!, {r10-r11} /* copy from source address [r1] */stmia r0!, {r10-r11} /* copy to target address [r0] */cmp r1, r2/* until source end address [r2] */blo copy_loop/** fix .rel.dyn relocations 定义了"-PIE"选项就会执行下面这段代码* 目的是为了让位置相关的资源(代码、参数、变量)的地址在重定位后仍然能被寻址到,所以让他们加上偏移地址,* 即等于他们重定位后的真正地址* 这些"存放(资源的地址)的地址" 存放在.rel.dyn这个段中,每个参数后面都会跟着一个起标志作用的参数,* 如果这个标志参数为23,即0x17,则表示这个(资源的地址) 是位置相关的,需要加上重定位偏移值* 这一段代码首先让.rel.dyn这个段中的存放的地址值加上偏移值,使其在sdram中取出(资源的地址)* 然后再让这些(资源的地址)加上偏移值,存回rel.dyn中存放这些地址的地址中,* 比较拗口,抽象,大家多研究研究代码,或看看我下面发的图来帮助理解*/ldr r2, =__rel_dyn_start /* r2 <- SRC &__rel_dyn_start */ldr r3, =__rel_dyn_end /* r3 <- SRC &__rel_dyn_end */fixloop:ldmia r2!, {r0-r1} /* (r0,r1) <- (SRC location,fixup) r0为"存放(资源的地址)的地址",* 这个地址里存放的是需要用到的(资源的地址),r1为标志值*/and r1, r1, #0xff //r1取低八位cmp r1, #23 /* relative fixup? 和23比较,如果相等则继续往下,否则跳到fixnext */bne fixnext/* relative fix: increase location by offset */add r0, r0, r4 //r4存放的是重定位偏移值,r0这个地址存放的是位置相关的(资源的地址),//r4+r0即为重定位后的"存放(资源的地址)的地址",ldr r1, [r0] //在sdram中取出还未修改的(资源的地址)add r1, r1, r4 //加上偏移值str r1, [r0] //存回去fixnext: //跳到下一个继续检测是否需要重定位cmp r2, r3blo fixlooprelocate_done:/* ARMv4- don't know bx lr but the assembler fails to see that */#ifdef __ARM_ARCH_4__mov pc, lr //ARM920T用的汇编指令集是ARMv4,所以使用这条返回指令,//返回重定位后的here标志#elsebx lr#endifENDPROC(relocate_code)• 1• 2 ••原谅博主表达能力太渣,我发一下图吧到这里,代码重定位的分析就结束了,下一篇内容将开始修改代码使u-boot能从nor flash启动。
本文档采用了Uboot1.1.6中的nandflash的新驱动,没有用nand_legacy,同时添加了yaffs文件系统烧写的功能,并且对网上一些移植文档的不妥,缺少之处进行补充。
如有不妥之处,欢迎指正。
联系方式:edaworld@零、移植前说明:1. 工作环境:Fedora 7 ,内核2.6.21交叉编译器:Arm-linux-gcc 3.3.2目标板:优龙FS2410,NAND Flash:64M K9F1208,NOR Flash:2M SST39VF1601 (本次移植不包含NOR Flash 支持), RAM 64M ,CS8900Q32. 下载源码,建立工作目录u-boot的源码可以从以下网址下载:/u-boot/u-boot-1.1.6.tar.bz2建立工作目录:mkdir /bootloadercd /bootloader把下载的源码拷贝到该目录,解压;tar jxvf u-boot-1.1.6.tar.bz2注意使用交叉编译器为3.3.2版本一、移植步骤如下:(1)、建立自己fs2410开发板的配置cd /u-boot-1.1.61)# cp –r board/smdk2410 board/fs24102)# cp include/configs/smdk2410.h include/configs/fs2410.hfs2410.h是开发板的配置文件,他包括开发板的CPU、系统时钟、RAM、FLASH系统及其他相关的配置信息,由于u-boot已经支持三星的SMDK2410开发板,所以移植的时候直接拷贝SMDK2410的配置文件,做相应的修改即可。
由于Uboot对SMDK2410板的NAND Flash初始化部分没有写,即lib_arm/board.c中的start_armboot函数中有这么一句:#if (CONFIG_COMMANDS & CFG_CMD_NAND)puts ("NAND:");nand_init(); /* go init the NAND */#endif但是在board/smdk2410目录下源文件中都没有定义nand_init这个函数。
(一)U-Boot启动过程--详细版的完全分析我们知道,bootloader是系统上电后最初加载运行的代码。
它提供了处理器上电复位后最开始需要执行的初始化代码。
在PC机上引导程序一般由BIOS开始执行,然后读取硬盘中位于MBR(Main Boot Record,主引导记录)中的Bootloader(例如LILO或GRUB),并进一步引导操作系统的启动。
然而在嵌入式系统中通常没有像BIOS那样的固件程序,因此整个系统的加载启动就完全由bootloader来完成。
它主要的功能是加载与引导内核映像一个嵌入式的存储设备通过通常包括四个分区:第一分区:存放的当然是u-boot第二个分区:存放着u-boot要传给系统内核的参数第三个分区:是系统内核(kernel)第四个分区:则是根文件系统如下图所示:u-boot是一种普遍用于嵌入式系统中的Bootloader。
Bootloader介绍Bootloader是进行嵌入式开发必然会接触的一个概念,它是嵌入式学院<嵌入式工程师职业培训班>二期课程中嵌入式linux系统开发方面的重要内容。
本篇文章主要讲解Bootloader 的基本概念以及内部原理,这部分内容的掌握将对嵌入式linux系统开发的学习非常有帮助!Bootloader的定义:Bootloader是在操作系统运行之前执行的一小段程序,通过这一小段程序,我们可以初始化硬件设备、建立内存空间的映射表,从而建立适当的系统软硬件环境,为最终调用操作系统内核做好准备。
意思就是说如果我们要想让一个操作系统在我们的板子上运转起来,我们就必须首先对我们的板子进行一些基本配置和初始化,然后才可以将操作系统引导进来运行。
具体在Bootloader中完成了哪些操作我们会在后面分析到,这里我们先来回忆一下PC的体系结构:PC机中的引导加载程序是由BIOS和位于硬盘MBR中的OS Boot Loader(比如LILO和GRUB等)一起组成的,BIOS在完成硬件检测和资源分配后,将硬盘MBR中的Boot Loader读到系统的RAM中,然后将控制权交给OS Boot Loader。
[uboot](第五章)uboot流程——uboot启动流程/ooonebook/article/details/53070065以下例⼦都以project X项⽬tiny210(s5pv210平台,armv7)为例[uboot] uboot流程系列:建议先看《[project X] tiny210(s5pv210)上电启动流程(BL0-BL2)》,根据例⼦了解⼀下上电之后的BL0\BL1\BL2阶段,以及各个阶段的运⾏位置,功能。
建议可以和《[uboot] (番外篇)global_data介绍》和《[uboot] (番外篇)uboot relocation介绍》结合起来看。
=================================================================================⼀、uboot说明1、uboot要做的事情CPU初始刚上电的状态。
需要⼩⼼的设置好很多状态,包括cpu状态、中断状态、MMU状态等等。
其次,就是要根据硬件资源进⾏板级的初始化,代码重定向等等。
最后,就是进⼊命令⾏状态,等待处理命令。
在armv7架构的uboot,主要需要做如下事情arch级的初始化关闭中断,设置svc模式禁⽤MMU、TLB关键寄存器的设置,包括时钟、看门狗的寄存器板级的初始化堆栈环境的设置代码重定向之前的板级初始化,包括串⼝、定时器、环境变量、I2C\SPI等等的初始化进⾏代码重定向代码重定向之后的板级初始化,包括板级代码中定义的初始化操作、emmc、nand flash、⽹络、中断等等的初始化。
进⼊命令⾏状态,等待终端输⼊命令以及对命令进⾏处理上述⼯作,也就是uboot流程的核⼼。
2、疑问在前⾯的⽂章中虽然已经说明了,在spl的阶段中已经对arch级进⾏了初始化了,为什么uboot⾥⾯还要对arch再初始化⼀遍?回答:spl对于启动uboot来说并不是必须的,在某些情况下,上电之后uboot可能在ROM上或者flash上开始执⾏⽽并没有使⽤spl。
u-boot 移植步骤详解(必会)1 U-Boot简介U-Boot,全称Universal Boot Loader,是遵循GPL条款的开放源码项目。
从FADSROM、8xxROM、PPCBOOT逐步发展演化而来。
其源码目录、编译形式与Linux内核很相似,事实上,不少U-Boot源码就是相应的Linux内核源程序的简化,尤其是一些设备的驱动程序,这从U-Boot源码的注释中能体现这一点。
但是U-Boot不仅仅支持嵌入式Linux系统的引导,当前,它还支持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项目的开发目标,即支持尽可能多的嵌入式处理器和嵌入式操作系统。
就目前来看,U-Boot对PowerPC系列处理器支持最为丰富,对Linux的支持最完善。
其它系列的处理器和操作系统基本是在2002年11 月PPCBOOT 改名为U-Boot后逐步扩充的。
从PPCBOOT向U-Boot的顺利过渡,很大程度上归功于U-Boot的维护人德国DENX软件工程中心Wolfgang Denk[以下简称W.D]本人精湛专业水平和持着不懈的努力。
当前,U-Boot项目正在他的领军之下,众多有志于开放源码BOOT LOADER移植工作的嵌入式开发人员正如火如荼地将各个不同系列嵌入式处理器的移植工作不断展开和深入,以支持更多的嵌入式操作系统的装载与引导。
选择U-Boot的理由:①开放源码;②支持多种嵌入式操作系统内核,如Linux、NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS;③支持多个处理器系列,如PowerPC、ARM、x86、MIPS、XScale;④较高的可靠性和稳定性;④较高的可靠性和稳定性;⑤高度灵活的功能设置,适合U-Boot调试、操作系统不同引导要求、产品发布等;⑥丰富的设备驱动源码,如串口、以太网、SDRAM、FLASH、LCD、NVRAM、EEPROM、RTC、键盘等;⑦较为丰富的开发调试文档与强大的网络技术支持;2 U-Boot主要目录结构- board 目标板相关文件,主要包含SDRAM、FLASH驱动;- common 独立于处理器体系结构的通用代码,如内存大小探测与故障检测;- cpu 与处理器相关的文件。
如mpc8xx子目录下含串口、网口、LCD驱动及中断初始化等文件;- driver 通用设备驱动,如CFI FLASH驱动(目前对INTEL FLASH支持较好)- doc U-Boot的说明文档;- examples可在U-Boot下运行的示例程序;如hello_world.c,timer.c;- include U-Boot头文件;尤其configs子目录下与目标板相关的配置头文件是移植过程中经常要修改的文件;- lib_xxx 处理器体系相关的文件,如lib_ppc, lib_arm目录分别包含与PowerPC、ARM 体系结构相关的文件;- net 与网络功能相关的文件目录,如bootp,nfs,tftp;- post 上电自检文件目录。
尚有待于进一步完善;- rtc RTC驱动程序;- tools 用于创建U-Boot S-RECORD和BIN镜像文件的工具;3 U-Boot支持的主要功能U-Boot可支持的主要功能列表系统引导支持NFS挂载、RAMDISK(压缩或非压缩)形式的根文件系统支持NFS挂载、从FLASH中引导压缩或非压缩系统内核;基本辅助功能强大的操作系统接口功能;可灵活设置、传递多个关键参数给操作系统,适合系统在不同开发阶段的调试要求与产品发布,尤对Linux支持最为强劲;支持目标板环境参数多种存储方式,如FLASH、NVRAM、EEPROM;CRC32校验,可校验FLASH中内核、RAMDISK镜像文件是否完好;设备驱动串口、SDRAM、FLASH、以太网、LCD、NVRAM、EEPROM、键盘、USB、PCMCIA、PCI、RTC等驱动支持;上电自检功能SDRAM、FLASH大小自动检测;SDRAM故障检测;CPU型号;特殊功能XIP内核引导;4 移植前的准备(1)、首先读读uboot自带的readme文件,了解了一个大概。
(2)、看看common.h,这个文件定义了一些基本的东西,并包含了一些必要的头文件。
再看看flash.h,这个文件里面定义了flash_info_t为一个struct。
包含了flash的一些属性定义。
并且定义了所有的flash的属性,其中,AMD的有:AMD_ID_LV320B,定义为“#define AMD_ID_LV320B 0x22F922F9”。
(3)、对于“./borad/at91rm9200dk/flash.c”的修改,有以下的方面:“void flash_identification(flash_info_t *info)”这个函数的目的是确认flash的型号。
注意的是,这个函数里面有一些宏定义,直接读写了flash。
并获得ID号。
(4)、修改:”./board/at91rm9200dk/config.mk”为TEXT_BASE=0x21f80000 为TEXT_BASE=0x21f00000 (当然,你应该根据自己的板子来修改,和一级boot的定义的一致即可)。
(5)、再修改”./include/configs/at91rm9200dk.h”为修改flash和SDRAM的大小。
(6)、另外一个要修改的文件是:./borad/at91rm9200dk/flash.c。
这个文件修改的部分比较的多。
a.首先是OrgDef的定义,加上目前的flash。
b.接下来,修改”#define FLASH_BANK_SIZE 0x200000”为自己flash的容量c.在修改函数flash_identification(flash_info_t * info)里面的打印信息,这部分将在u-boot启动的时候显示。
d.然后修改函数flash_init(void)里面对一些变量的赋值。
e.最后修改的是函数flash_print_info(flash_info_t * info)里面实际打印的函数信息。
f.还有一个函数需要修改,就是:“flash_erase”,这个函数要检测先前知道的flash类型是否匹配,否则,直接就返回了。
把这里给注释掉。
(7)、接下来看看SDRAM的修改。
这个里面对于“SIZE”的定义都是基于字节计算的。
只要修改”./include/configs/at91rm9200dk.h”里面的“#define PHYS_SDRAM_SIZE 0X200000”就可以了。
注意,SIZE是以字节为单位的。
(8)、还有一个地方要注意就是按照目前的设定,一级boot把u_boot加载到了SDRAM的空间为:21F00000 -> 21F16B10,这恰好是SDRAM的高端部分。
另外,BSS为21F1AE34。
(9)、编译后,可以写入flash了。
a.压缩这个u-boot.bin“gzip –c u-boot.bin > u-boot.gz”压缩后的文件大小为:43Kbytesb.接着把boot.bin和u-boot.gz烧到flash里面去。
Boot.bin大约11kBytes,在flash的0x1000 0000 ~ 0x1000 3fff5 U-Boot移植过程①获得发布的最新版本U-Boot源码,与Linux内核源码类似,也是bzip2的压缩格式。
可从U-Boot的官方网站/projects/U-Boot上获得;②阅读相关文档,主要是U-Boot源码根目录下的README文档和U-Boot官方网站的DULG(The DENX U-Boot and Linux Guide)文档http://www.denx.de/twiki/bin/view/DULG/Manual。
尤其是DULG文档,从如何安装建立交叉开发环境和解决U-Boot移植中常见问题都一一给出详尽的说明;③订阅U-Boot用户邮件列表/lists/listinfo/u-boot-users。
在移植U-Boot过程中遇有问题,在参考相关文档和搜索U-Boot-User邮件档案库/mailarchive/forum.php?forum_id=12898仍不能解决的情况下,第一时间提交所遇到的这些问题,众多热心的U-Boot开发人员会乐于迅速排查问题,而且很有可能,W.D本人会直接参与指导;④在建立的开发环境下进行移植工作。
绝大多数的开发环境是交叉开发环境。
在这方面,DENX 和MontaVista均提供了完整的开发工具集;⑤在目标板与开发主机间接入硬件调试器。
这是进行U-Boot移植应当具备且非常关键的调试工具。
因为在整个U-Boot的移植工作中,尤其是初始阶段,硬件调试器是我们了解目标板真实运行状态的唯一途径。
在这方面,W.D本人和众多嵌入式开发人员倾向于使用BDI2000。
一方面,其价格不如ICE调试器昂贵,同时其可靠性高,功能强大,完全能胜任移植和调试U-Boot。
另外,网上也有不少关于BDI2000调试方面的参考文档。
⑥如果在参考开发板上移植U-Boot,可能需要移除目标板上已有的BOOT LOADER。
可以根据板上BOOT LOADER的说明文档,先着手解决在移除当前BOOT LOADER的情况下,如何进行恢复。
以便今后在需要场合能重新装入原先的BOOT LOADER。
6. U-Boot移植方法当前,对于U-Boot的移植方法,大致分为两种。
一种是先用BDI2000创建目标板初始运行环境,将U- Boot镜像文件u-boot.bin下载到目标板RAM中的指定位置,然后,用BDI2000进行跟踪调试。
其好处是不用将U-Boot镜像文件烧写到FLASH中去。
但弊端在于对移植开发人员的移植调试技能要求较高,BDI2000的配置文件较为复杂。
另外一种方法是用BDI2000先将U-Boot 镜像文件烧写到FLASH中去,然后利用GDB和BDI2000进行调试。