Arm 我的ttb_基址切换有问题
首先,感谢来自artless noise的好建议。Arm 我的ttb_基址切换有问题,arm,Arm,首先,感谢来自artless noise的好建议。 我选择与usr任务(vaddr:0-4G)共享3G-4G-1内核空间地址以切换任务。 我认为任务切换是这样的: 当usr任务在其自己的地址空间中运行时,会出现时钟中断 分支到usr地址空间的3G(也是内核3G空间)。 上下文保存 附表() { .. switch_ttb_base(ttb_base);//我认为这是关键,(taskA-->TaskB) //当ttb_基址切换时,地址空间发生变化, //看起来TaskB被中断并到达此处。 /
我选择与usr任务(vaddr:0-4G)共享3G-4G-1内核空间地址以切换任务。
我认为任务切换是这样的:
{
..
switch_ttb_base(ttb_base);
//我认为这是关键,(taskA-->TaskB)
//当ttb_基址切换时,地址空间发生变化,
//看起来TaskB被中断并到达此处。
//因此,在恢复上下文后,它将返回到TaskB
//看起来TaskB刚才被中断了!
..
}
这是我的代码,(ARM920T,S3C2440)
手臂停下,我不知道为什么?感谢您的帮助我做了一个mmu测试来测试mmu缓存操作 我将ttb底座切换为:
void change_ttb_base (unsigned ttb)
{
sync_dcaches ();
invalidate_icache ();
invalidate_dcaches ();
set_ttb_base (ttb);
invalidate_tlbs ();
}
在我的s3c2440板上,0x30000000-0x340000000是sdram地址,我在sdram地址空间上进行测试,
ttb_基地切换成功但是当代码在高3G地址运行时,在我调用change_ttb_base()之后,ARM就停止了。我想,在高3G地址运行的代码需要MMU地址转换,我更改了ttb_base并使所有I&d缓存和TLB无效,所以ARM核心不知道下一步是什么,所以就停止吧
是这样吗?不回答您的问题,但是ARM有域和pid寄存器用于快速上下文切换。您可以使用这些功能并避免缓存刷新。每个上下文切换只需要更改一个域和pid寄存器。更改
TTB_基
非常昂贵。通常,对于上下文切换,只需更新第二级表并刷新该范围。对于域和PID,甚至通常也不需要这样做。所有进程的操作系统和硬件映射(高内存)保持不变。即使是共享库text
,如libc,也可以跨进程映射。vaddr for libc文本映射相同,意味着MMU更新更小,进程间缓存效果更好。但FCSE只能使用32M。32M对我来说似乎不太好。是的,FCSE限制为32M,但通常主进程映射在此范围内。共享库位于其他位置。您不需要刷新缓存或TLB,因此使用FCSE可以提高性能。DACR或域没有此限制;我相信只有16个,但支持全4G。您可以将FCSE与DACR相结合,以拥有更多的进程。典型系统没有数百个活动进程。此外,可能不需要您的某些更新。你可以懒散,把它们留给故障处理程序。我认为你在排序上可能仍然有问题。在前几次失效后,指令在set\u ttb\u base()
之前被提取到缓存中。很难说,有些事情将取决于新旧ttb_基地。你的问题很难回答,因为它涉及到ARM系统的许多方面。谢谢,也许我应该阅读ARM linux的源代码并尝试更多的测试!谢谢上帝!!!!!。我在没有映射端口的情况下切换了ttb_基,然后我使用uart_printk()来编写这个端口。当然,ARM将停止。。。。。。。我真粗心!!!!
copy_kernel_page_tbls (INIT_L1_BASE,KERNEL_CODE_START,1<<30); /* 1G size */
extern unsigned long __ticks;
#define __DEBUG__
static
void schedlue ( void )
{
// ..............
sync_dcaches ();
invalidate_icaches ();
invalidate_dcaches ();
invalidate_tlbs();
set_ttb_base(current_p->ttb_base);
}
void __do_timer0 (void)
{
static unsigned i = 0;
++ i;
current_p = task_st[i & 1]; /* just 2 tasks */
__ticks ++;
.....
.....
schedule ();
}
void change_ttb_base (unsigned ttb)
{
sync_dcaches ();
invalidate_icache ();
invalidate_dcaches ();
set_ttb_base (ttb);
invalidate_tlbs ();
}