免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1166 | 回复: 0
打印 上一主题 下一主题

uCLinux初始化阶段current的来历 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-10-13 09:42 |只看该作者 |倒序浏览

uClinux初始化阶段start_kernel()会调用sched_init()函数:
asmlinkage void __init start_kernel(void)
{
    char * command_line;
    extern char saved_command_line[];
/*
* Interrupts are still disabled. Do necessary setups, then
* enable them
*/
    lock_kernel();
    printk(linux_banner);
    setup_arch(&command_line);
    printk("Kernel command line: %s\n", saved_command_line);
    parse_options(command_line);
    trap_init();
    init_IRQ();
    sched_init();
    ......
}
/* kernel/sched.c, L1383: */
void __init sched_init(void)
{
    ......
   
    init_bh(TIMER_BH, timer_bh);
    init_bh(TQUEUE_BH, tqueue_bh);
    init_bh(IMMEDIATE_BH, immediate_bh);
    /*
     * The boot idle thread does lazy MMU switching as well:
     */
    atomic_inc(&init_mm.mm_count);
    enter_lazy_tlb(&init_mm, current, cpu);
}
其中enter_lazy_tlb()函数使用current变量做为一个参数。以前只知道current表示当前任务。然而在初始化阶段“当前任务”又是谁呢,又是从哪里获得的呢?
/* include/asm-armnommu/current.h */
static inline struct task_struct *get_current(void) __attribute__ (( __const__ ));
static inline struct task_struct *get_current(void)
{
    register unsigned long sp asm ("sp");
    return (struct task_struct *)(sp & ~0x1fff);
}
#define current (get_current())
也就是说,当前堆栈指针SP的值取高19位,即2^13 = 8182字节的边界处。此结论如何得出的呢?见下:
/* arch/armnommu/kernel/head-armv.S, L459 */
                .long   init_task_union+8192    @ sp
/* arch/armnommu/kernel/init_task.c, L17 */
/*
* Initial task structure.
*
* We need to make sure that this is 8192-byte aligned due to the
* way process stacks are handled. This is done by making sure
* the linker maps this in the .text segment right after head.S,
* and making head.S ensure the proper alignment.
*
* The things we do for performance..
*/
union task_union init_task_union __attribute__((__section__(".init.task"))) =
        { INIT_TASK(init_task_union.task) };
/* include/linux/sched.h, L577 */
#ifndef INIT_TASK_SIZE
# define INIT_TASK_SIZE 2048*sizeof(long)
#endif
union task_union {
    struct task_struct task;
    unsigned long stack[INIT_TASK_SIZE/sizeof(long)];
};
这表示task_union占用2048 * sizeof(long) = 8192字节,即2个page。
而在arch/armnommu/vmlinux.lds里
    ...
    . = ALIGN(8192);
    .data : {
            __data_start = .;
        /*
         * first, the init task union, aligned
         * to an 8192 byte boundary.
         */
        *(.init.task)
以此就能保证init_task是在8192字节的边界上了。
于是,include/asm-armnommu/current.h里get_current函数自然就能得到指向init_task控制块的指针了。


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/17532/showart_2068940.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP