从cplb_data全局变量看uclinux的存储空间划分

rev 0.1

快乐虾

http://blog.csdn.net/lights_joy/

[email protected]

本文适用于

ADI bf561 DSP

优视BF561EVB开发板

uclinux-2008r1-rc8 (移植到vdsp5)

Visual DSP++ 5.0

欢迎转载但请保留作者信息

BF561中,它的整个存储空间是这样的:

bf561存储空间

cplb_data这个全局变量的定义在arch/blackfin/kernel/cplb-nommu/cplb_init.c文件中,从这个全局变量可以看出内核对整个存储区域的划分。

static struct cplb_desc cplb_data[] = {

{

.start = 0,

.end = SIZE_1K,

.psize = SIZE_1K,

.attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB,

.i_conf = SDRAM_OOPS,

.d_conf = SDRAM_OOPS,

#if defined(CONFIG_DEBUG_HUNT_FOR_ZERO)

.valid = 1,

#else

.valid = 0,

#endif

.name = "Zero Pointer Guard Page",

},

{

.start = 0, /* dyanmic */

.end = 0, /* dynamic */

.psize = SIZE_4M,

.attr = INITIAL_T | SWITCH_T | I_CPLB,

.i_conf = L1_IMEMORY,

.d_conf = 0,

.valid = 1,

.name = "L1 I-Memory",

},

{

.start = 0, /* dynamic */

.end = 0, /* dynamic */

.psize = SIZE_4M,

.attr = INITIAL_T | SWITCH_T | D_CPLB,

.i_conf = 0,

.d_conf = L1_DMEMORY,

#if ((L1_DATA_A_LENGTH > 0) || (L1_DATA_B_LENGTH > 0))

.valid = 1,

#else

.valid = 0,

#endif

.name = "L1 D-Memory",

},

{

#if defined(CONFIG_BF561) || defined(CONFIG_BF54x)

.start = L2_START,

.end = L2_START+L2_LENGTH,

.psize = SIZE_1M,

.attr = L2_ATTR,

.i_conf = L2_MEMORY,

.d_conf = L2_MEMORY,

.valid = 1,

#else

.valid = 0,

#endif

.name = "L2 Memory",

},

{

.start = 0,

.end = 0, /* dynamic */

.psize = 0,

.attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB,

.i_conf = SDRAM_IGENERIC,

.d_conf = SDRAM_DGENERIC,

.valid = 1,

.name = "Kernel Memory",

},

{

.start = 0, /* dynamic */

.end = 0, /* dynamic */

.psize = 0,

.attr = INITIAL_T | SWITCH_T | D_CPLB,

.i_conf = SDRAM_IGENERIC,

.d_conf = SDRAM_DNON_CHBL,

.valid = 1,

.name = "uClinux MTD Memory",

},

{

.start = 0, /* dynamic */

.end = 0, /* dynamic */

.psize = SIZE_1M,

.attr = INITIAL_T | SWITCH_T | D_CPLB,

.d_conf = SDRAM_DNON_CHBL,

.valid = 1,

.name = "Uncached DMA Zone",

},

{

.start = 0, /* dynamic */

.end = 0, /* dynamic */

.psize = 0,

.attr = SWITCH_T | D_CPLB,

.i_conf = 0, /* dynamic */

.d_conf = 0, /* dynamic */

.valid = 1,

.name = "Reserved Memory",

},

{

.start = ASYNC_BANK0_BASE,

.end = ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE,

.psize = 0,

.attr = SWITCH_T | D_CPLB,

.d_conf = SDRAM_EBIU,

.valid = 1,

.name = "Asynchronous Memory Banks",

},

{

.start = BOOT_ROM_START,

.end = BOOT_ROM_START + BOOT_ROM_LENGTH,

.psize = SIZE_1M,

.attr = SWITCH_T | I_CPLB | D_CPLB,

.i_conf = SDRAM_IGENERIC,

.d_conf = SDRAM_DGENERIC,

.valid = 1,

.name = "On-Chip BootROM",

},

};

从上面可以看出,内核将整个存储空间分为10个区域,每个区域的序号可以用下面的宏来表示。

enum {

ZERO_P, L1I_MEM, L1D_MEM, L2_MEM, SDRAM_KERN, SDRAM_RAM_MTD, SDRAM_DMAZ, RES_MEM, ASYNC_MEM, OCB_ROM

};

1.1.1 ZERO_P区域

这块区域的初始化信息为:

{

.start = 0,

.end = SIZE_1K,

.psize = SIZE_1K,

.attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB,

.i_conf = SDRAM_OOPS,

.d_conf = SDRAM_OOPS,

#if defined(CONFIG_DEBUG_HUNT_FOR_ZERO)

.valid = 1,

#else

.valid = 0,

#endif

.name = "Zero Pointer Guard Page",

},

从它的name猜测,应该是用来保护对NULL地址的访问的,当访问此地址时,将引发一个cplb error,然后内核就可以进行相应的处理了。

1.1.2 L1指令区域

这块区域初始化为:

{

.start = 0, /* dyanmic */

.end = 0, /* dynamic */

.psize = SIZE_4M,

.attr = INITIAL_T | SWITCH_T | I_CPLB,

.i_conf = L1_IMEMORY,

.d_conf = 0,

.valid = 1,

.name = "L1 I-Memory",

},

BF561中,AB两个核都有各自的大小为16KL1 INSTRUCTION SRAM,对于A核,其地址为0xffa0 0000 ~ 0xffa0 4000,对于B核,其地址为0xff60 0000 ~ 0xff60 4000。因此在这里将它们的startend设置为0,但是在下面的设置函数中将对其进行初始化:

void __init generate_cpltab_cpu(unsigned int cpu)

{

………………………………

cplb_data[L1I_MEM].start = get_l1_code_start_cpu(cpu);

cplb_data[L1I_MEM].end = cplb_data[L1I_MEM].start + L1_CODE_LENGTH;

……………..

}

1.1.3 L1数据区域

这个区域初始化为:

{

.start = 0, /* dynamic */

.end = 0, /* dynamic */

.psize = SIZE_4M,

.attr = INITIAL_T | SWITCH_T | D_CPLB,

.i_conf = 0,

.d_conf = L1_DMEMORY,

#if ((L1_DATA_A_LENGTH > 0) || (L1_DATA_B_LENGTH > 0))

.valid = 1,

#else

.valid = 0,

#endif

.name = "L1 D-Memory",

},

BF561中,每个核都有两块L1 SRAM用于存储数据,这两块32KSRAM又都可以分为两半,一半存数据,一半用于cache,但是这两块SRAM之间并不连续。对于A核来讲,其空间为:0xff80 0000 ~ 0xff80 80000xff90 0000 ~ 0xff90 8000。而对于B核,它的空间则为:0xff40 0000 ~ 0xff40 80000xff50 0000 ~ 0xff50 8000

看看它的初始化:

void __init generate_cpltab_cpu(unsigned int cpu)

{

…………………………………

cplb_data[L1D_MEM].start = get_l1_data_a_start_cpu(cpu);

cplb_data[L1D_MEM].end = get_l1_data_b_start_cpu(cpu) + L1_DATA_B_LENGTH;

……………………………

}

也就是说,内核定义的这块空间包括bank a全部和bank b的一半,还包括bank abank b之间reserve的部分。

1.1.4 L2缓存

这块区域定义为:

{

#if defined(CONFIG_BF561) || defined(CONFIG_BF54x)

.start = L2_START,

.end = L2_START+L2_LENGTH,

.psize = SIZE_1M,

.attr = L2_ATTR,

.i_conf = L2_MEMORY,

.d_conf = L2_MEMORY,

.valid = 1,

#else

.valid = 0,

#endif

.name = "L2 Memory",

},

这个就比较简单了,指向128KL2

/* Level 2 Memory */

#define L2_START 0xFEB00000

#define L2_LENGTH 0x20000

1.1.5 内核区域

这块区域定义为:

{

.start = 0,

.end = 0, /* dynamic */

.psize = 0,

.attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB,

.i_conf = SDRAM_IGENERIC,

.d_conf = SDRAM_DGENERIC,

.valid = 1,

.name = "Kernel Memory",

},

在下面还有一行初始化的代码:

cplb_data[SDRAM_KERN].end = memory_end;

在不使用mem这个内核参数的情况下,这个区域将包含CONFIG_MEM_SIZE指定的内存的整个空间(可能除去1M或者2MDMA区域)。在使用mem内核参数的情况下,将指向mem指定的空间大小(同样可能除去1M或者2MDMA区域)。但由于ANOMALY_05000263的缘故,这个值将被限制为60M,即0x03c0 0000

1.1.6 根文件系统区域

这块区域初始化为:

{

.start = 0, /* dynamic */

.end = 0, /* dynamic */

.psize = 0,

.attr = INITIAL_T | SWITCH_T | D_CPLB,

.i_conf = SDRAM_IGENERIC,

.d_conf = SDRAM_DNON_CHBL,

.valid = 1,

.name = "uClinux MTD Memory",

},

这块区域仅当启用了CONFIG_MTD_UCLINUX时才有效,也就是说,仅当内核使用extcramfs或者romfs做为根文件系统时才有效。因为这个时候会在内核结束的位置插入一个rootfs,然后在setup_arch中将这个rootfs搬移到SDRAM的最高位置,此时就可以用这块区域来表示这个rootfs

当没有启用CONFIG_MTD_UCLINUX时,这块区域没有使用,因而在下面的初始化代码中将它的.valid设置为0

void __init generate_cpltab_cpu(unsigned int cpu)

{

…………………………

#ifdef CONFIG_MTD_UCLINUX

cplb_data[SDRAM_RAM_MTD].start = memory_mtd_start;

cplb_data[SDRAM_RAM_MTD].end = memory_mtd_start + mtd_size;

cplb_data[SDRAM_RAM_MTD].valid = mtd_size > 0;

# if defined(CONFIG_ROMFS_FS)

cplb_data[SDRAM_RAM_MTD].attr |= I_CPLB;

/*

* The ROMFS_FS size is often not multiple of 1MB.

* This can cause multiple CPLB sets covering the same memory area.

* This will then cause multiple CPLB hit exceptions.

* Workaround: We ensure a contiguous memory area by extending the kernel

* memory section over the mtd section.

* For ROMFS_FS memory must be covered with ICPLBs anyways.

* So there is no difference between kernel and mtd memory setup.

*/

cplb_data[SDRAM_KERN].end = memory_mtd_start + mtd_size;;

cplb_data[SDRAM_RAM_MTD].valid = 0;

# endif

#else

cplb_data[SDRAM_RAM_MTD].valid = 0;

#endif

………………..

}

1.1.7 保留的DMA区域

这块区域初始化为:

{

.start = 0, /* dynamic */

.end = 0, /* dynamic */

.psize = SIZE_1M,

.attr = INITIAL_T | SWITCH_T | D_CPLB,

.d_conf = SDRAM_DNON_CHBL,

.valid = 1,

.name = "Uncached DMA Zone",

},

在下面还有一段初始化的代码:

cplb_data[SDRAM_DMAZ].start = _ramend - DMA_UNCACHED_REGION;

cplb_data[SDRAM_DMAZ].end = _ramend;

即这块区域将表示未用cacheSDRAM。这里根据配置DMA_UNCACHED_REGION的值可以是1M或者2M,也可以为0

1.1.8 RES_MEM

这块区域初始化配置为:

{

.start = 0, /* dynamic */

.end = 0, /* dynamic */

.psize = 0,

.attr = SWITCH_T | D_CPLB,

.i_conf = 0, /* dynamic */

align=

你可能感兴趣的:(cache,Blog,ext)