start_kernel初步学习(1)

start_kernel函数是linux内核的启动函数

1. 首先,先初始化lockdep,lockdep是linux死锁检测模块,用来检测死锁的发生

void lockdep_init(void)
{
    int i;

    /* 这里只是初始化hash,lockdep_initialized确保hash只被初始化一次 */
    /*
     * Some architectures have their own start_kernel()
     * code which calls lockdep_init(), while we also
     * call lockdep_init() from the start_kernel() itself,
     * and we want to initialize the hashes only once:
     */
    if (lockdep_initialized)
        return;

    for (i = 0; i < CLASSHASH_SIZE; i++)
        INIT_LIST_HEAD(classhash_table + i);

    for (i = 0; i < CHAINHASH_SIZE; i++)
        INIT_LIST_HEAD(chainhash_table + i);

    lockdep_initialized = 1;
}

2. debug_objects_early_init函数,debug objects是用来进行内核对象调试的

/*
 * Called during early boot to initialize the hash buckets and link
 * the static object pool objects into the poll list. After this call
 * the object tracker is fully operational.
 */
void __init debug_objects_early_init(void)
{
    int i;

    /* 初始化obj_hash的自旋锁 */
    for (i = 0; i < ODEBUG_HASH_SIZE; i++)
        raw_spin_lock_init(&obj_hash[i].lock);

    /* 将obj_static_pool的节点添加到hash链中 */
    for (i = 0; i < ODEBUG_POOL_SIZE; i++)
        hlist_add_head(&obj_static_pool[i].node, &obj_pool);
}


3. boot_init_stack_canary函数用来初始化canary,canary是一种栈溢出的保护机制,详情参考 https://www.ibm.com/developerworks/cn/linux/l-cn-gccstack/

__always_inline是gcc编译器的一个内嵌功能,表示该函数总是被处理成内联函数

static __always_inline void boot_init_stack_canary(void)
{
    u64 canary;
    u64 tsc;

#ifdef CONFIG_X86_64
    BUILD_BUG_ON(offsetof(union irq_stack_union, stack_canary) != 40);
#endif
    /*
     * We both use the random pool and the current TSC as a source
     * of randomness. The TSC only matters for very early init,
     * there it already has some randomness on most systems. Later
     * on during the bootup the random pool has true entropy too.
     */
    get_random_bytes(&canary, sizeof(canary));
    tsc = __native_read_tsc();
    canary += tsc + (tsc << 32UL);

    current->stack_canary = canary;
#ifdef CONFIG_X86_64
    percpu_write(irq_stack_union.stack_canary, canary);
#else
    percpu_write(stack_canary.canary, canary);
#endif
}

4. cgroup_init_early初始化cgroup, Cgroups control groups 的缩写,是 Linux 内核提供的一种可以限制、记录、隔离进程组( process groups )所使用的物理资源(如: cpu,memory,IO 等等)的机制。最初由 google 的工程师提出,后来被整合进 Linux 内核。
cgroups请参考 http://www.cnblogs.com/lisperl/archive/2012/04/17/2453838.html

/**
 * cgroup_init_early - cgroup initialization at system boot
 *
 * Initialize cgroups at system boot, and initialize any
 * subsystems that request early init.
 */
int __init cgroup_init_early(void)
{
    int i;
    atomic_set(&init_css_set.refcount, 1);
    INIT_LIST_HEAD(&init_css_set.cg_links);
    INIT_LIST_HEAD(&init_css_set.tasks);
    INIT_HLIST_NODE(&init_css_set.hlist);
    css_set_count = 1;
    init_cgroup_root(&rootnode);
    root_count = 1;
    init_task.cgroups = &init_css_set;

    init_css_set_link.cg = &init_css_set;
    init_css_set_link.cgrp = dummytop;
    list_add(&init_css_set_link.cgrp_link_list,
         &rootnode.top_cgroup.css_sets);
    list_add(&init_css_set_link.cg_link_list,
         &init_css_set.cg_links);

    for (i = 0; i < CSS_SET_TABLE_SIZE; i++)
        INIT_HLIST_HEAD(&css_set_table[i]);

    /* at bootup time, we don't worry about modular subsystems */
    for (i = 0; i < CGROUP_BUILTIN_SUBSYS_COUNT; i++) {
        struct cgroup_subsys *ss = subsys[i];

        BUG_ON(!ss->name);
        BUG_ON(strlen(ss->name) > MAX_CGROUP_TYPE_NAMELEN);
        BUG_ON(!ss->create);
        BUG_ON(!ss->destroy);
        if (ss->subsys_id != i) {
            printk(KERN_ERR "cgroup: Subsys %s id == %d\n",
                   ss->name, ss->subsys_id);
            BUG();
        }

        if (ss->early_init)
            cgroup_init_subsys(ss);
    }
    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值