为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

U-boot笔记

2011-06-28 35页 doc 2MB 25阅读

用户头像

is_425733

暂无简介

举报
U-boot笔记U-BOOT笔记 U-BOOT笔记(tegra 2) 1.内存分布图: CONFIG_SYS_INIT_RAM_ADDR gd_t gd GENERATED_GBL_DATA_SIZE 对齐到8边界 对齐15边界后可能多余的部分 leave 3 words for abort-stack (12Byte) 对齐到8边界 CONFIG_USE_IRQ (8KB) gd_t Global Data gd->irq_sp bd_t Board Info gd->bd TOTAL_MALLOC_LEN (4MB) U-Boot cod...
U-boot笔记
U-BOOT笔记 U-BOOT笔记(tegra 2) 1.内存分布图: CONFIG_SYS_INIT_RAM_ADDR gd_t gd GENERATED_GBL_DATA_SIZE 对齐到8边界 对齐15边界后可能多余的部分 leave 3 words for abort-stack (12Byte) 对齐到8边界 CONFIG_USE_IRQ (8KB) gd_t Global Data gd->irq_sp bd_t Board Info gd->bd TOTAL_MALLOC_LEN (4MB) U-Boot code 对齐到4KB边界 CONFIG_LCD (根据屏幕分辨率来分配) 液晶显示器 对齐到4KB边界 gd->fb_base CONFIG_VFD (7KB) 真空荧光显示器 对齐到4KB边界 gd->fb_base TLB table (16KB) 对齐到64KB边界 gd->tlb_addr CONFIG_PRAM (512KB) LOGBUFF_RESERVE (20KB) CONFIG_SYS_MEM_TOP_HIDE (1MB) | | | | | | | | | | 0 40MB gd 44MB addr_sp id addr ram size sp gd->start_addr_sp gd->relocaddr |----- CONFIG_PRELOADER ----| 2. void relocate_code (addr_sp, gd, addr_moni)分析: 函数调用如下: relocate_code (addr_sp, id, addr); 重定位知识: 重定位(.rel.xxx)条目: 1) 它会包含一个符号表中一个条目的索引,因为这样我们才知道它具体是哪个符号需要被重定位的; 2) 它会包含一个 .text section 中的地址单元的偏移值。原本这个偏移值处的地址单元里面应该存放着 call 指令的操作数。对上面来说,也就是函数 sum_func 的地址,但是目前这个地址汇编器还不知道。 3) 它还会包含一个tag,以指明该重定位属于何种类型。 结构中r_offset 对于可重定位文件来说,就是地址单元的偏移值(下面的b条);另外对可执行文件或者动态库来说,就是该地址单元的运行时地址。 下面a条中的符号表内索引和c条中的类型,一起构成了结构中的字段 r_info。 符号表(.symtab)条目: a) 在可重定位文件中,如果该符号对应的section index(上面的Ndx)为SHN_COMMON,那么符号的值表示的是该数据的对齐要求,比方上面的变量ch 。 b) 在可重定位文件中,除去上面那条a中定义的符号,对于其他的符号来说,其值表示的是对应section内的偏移值。比方gv_inited变量定义在.data section 的最前面,所以其值为0。 c) 在可执行文件或者动态库中,符号的值表示的是运行时的内存地址。 需要装载的节的类型(sh_type == SHT_REL) 由于烧写到Flash中的是bin文件格式,所以相对elf文件来说,它只包含纯的汇编部分的代码,也就是说他不包含elf中节的辅助数据结构部分(节头数据结构)和运行中用不到的节部分。 BIN文件就是将elf文件中的代码段,数据段,还有一些自定义的段抽取出来做成的一个内存的镜像。因此下面针对各个节加载进来的都是有效数据,不包括节头数据结构。 a.​ 拷贝_start到_bss_start_ofs之间的代码到分配给U-Boot code用的内存地址中 b.​ 对代码进行重定位操作 1)​ 计算U-Boot code运行地址和加载地址的偏移量(供重定位用),delta = 运行内存地址 - _TEXT_BASE 2)​ 获取.dynsym节数据的的加载地址 = _rel_dyn_start_ofs + _TEXT_BASE,即sh_offset指向的起始地址 3)​ 获取.rel.dyn节数据的加载起始地址 = _rel_dyn_start_ofs + _TEXT_BASE,即sh_offset指向的起始地址 4)​ 获取.rel.dyn节数据的加载结束地址 = _rel_dyn_end_ofs + _TEXT_BASE,即sh_offset指向的结束地址 5)​ 把.rel.dyn节条目的r_offset的值+delta = 当前条目r_offset在运行内存中的地址 6)​ 获取.rel.dyn节条目的r_info,再分离出type的值并判断 7)​ 如果是R_ARM_RELATIVE (0x23) A.​ 读取r_offset的值+delta,完成重定位功能 B.​ 保存回重定位后的值到r_offset C.​ 指向下一个条目跳转到5)进行循环处理 8)​ 如果是R_ARM_ABS32 (0x02) A.​ 从r_info里分离出sym index B.​ 根据sym index定位到.dynsym对应的条目位置 C.​ 读取条目中st_value的值+delta,完成重定位功能 D.​ 保存回重定位后的值到r_offset E.​ 指向下一个条目跳转到5)进行循环处理 9)​ 如果是其他 c.​ 初始化.bss段 d.​ 跳转到运行内存空间执行重定位后的代码 3.void board_init_r (gd_t *id, ulong dest_addr)分析 函数调用如下: board_init_r (id, addr); 1)​ 把id保存到全局变量gd中 2)​ 设置重定位完毕标志 3)​ 调用各种初始化函数进行初始化处理 4)​ 正式运行U-Boot 在SkyEye模拟器上运行Linux的配置及编译流程: 1.​ 下载各种需要资源和源代码,准备编译环境到一个工作目录,比如~/tools目录 A.​ 交叉编译工具arm-linux-gcc-4.4.3.tar.gz B.​ Linux内核源代码linux-2.6.25-android-1.0_r1.tar.gz C.​ Skyeye模拟器源代码skyeye-1.3.2_rc1.tar.gz D.​ Skyeye测试包skyeye-testsuite-1.3.2_rc1.tar.gz 2.​ 安装/测试SkyEye tar -xzf skyeye-1.3.2_rc1.tar.gz cd ~/tools/skyeye-1.3.2_rc1 ./configure make lib make sudo make install_lib sudo make install 做完这步会创建/opt/skyeye目录 添加路径到PATH中: gedit ~/.bashrc export PATH=/opt/skyeye/bin:$PATH 用testsuit测试skyeye: tar -xzf skyeye-testsuite-1.3.2_rc1.tar.gz cd ./skyeye-testsuite-1.3.2_rc1/linux/s3c2410/s3c2410x-2.6.36/ skyeye -n -e ./vmlinux -c skyeye.conf  如果能够启动进入sh,那证明skyeye已经正确安装了 3.​ 编译Linux 2.6.36.2内核 tar -xjf linux-2.6.36.2.tar.bz2 cd linux-2.6.36.2 gedit Makefile 修下面两行 ARCH ?= $(SUBARCH) CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%) 改成: ARCH ?= arm CROSS_COMPILE ?= arm-none-linux-gnueabi- make s3c2410_defconfig make menuconfig 选择Kernel Features 把内核用ARM EABI编译。 sourcery g++似乎默认使用EABI来编译busybox,可能是因为toolchain中其他的链接库都用了这种方式来编译吧,所以要求内核支持EABI的系统调用方式。还没找到让sourcery g++以elf的方式来编译busybox,所以这个选项是必须的。 至于 Allow old ABI binaries to run with this kernel (EXPERIMENTAL) (NEW) ,看你需不需要跑一些非EABI方式的应用咯 选择Boot options 这里需要修改的是boot parameter,这个跟skyeye的配置文件有关(配置文件如下)。 我们的系统有32M内存,并且我们让skyeye把initrd加载到地址0x30800000,所以,我们通过启动参数让kernel知道initrd的位置和他的大小 ============================================================================= # skyeye config file for S3C2410X arch:arm cpu: arm920t mach: s3c2410x # physical memory mem_bank: map=M, type=RW, addr=0x30000000, size=0x02000000 # all peripherals I/O mapping area mem_bank: map=I, type=RW, addr=0x48000000, size=0x12000040 uart:mod=stdio load_addr:base=0x30000000, mask=0xFFFFFF load_file: filename=./initrd.img, initrd_start=0x30800000 ================================================================================ 我们顺带解释一下busybox的配置文件 arch:arm --- CPU的架构体系是arm cpu:arm920t --- CPU的核心是arm920t(参考你需要仿真的CPU datasheet,s3c2410是arm920t) mach: s3c2410 ---- CPU的具体型号 mem_bank: map=M, type=RW, addr=0x30000000, size=0x02000000 告诉skyeye内存放置的地址,map=M代表这是内存,type=RW代表可读写,addr指定内存挂载的物理地址的,size是内存的大小。 我们看到,我们在地址0x30000000上放置了一块32M内存芯片的。 mem_bank: map=I, type=RW, addr=0x48000000, size=0x12000040 这里设置了一个从addr=0x48000000开始长度为0x12000040的I/O地址空间。从s3c2410的datasheet可以知道,CPU各个既存器就分布于 从0x48000000开始到0x5A000040的地址空间上,所以,需要告诉skyeye他们的位置。 uart:mod=stdio 这行告诉skyeye把串口输出定位到标准输出。 load_addr:base=0x30000000, mask=0xFFFFFF 这一行指定内核会被加载的地址。编译出来的内核会放在0x30000000开始的一段内存中 load_file: filename=./initrd.img, initrd_start=0x30800000 这一行告诉skyeye需要把文件initrd.img放到地址为0x30800000的位置上,这是我们initrd的镜像。 make 4.​  编译busybox-1.18.5 tar -xjf busybox-1.18.5.tar.bz2 对busybox的Makefile做同样的交叉编译修改: ARCH ?= arm CROSS_COMPILE ?= arm-none-linux-gnueabi- make menuconfig Busybox settings --> Build Options --> 1. 选中静态编译busybox,因为在跟文件系统中,我们暂时不打算放进各种程序动态链接库。 2. 另外,在Cross Complier prefix中,因为我们已经修改过Makefile中的CROSS_COMPILE变量,没有必要在这里重新指定,所以可以留空。 3. Additional CFLAGS必须填入-march=armv4t -mcpu=arm920t,指定CPU的类型。 这跟sourcery g++ lite的交叉编译器有关。如果不指定cpu的版本,sourcery g++ lite会把busybox编译成armv5t的版本。 (怎么知道?用arm-none-linux-gnueabi-readelf -A busybox 看看吧。) 至于其他的选项,自己看着办咯。 make make install 完了以后,busybox会在源码树下创建_install目录作为部署busybox的地方: 5.​  创建根文件系统 创建ext2fs镜像: dd if=/dev/zero of=initrd.img bs=1k count=4096 mke2fs -F -v initrd.img 在镜像中加入busybox工具: 创建一个和_install平行的rootfs目录 sudo mount -o loop initrd.img rootfs/ cd rootfs/ cp -r ../_install/* ./ 此时rootfs目录下的目录结构如下 创建根文件系统的其他目录结构: mkdir proc lib etc dev root home var tmp sys chmod 777 tmp 此时rootfs目录下的目录结构如下 创建必要的设备: cd dev sudo mknod -m 640 ram b 1 1 sudo mknod -m 644 ttySAC0 c 204 64 ram是内存设备,ttySAC0是s3c24xx系列的串口设备,他的主设备号是204,从设备号从64开始。 此时dev目录下的目录结构如下 创建etc/inittab: cd .. gedit etc/inittab 内容如下: ::sysinit:/etc/init.d/rcS ::askfirst:-/bin/sh ::restart:/sbin/init ::ctrlaltdel:/sbin/reboot ::shutdown:/bin/umount -a -r ::shutdown:/sbin/swapoff -a chmod 644 etc/inittab 创建启动脚本 etc/init.d/rcS: mkdir etc/init.d gedit etc/init.d/rcS 内容如下: #!/bin/sh /bin/mount -t proc none /proc /bin/mount -t sysfs none /sys hostname MyArmSys mkdir /var/tmp mkdir /var/log mkdir /var/run  mkdir /var/lock /bin/ash chmod 755 etc/init.d/rcS 此时etc目录下的目录结构如下 最后完成initrd.img: cd .. sudo umount rootfs/ 6.​ 在skyeye中验证测试Linux内核和根文件系统编译结果 创建一个test目录,拷贝编译好的Linux内核文件vmlinux和根文件系统文件initrd.img 创建skyeye的硬件配置文件skyeye.conf,内容如下: arch:arm cpu: arm920t mach: s3c2410x # physical memory mem_bank: map=M, type=RW, addr=0x30000000, size=0x02000000 # all peripherals I/O mapping area mem_bank: map=I, type=RW, addr=0x48000000, size=0x12000040 uart:mod=stdio load_addr:base=0x30000000, mask=0xFFFFFF load_file: filename=./initrd.img, initrd_start=0x30800000 #dbct:state=on 创建一个运行的shell文件run.sh,内容如下: #!/bin/sh skyeye -n -e ./vmlinux -c ./skyeye.conf 此时test目录下的目录结构如下 ./run.sh 运行结果如下图 7.​ 在 arm-linux 的宿主机里配置 NFS Server  sudo apt-get install nfs-kernel-server sudo apt-get install nfs-common 8.​ 编译u-boot-2011.03 tar -jxvf u-boot-latest.tar.bz2 cd u-boot-2011.03 make smdk2410_config 修改include/configs/smdk2410.h文件,添加 #define CONFIG_SYS_SDRAM_BASE             0x00000000 #define CONFIG_SYS_INIT_SP_ADDR              (CONFIG_SYS_TEXT_BASE - GENERATED_GBL_DATA_SIZE) make 编译成功后如图所示 顺利make出u-boot.bin、u-boot、u-boot.srec u-boot.bin是不带调制信息的二进制文件 u-boot是包含调制信息的elf文件,也是本要使用的文件 u-boot.srec是moto的一种文件格式 将编译好的elf文件反汇编成汇编命令如下 arm-linux-objdump -d u-boot > ./u-boot.txt arm-none-linux-gnueabi-objdump -d u-boot > ./u-boot.txt 9.​ 
/
本文档为【U-boot笔记】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索