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

来源:互联网 发布:广电网络(600831)股吧 编辑:程序博客网 时间:2024/06/08 08:59

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,

         .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 */

         .d_conf = 0, /* dynamic */

         .valid = 1,

         .name = "Reserved Memory",

     },

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

     cplb_data[RES_MEM].start = _ramend;

     cplb_data[RES_MEM].end = physical_mem_end;

也就是说,它将指向保留的内存区域。所谓保留的内存区域,就是用memmaxmem这两个内核参数指定可用SDRAM大小时的空间差,比如mem=32m maxmem=64m,那么后面的32m空间就是保留的区域。

1.1.9   ASYNC_MEM

这块空间定义为:

     {

         .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",

     },

比较简单,就是4async bank的区域。

1.1.10 BOOT_ROM区域

这个区域定义为:

     {

         .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",

     },

它的起始位置和结束位置为:

#define BOOT_ROM_START      0xEF000000

#define BOOT_ROM_LENGTH     0x800

即这个区域表示BF561内部的BOOTROM

它的两个配置:

#define SDRAM_IGENERIC    (CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | CPLB_PORTPRIO)

#define SDRAM_DGENERIC   (CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW  | CPLB_COMMON)

 

1       参考资料

uclinux-2008r1(bf561)内核存储区域初探(2008/6/4)

 

 

原创粉丝点击