DSP

从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中,它的整个存储空间是这样的: 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,