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) }
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)
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮