uclinux-2008R1.5-RC3(bf561)到VDSP5的移植(65):B核启动
2019-07-13 15:56 发布
生成海报
快乐虾
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=17&extra =进行讨论。
在 A 核启动的末期,会创建一个内核线程,此内核线程的入口为 kernel_init 函数。
static int __init kernel_init(void * unused)
{
………………………
smp_prepare_cpus(max_cpus);
…………………… ..
}
再看看 smp_prepare_cpus 函数:
void __init smp_prepare_cpus(unsigned int max_cpus)
{
platform_prepare_cpus(max_cpus);
platform_request_ipi(&ipi_handler);
}
继续看 platform_prepare_cpus 函数:
void __init platform_prepare_cpus(unsigned int max_cpus)
{
int len;
len = &coreb_trampoline_end - &coreb_trampoline_start + 1;
if (len > COREB_SRAM_SIZE) {
/* Paranoid. */
printk(KERN_ERR "Bootstrap code size (%d) > CoreB SRAM (%d)./n" ,
len, COREB_SRAM_SIZE);
return ;
}
dma_memcpy((void *)COREB_SRAM_BASE, &coreb_trampoline_start, len);
/* Both cores ought to be present on a bf561! */
cpu_set(0, cpu_present_map); /* CoreA */
cpu_set(1, cpu_present_map); /* CoreB */
printk(KERN_INFO "CoreB bootstrap code to SRAM %p via DMA./n" , (void *)COREB_SRAM_BASE);
}
在这里有两个符号 coreb_trampoline_end 和 coreb_trampoline_start 。这两个符号分别指向了 B 核入口代码的起始位置和结束位置,然后通过 DMA 将它们复制到 COREB_SRAM_BASE ,即 0xff60 0000 , B 核启动后将从这里开始执行。
注意此时 B 核仍然没有启动。真正启动 B 核要到下面的函数:
int __cpuinit platform_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
unsigned long timeout;
if ((bfin_read_SICA_SYSCR() & COREB_SRAM_INIT) == 0)
return -EBUSY; /* CoreB already running?! */
printk(KERN_INFO "Booting Core B./n" );
spin_lock(&boot_lock);
/* Kick CoreB, which should start execution from CORE_SRAM_BASE. */
SSYNC();
bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~COREB_SRAM_INIT);
SSYNC();
timeout = jiffies + 1 * HZ;
while (time_before(jiffies, timeout)) {
if (cpu_isset(cpu, cpu_callin_map))
break ;
udelay(100);
barrier();
if (jiffies > (timeout+500)) {
printk(KERN_INFO "." );
timeout = jiffies;
}
}
spin_unlock(&boot_lock);
return cpu_isset(cpu, cpu_callin_map) ? 0 : -ENOSYS;
}
这种方式在 vdsp 下使用有几个问题需要修改。
1.1 条件检测
首先因为 vdsp 一启动直接就将 B 核置于 FULLON 的状态,所以前面的这个条件检测
if ((bfin_read_SICA_SYSCR() & COREB_SRAM_INIT) == 0)
return -EBUSY; /* CoreB already running?! */
只能略过。
1.2 代码加载
在这里 B 核的可执行代码是由 A 核加载的,在 vdsp 下可以直接将代码放在 coreb 里面,因此 platform_prepare_cpus 函数只要留下
/* Both cores ought to be present on a bf561! */
cpu_set(0, cpu_present_map); /* CoreA */
cpu_set(1, cpu_present_map); /* CoreB */
这两行即可。
直接将 arch/blackfin/mach-bf561/secondary.S 添加到 coreb 工程中。
1.3 修改 coreb 入口
在默认情况下, B 核入口指向 uclinux_basiccrt.S ,需要在 ldf 文件中进行修改:
RESOLVE(coreb_trampoline_start, 0xFF600000)
KEEP(coreb_trampoline_start,_main)
1.4 代码共享
在此之前一直是将所有的代码链接到 A 核中,在启用了 B 核之后,这些代码和数据都必须设置为共享,最简单的办法就是将这些 dlb 和 sml3.dlb 放在一起,就像这样:
$LIBRARIES_SML3 =
/*$VDSG */
/* Text inserted between these $VDSG comments will be preserved */
/*$VDSG */
sml3.dlb
,arch-mm.dlb
,arch-kernel.dlb
,arch-lib.dlb
,kernel.dlb
,init.dlb
,mach-common.dlb
,mm.dlb
,fs.dlb
,fs-proc.dlb
,fs-sysfs.dlb
,fs-ramfs.dlb
,fs-patitions.dlb
,lib.dlb
,drivers-char.dlb
,drivers-serial.dlb
,drivers-base.dlb
,drivers-base-power.dlb
,drivers-net.dlb
,mach-bf561.dlb
,security.dlb
,net.dlb
,net-core.dlb
,net-netlink.dlb
,net-sched.dlb
,net-ethernet.dlb
,block.dlb
,$LIBS
然后将各个 section 的定义由 p0 转移到 COMMON_MEMORY 。
当然这样做会引起一些新的链接错误,下面将逐一解决。
uclinux-2008R1.5-RC3(bf561) 到 VDSP5 的移植 (61) : __builtin_constant_p (2009-2-11)
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)
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮