如何在UBOOT代码中进行内存uboot配置文件

u-boot_smdkv210 分析六:内存分配 - Efronc - 博客园
comments(8)
trackbacks(0)
1.内存分配图(引用网络图片)
2.u-boot映像的地址0并非指物理地址0,由不同的启动方式映射到不同的地址。例如v210是映射到0xD0000000处的irom。
3.TEXT_BASE等指向SDRAM的地址均为虚拟地址。
4.TEXT_BASE为顶层Makefile中定义的,例如三星官方BSP中定义的是0xC3E00000,它是程序实际的链接首地址。
5.SDRAM_BASE被MMU映射在0xC0000000。
6._end和__bss_start为链接脚本文件中最后定义的bss段,在链接时确定,并与u-boot映像编译在一起。
7.在bl1段运行时,u-boot映像被复制到TEXT_BASE开始的地址处。
8.&u-boot分配用户栈顶的代码为:&ldr&r0, _TEXT_BASE&&/* upper 128 KiB: relocated uboot&& */&&&&& 将0xc3e00000加载到r0&sub&r0, r0, #CFG_MALLOC_LEN&/* malloc area&&&&&&&&&&&&&&&&&&&&& */&&&&& r0减去0x4000的malloc域&sub&r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo&&&&&&&&&&&&&&&&&&&&&&& */&&&&& r0减去128字节的全局结构体#if defined(CONFIG_USE_IRQ)&sub&r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)&&&如果用户有使用IRQ,再减去2*4*1024的中断栈空间#endif&sub&sp, r0, #12&&/* leave 3 words for abort-stack&&& */&&&&& 为取址终止异常预留3个字空间后设置好用户sp1468人阅读
bootloader(49)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& (此图是我个人画的不知道有哪些地方有问题,请提出宝贵意见&)
&&&&&&& &如果u-boot是从nandflash启动,硬件会自动把nandflash前0x1000Byte(即4KB)拷贝到&‘Steppingstone’中。&‘Steppingstone’有两个起始地址映射一个是0x0,另一个是0x。这时候PC跳转到0x0地址处,即&‘Steppingstone’起始位置处执行者4KB的代码。这段代码初始化了cpu模式和时钟等等,有必要说下这时候的堆栈初始化这时候sp指针直接指向了0x33f0fffC(即&STACK_BASE+STACK_SIZE-4),fp是0x0也就是‘Steppingstone’的起始地址,。
&&&&&&& 然后又将nandflash存储空间的起始0x0位置的到 0X60000 (#define LENGTH_UBOOT&&&0x60000)拷贝到0x33f80000(TEXT_BASE)。64MB的SDRAM是挂载到NGCS6上的,NGCS6的起始地址是0x,也就是说SDRAM的起始地址是0x,终止地址是0x.因为0x - 0x33f80000 = 0x80000 是大于u-boot的代码空间0x60000&(即LENGTH_UBOOT),0x80000
- 0x60000 = 0x20000,就是说u-boot上的高地址部分有0x20000的空着。
&&&&&& 上面说的‘Steppingstone’中的哪4KB代码拷贝完了自己后并没有立即跳到0x33f80000这个位置去执行,而是接着初始化了SDRAM中的堆栈(这是第二次初始化堆栈了!),怎么初始化的呢?我们看看首先看sp =& _TEXT_BASE - CONFIG_SYS_MALLOC_LEN - CONFIG_SYS_GBL_DATA_SIZE&& &/*& -(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)因为没有用到所以注释掉,这个u-boot没有用到中断&
*/& - 12(这个12是leave 3 words for abort-stack)= 0x33f80000 - (0x10000 + 0x4000) - 0x80 -& 0xc = 0x33f6bf74(sp 没有设置)。.rodata、.data、.got(这是什么??先放着)、.u_boot_cmd、.bss区是在arch/arm/cpu/arm920t/u-boot.lds中定义的,貌似没有具体值,这些是在u-boot代码段后面,紧贴在0x33fe0000前面。
&&&&&& 在start_armboot中有这个数据结构指针:gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t)),按上面的分析它在全局数据区(global_data)的顶部,这个指针指向的数据结构global_data如下:
typedef struct
global_data {
unsigned long
/* serial_init() was called */
unsigned long
/* Address
of Environment struct */
unsigned long
/* Checksum of Environment valid? */
unsigned long
/* base address of frame buffer */
#ifdef CONFIG_VFD
unsigned char
/* display type */
#ifdef CONFIG_FSL_ESDHC
unsigned long
unsigned long
/* CPU clock in Hz!
unsigned long
phys_size_t ram_
/* RAM size */
unsigned long
/* reset status register at boot */
/* jump table */
} gd_t;bd_info数据结构如下:typedef struct bd_info {
/* serial console baudrate */
unsigned long
bi_ip_ /* IP Address */
struct environment_s
bi_arch_ /* unique id for this board */
bi_boot_ /* where this board expects params */
/* RAM configuration */
bi_dram[CONFIG_NR_DRAM_BANKS];
global_data数据结构中的大小为24B + 28B = 52B,其中CONFIG_VFD和CONFIG_FSL_ESDHC没定义,全局数据区顶部放着52B。(没有确认)
下面我看到这个gd-&bd = (bd_t*)((char*)gd - sizeof(bd_t))很困惑,岂不是把bd_info数据结构放到global_data结构前面去了?
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:550575次
积分:8418
积分:8418
排名:第1825名
原创:235篇
转载:89篇
评论:117条
(1)(2)(3)(3)(6)(3)(6)(6)(11)(12)(4)(1)(4)(5)(4)(9)(2)(1)(4)(3)(5)(4)(6)(2)(9)(14)(21)(6)(4)(36)(47)(7)(7)(65)(6)
文章:28篇
阅读:91638
点击它俩和我交谈
点击它给我发邮件Uboot直接在ram中运行的办法_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
Uboot直接在ram中运行的办法
上传于||文档简介
&&Uboot直接在ram中运行的办法
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
定制HR最喜欢的简历
你可能喜欢S3C6410开发全纪录(二)《如何计算内存大小,并在UBOOT中调整内存大小》 ._百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
S3C6410开发全纪录(二)《如何计算内存大小,并在UBOOT中调整内存大小》 .
上传于||暂无简介
阅读已结束,如果下载本文需要使用2下载券
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩5页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢博客访问: 121886
博文数量: 87
博客积分: 325
博客等级: 一等列兵
技术积分: 595
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: LINUX
前章我们已经可以制作出用来启动的SD卡了,并将自己编译的UBOOT烧录到了SD卡中
这份UBOOT代码中的内存配置肯定和手头的开发板不一致,这里我们将搞清楚如何修改内存大小,并说清楚内存大小到底是如何计算的
一、关于内存大小的计算
1)硬件的型号,在飞凌的开发板中
128M内存 采用的是 K4X51163PC 可以看出来 这颗芯片是 总大小为512 bit 位宽 为16256M内存 采用的是 K4X1G163PC 可以看出来 这颗芯片是 总大小为1G& bit 位宽 为16
2)贴片数量2,都是用2DDR,来构成32位
3)查看DDR的芯片手册128M内存 总共有 4 个 BANK 行列地址线数量分别为 Row = 13 Col = 10256M内存 总共有 4 个 BANK 行列地址线数量分别为 Row = 14 Col = 10
4)以256M内存为例,内存大小的计算为
每个BANK的存储单元个数 = (2^Row)*(2^Col) = 2^(Row+Col)每个存储单元 可以存放 16 位 的数据 总容量 = 芯片个数 * 每个芯片的BANK数量 * 位宽 * 行地址线数量 * 列地址线数量 (这里的单位都是bit)&&&&&&&&&&& = 2*4*16*(2^14)*(2^10) = 2^(1+2+4+14+10)= 2^31 bit&
转换为 字节 2^28& 转换为兆 2^8 M = 256 M
这里需要说明的是 行列地址线的总数是 > 16 的,行列地址线在实际的使用过程中是分时复用的。
二、内存大小的修改
修改用来显示的内存大小
./include/configs/smdk6410.h:#define&PHYS_SDRAM_1_SIZE&&0x&&&&./include/configs/smdk6410.h:#define PHYS_SDRAM_1_SIZE
0x /* 256 MB */
修改CPU中对应的寄存器配置
《s3c6410_rev12.pdf》196页,5.5.4 MEMORY CONFIGURATION REGISTER
P1MEMCFG&&0x7E00100C&&R/W&&32-bit&DRAM&controller&memory&config&register&&0x01_0020&&P1MEMCFG
0x7E00100C
32-bit DRAM controller memory config register
Active&chips&&[22:21]&&&
00&=&1&chip&&&&
01&=&2&chips&&&&
10&=&Reserved&&&
11&=&Reserved&&&Active chips
00 = 1 chip
01 = 2 chips
10 = Reserved
11 = Reserved
这里我们是2片所以要选成 01
Row&bits&[5:3]&&
000&=&11&bits&&&&
001&=&12&bits&&&&
010&=&13&bits&&&&
011&=&14&bits&&&&
100&=&15&bits&&&&
101&=&16&bits&&&&Row bits [5:3]
000 = 11 bits
001 = 12 bits
010 = 13 bits
011 = 14 bits
100 = 15 bits
101 = 16 bits
Column&bits&&[2:0]&&&
000&=&8&bits&&&&
001&=&9&bits&&&&
010&=&10&bits&&&&
011&=&11&bits&&&&
100&=&12&bits&&&&Column bits
000 = 8 bits
001 = 9 bits
010 = 10 bits
011 = 11 bits
100 = 12 bits
以256M内存芯片的参数为例
《K4X1G163PC.pdf》芯片手册中描述如下:
32M&x16&BA0,BA1&A0&-&A13&A0&-&A9&&32M x16 BA0,BA1 A0 - A13 A0 - A9
这里我们需要将Row设置为011将Column设置为010
uboot代码中我们可以看到
./include/s3c6410.h:#define&ELFIN_DMC1_BASE&&&&&&&&&0x7e001000&&./include/s3c6410.h:#define ELFIN_DMC1_BASE
0x7e001000
./include/s3c6410.h:#define&INDEX_DMC_MEMORY_CFG&&&&(0x0C)&&./include/s3c6410.h:#define INDEX_DMC_MEMORY_CFG
./include/s3c6410.h:#define&DMC1_MEM_CFG&&&&&&&&&&&&0x&&./include/s3c6410.h:#define DMC1_MEM_CFG
实际上,如果通过读CPU的手册而将内存配置正确,是件挺困的事情,还好我们有很多可参考的代码,但我们需要弄清楚这些代码为什么要这样修改
修改行列地址线的配置
#define&DMC1_MEM_CFG&0x0001001A&&#define DMC1_MEM_CFG 0x0001001A
1A转换为二进制为,可以看到,是我们查到的Row,Column的寄存器配置的值
在有些代码中也修改了 #define DMC1_CHIP0_CFG&&0x150F8 这个寄存器的值,为 #define DMC1_CHIP0_CFG&&0x150F0翻遍了资料也不知道这个值是做什么用的,为什么要修改,所以我这里并没有修改这个值,也希望有经验的朋友能告诉我为什么。
修改UBOOT的自举地址
一般考虑修改UBOOT自举地址都会去修改 board/samsum/smdk6410/config.mk 中的 TEXT_BASE 的值,但这里不能做
网上下来资料看了下,目前大多数的s3c6410开发板都没有去修改UBOOT的自举地址,这里记录了下查找及修改的过程
cpu/s3c64xx/start.S&中看到&&
#ifdef&CONFIG_BOOT_MOVINAND &&
&&&&&&&&ldr&&&&&sp,&_TEXT_PHY_BASE&&
&&&&&&&&bl&&&&&&movi_bl2_copy&&
&&&&&&&&b&&&&&&&after_copy&&
#endif&&cpu/s3c64xx/start.S 中看到
#ifdef CONFIG_BOOT_MOVINAND
sp, _TEXT_PHY_BASE
movi_bl2_copy
after_copy
_TEXT_PHY_BASE:&&
&&&&&&&&.word&&&CFG_PHY_UBOOT_BASE&&_TEXT_PHY_BASE:
CFG_PHY_UBOOT_BASE
修改&include/configs/smdk6410.h&&
#define&CFG_MEMTEST_END&&&&&&&&&MEMORY_BASE_ADDRESS&+&0x7e00000&&&&&&&&&/*&128&MB&in&DRAM&&&&&&&*/ &&
#define&CFG_MEMTEST_END&&&&&&&&&MEMORY_BASE_ADDRESS&+&0xfe00000&&&&&&&&&/*&256&MB&in&DRAM&&&&&&&*/ &&
#ifdef&CONFIG_ENABLE_MMU &&
&&&&&&&&&&
&&&&&&&&#define&CFG_UBOOT_BASE&0xcfe00000 &&
&&&&&&&&&&
&&&&&&&&#define&CFG_UBOOT_BASE&0x5fe00000 &&
#define&CFG_PHY_UBOOT_BASE&MEMORY_BASE_ADDRESS&+&0XFE00000&&修改 include/configs/smdk6410.h
#define CFG_MEMTEST_END
MEMORY_BASE_ADDRESS + 0x7e00000
/* 128 MB in DRAM
#define CFG_MEMTEST_END
MEMORY_BASE_ADDRESS + 0xfe00000
/* 256 MB in DRAM
#ifdef CONFIG_ENABLE_MMU
// #define CFG_UBOOT_BASE
0xc7e00000
#define CFG_UBOOT_BASE 0xcfe00000
//#define CFG_UBOOT_BASE
0x57e00000
#define CFG_UBOOT_BASE 0x5fe00000
//#define CFG_PHY_UBOOT_BASE
MEMORY_BASE_ADDRESS + 0x7e00000
#define CFG_PHY_UBOOT_BASE MEMORY_BASE_ADDRESS + 0XFE00000
修改&board/samsung/smdk6410/config.mk&&
TEXT_BASE&=&0xcfe00000&&修改 board/samsung/smdk6410/config.mk
//TEXT_BASE = 0xc7e00000
TEXT_BASE = 0xcfe00000
修改&include/movi.h&&
#define&BL2_BASE&&&&&&&&&&&&&&&&0x5FE00000 &&
这宏只作用于movi_bl2_copy函数,因为我们需要将UBOOT自举到256的最顶端&&修改 include/movi.h
//#define BL2_BASE
0x57E00000
#define BL2_BASE
0x5FE00000
这宏只作用于movi_bl2_copy函数,因为我们需要将UBOOT自举到256的最顶端
修改MMU地址映射规则
修改&board/samsung/smdk6410/lowlevel_init.S&&
找到&mmu_table:将&&
&&&&&&&&&&
&&&&&&&&.set&__base,&0x500&&
&&&&&&&&.rept&0xC80&-&0xC00&&&&&&&&&&
&&&&&&&&FL_SECTION_ENTRY&__base,3,0,1,1&&
&&&&&&&&.set&__base,__base+1&&
&&&&&&&&.endr&&
&&&&&&&&&&
&&&&&&&&.rept&0x1000&-&0xc80&&&&&&&&&&
&&&&&&&&.word&0x&&
&&&&&&&&.endr&&
修改为:&&
&&&&&&&&&&
&&&&&&&&.set&__base,&0x500&&
&&&&&&&&.rept&0xd00&-&0xC00&&
&&&&&&&&FL_SECTION_ENTRY&__base,3,0,1,1&&
&&&&&&&&.set&__base,__base+1&&
&&&&&&&&.endr&&
&&&&&&&&&&
&&&&&&&&.rept&0x1000&-&0xd00&&
&&&&&&&&.word&0x&&
&&&&&&&&.endr&&修改 board/samsung/smdk6410/lowlevel_init.S
找到 mmu_table:将
// 128MB for SDRAM 0xC0000000 -> 0x
.set __base, 0x500
.rept 0xC80 - 0xC00
FL_SECTION_ENTRY __base,3,0,1,1
.set __base,__base+1
// access is not allowed.
.rept 0x1000 - 0xc80
// 256MB for SDRAM 0xC0000000 -> 0x
.set __base, 0x500
.rept 0xd00 - 0xC00
FL_SECTION_ENTRY __base,3,0,1,1
.set __base,__base+1
// access is not allowed.
.rept 0x1000 - 0xd00
UBOOT启动起来,敲入 md cfe00000,打印出内存的数据,可以查看到跟我们编译出来的u-boot.bin是一致的
三、参考资料
专家详解:内存工作原理及发展历程(值得一看)
6410平台上配置Linux的DDR参数(直接给出了结果,可以有个参考)
S3C6410的DRAM控制器(罗列的非常清楚)
《s3c6410_rev12.pdf》
《OK6410开发板硬件手册2.1.pdf》
《K4X51163PC.pdf》
《K4X1G163PC.pdf》
阅读(1092) | 评论(0) | 转发(3) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。

我要回帖

更多关于 uboot代码详细分析 的文章

 

随机推荐