从cplb_data全局变量看uclinux的存储空间划分
2019-07-13 15:49发布
生成海报
rev 0.1
快乐虾
http://blog.csdn.net/lights_joy/
lights@hb165.com
本文适用于
ADI bf561 DSP
优视BF561EVB开发板
uclinux-2008r1-rc8 (移植到vdsp5)
Visual DSP++ 5.0
欢迎转载,但请保留作者信息
在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两个核都有各自的大小为16K的L1 INSTRUCTION SRAM,对于A核,其地址为0xffa0 0000 ~ 0xffa0 4000,对于B核,其地址为0xff60 0000 ~ 0xff60 4000。因此在这里将它们的start和end设置为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用于存储数据,这两块32K的SRAM又都可以分为两半,一半存数据,一半用于cache,但是这两块SRAM之间并不连续。对于A核来讲,其空间为:0xff80 0000 ~ 0xff80 8000和0xff90 0000 ~ 0xff90 8000。而对于B核,它的空间则为:0xff40 0000 ~ 0xff40 8000和0xff50 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 a和bank 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,
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮