DSP

uclinux-2008R1.5-RC3(bf561)到VDSP5的移植(66):_ebss_l1

2019-07-13 17:31发布

  快乐虾 http://blog.csdn.net/lights_joy/ lights@hb165.com    本文适用于 ADI bf561 DSP 优视BF561EVB开发板 uclinux-2008r1.5-rc3(smp patch) Visual DSP++ 5.0(update 5)   欢迎转载,但请保留作者信息 如果您对本文有兴趣,可到http://www.bfin-tools.org/bbs/viewthread.php?tid=18&extra=参与讨论。         有几个链接错误: [Error li1021]  The following symbols referenced in processor 'p1' could not be resolved:         '_ebss_l1 [__ebss_l1]' referenced from 'arch-kernel.dlb[setup.doj]'         '_ebss_l1 [__ebss_l1]' referenced from 'arch-mm.dlb[blackfin_sram.doj]'         '_etext_l1 [__etext_l1]' referenced from 'arch-kernel.dlb[setup.doj]'         '_etext_l1 [__etext_l1]' referenced from 'arch-mm.dlb[blackfin_sram.doj]'         '_sdata_l1 [__sdata_l1]' referenced from 'arch-kernel.dlb[setup.doj]'         '_sdata_l1 [__sdata_l1]' referenced from 'arch-mm.dlb[blackfin_sram.doj]'         '_stext_l1 [__stext_l1]' referenced from 'arch-kernel.dlb[setup.doj]'         '_stext_l1 [__stext_l1]' referenced from 'arch-mm.dlb[blackfin_sram.doj]' 这里出现的几个符号均定义在vmlinux.lds.s中:      .text_l1 L1_CODE_START : AT(LOADADDR(.init.ramfs) + SIZEOF(.init.ramfs))      {          . = ALIGN(4);          __stext_l1 = .;          LDS_L1_CODE          . = ALIGN(4);          __etext_l1 = .;      }        .data_l1 L1_DATA_A_START : AT(LOADADDR(.text_l1) + SIZEOF(.text_l1))      {          . = ALIGN(4);          __sdata_l1 = .;          LDS_L1_A_DATA          __edata_l1 = .;            . = ALIGN(4);          __sbss_l1 = .;          LDS_L1_A_BSS            . = ALIGN(32);          LDS_L1_A_CACHE            . = ALIGN(4);          __ebss_l1 = .;      } 也就是说,这几个符号将指向A核中l1 memory被内核使用的部分的起始位置和结束位置。 再看看使用这两个符号的地方,第一个在arch/blackfin/kernel/setup.c(161)文件中 void __init bf53x_relocate_l1_mem(void) {      unsigned long l1_code_length;      unsigned long l1_data_a_length;      unsigned long l1_data_b_length;        l1_code_length = _etext_l1 - _stext_l1;      if (l1_code_length > L1_CODE_LENGTH)          panic("L1 Instruction SRAM Overflow/n");      /* cannot complain as printk is not available as yet.       * But we can continue booting and complain later!       */        /* Copy _stext_l1 to _etext_l1 to L1 instruction SRAM */      dma_memcpy(_stext_l1, _l1_lma_start, l1_code_length);        l1_data_a_length = _ebss_l1 - _sdata_l1;      if (l1_data_a_length > L1_DATA_A_LENGTH)          panic("L1 Data SRAM Bank A Overflow/n");        /* Copy _sdata_l1 to _ebss_l1 to L1 data bank A SRAM */      dma_memcpy(_sdata_l1, _l1_lma_start + l1_code_length, l1_data_a_length);        l1_data_b_length = _ebss_b_l1 - _sdata_b_l1;      if (l1_data_b_length > L1_DATA_B_LENGTH)          panic("L1 Data SRAM Bank B Overflow/n");        /* Copy _sdata_b_l1 to _ebss_b_l1 to L1 data bank B SRAM */      dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length +               l1_data_a_length, l1_data_b_length);   } 这个函数用于将代码复制到L1的相应区域,但是在VDSP下可以通过ldf文件直接将代码或者数据放置在相应的地方,因此这个函数可以略过,不调用它。 第二个地方在arch/blackfin/kernel/setup.c(475)文件中: void __init setup_arch(char **cmdline_p) { ………………………………      /* check the size of the l1 area */      l1_length = _etext_l1 - _stext_l1;      if (l1_length > L1_CODE_LENGTH)          panic("L1 code memory overflow/n");        l1_length = _ebss_l1 - _sdata_l1;      if (l1_length > L1_DATA_A_LENGTH)          panic("L1 data memory overflow/n"); ………………………………. } 仅仅是一个简单的条件判断,因为这个检验将由vdsp的链接器来完成,所以直接略过这里的条件判断。 第三个地方在arch/blackfin/mm/blackfin_sram.c(133)文件中: void __init l1_data_sram_init(void) {      unsigned int cpu;   #if L1_DATA_A_LENGTH != 0      printk(KERN_INFO "Blackfin DATA_A SRAM: %d KB/n",               L1_DATA_A_LENGTH >> 10);      for (cpu = 0; cpu < NR_CPUS; ++cpu) {          memset(&per_cpu(l1sram, cpu).l1_data_A_sram, 0x00,                 sizeof(per_cpu(l1sram, cpu).l1_data_A_sram));          per_cpu(l1sram, cpu).l1_data_A_sram[0].paddr = (void *)get_l1_data_a_start_cpu(cpu) +               (_ebss_l1 - _sdata_l1);          per_cpu(l1sram, cpu).l1_data_A_sram[0].size = L1_DATA_A_LENGTH - (_ebss_l1 - _sdata_l1);          per_cpu(l1sram, cpu).l1_data_A_sram[0].flag = SRAM_SLT_FREE;      } #endif #if L1_DATA_B_LENGTH != 0      printk(KERN_INFO "Blackfin DATA_B SRAM: %d KB/n",          L1_DATA_B_LENGTH >> 10);      for (cpu = 0; cpu < NR_CPUS; ++cpu) {          memset(&per_cpu(l1sram, cpu).l1_data_B_sram, 0x00, sizeof(per_cpu(l1sram, cpu).l1_data_B_sram));          per_cpu(l1sram, cpu).l1_data_B_sram[0].paddr = (void *)get_l1_data_b_start_cpu(cpu)/*+(_ebss_b_l1 - _sdata_b_l1)*/;          per_cpu(l1sram, cpu).l1_data_B_sram[0].size = L1_DATA_B_LENGTH/*-(_ebss_b_l1 - _sdata_b_l1)*/;          per_cpu(l1sram, cpu).l1_data_B_sram[0].flag = SRAM_SLT_FREE;      } #endif      /* mutex initialize */      spin_lock_init(&per_cpu(l1sram, cpu).l1_data_sram_lock); } 这段代码主要用于注册l1中的可用存储空间。它用_ebss_l1 - _sdata_l1来表示内核已经使用的空间大小,在此直接预留4K的空间出来,同时在LDF文件中将这个预留段的大小限制为4K 修改后的代码: void __init l1_data_sram_init(void) {      unsigned int cpu;   #if L1_DATA_A_LENGTH != 0      printk(KERN_INFO "Blackfin DATA_A SRAM: %d KB/n",               L1_DATA_A_LENGTH >> 10);      for (cpu = 0; cpu < NR_CPUS; ++cpu) {          memset(&per_cpu(l1sram, cpu).l1_data_A_sram, 0x00,                 sizeof(per_cpu(l1sram, cpu).l1_data_A_sram));          per_cpu(l1sram, cpu).l1_data_A_sram[0].paddr = (void *)get_l1_data_a_start_cpu(cpu) + 0x1000 /*(_ebss_l1 - _sdata_l1)*/;          per_cpu(l1sram, cpu).l1_data_A_sram[0].size = L1_DATA_A_LENGTH - 0x1000/*(_ebss_l1 - _sdata_l1)*/;          per_cpu(l1sram, cpu).l1_data_A_sram[0].flag = SRAM_SLT_FREE;      } #endif #if L1_DATA_B_LENGTH != 0      printk(KERN_INFO "Blackfin DATA_B SRAM: %d KB/n",          L1_DATA_B_LENGTH >> 10);      for (cpu = 0; cpu < NR_CPUS; ++cpu) {          memset(&per_cpu(l1sram, cpu).l1_data_B_sram, 0x00, sizeof(per_cpu(l1sram, cpu).l1_data_B_sram));          per_cpu(l1sram, cpu).l1_data_B_sram[0].paddr = (void *)get_l1_data_b_start_cpu(cpu) + 0x1000/*(_ebss_b_l1 - _sdata_b_l1)*/;          per_cpu(l1sram, cpu).l1_data_B_sram[0].size = L1_DATA_B_LENGTH - 0x1000/*(_ebss_b_l1 - _sdata_b_l1)*/;          per_cpu(l1sram, cpu).l1_data_B_sram[0].flag = SRAM_SLT_FREE;      } #endif      /* mutex initialize */      spin_lock_init(&per_cpu(l1sram, cpu).l1_data_sram_lock); } LDF文件中的修改:       MEM_A_L1_DATA_B         { TYPE(RAM) START(0xFF900000) END(0xFF900FFF) WIDTH(8) }       MEM_A_L1_DATA_A         { TYPE(RAM) START(0xFF800000) END(0xFF800FFF) WIDTH(8) }       MEM_B_L1_DATA_B         { TYPE(RAM) START(0xFF500000) END(0xFF500FFF) WIDTH(8) }       MEM_B_L1_DATA_A         { TYPE(RAM) START(0xFF400000) END(0xFF400FFF) WIDTH(8) }    

1       参考资料

uclinux-2008R1.5-RC3(bf561)VDSP5的移植(62)__builtin_return_address(2009-2-11) uclinux-2008R1.5-RC3(bf561)VDSP5的移植(63)_NSIG_WORDS_is_unsupported_size(2009-2-11) uclinux-2008R1.5-RC3(bf561)VDSP5的移植(64)__ebss_b_l1(2009-02-12) uclinux-2008R1.5-RC3(bf561)VDSP5的移植(65)B核启动(2009-2-13)