본문 바로가기
linux kernel

linux kernel study (0) - start_kernel

by 울뤀불뤀 2024. 3. 30.

linux kernel version : 6.1

arch : arm64

 

init/main.c : asmlinkage __visible void __init __no_sanitize_address start_kernel(void)

void set_task_stack_end_magic(struct task_struct *tsk)
{
    unsigned long *stackend;

    stackend = end_of_stack(tsk);
    *stackend = STACK_END_MAGIC;    /* for overflow detection */
}

end_of_stack

> 현재(커널-> 최초) 테스크 스트럭처 주소의 다음 주소를 가지고 온다. 

> kernel task의 stack 마지 막에 특정 값을 입력하여 스텍의 마지막 위치임을 표시한다. 

void __init smp_setup_processor_id(void)
{
    u64 mpidr = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
    set_cpu_logical_map(0, mpidr);

    pr_info("Booting Linux on physical CPU 0x%010lx [0x%08x]\n",
        (unsigned long)mpidr, read_cpuid_id());
}

cpu의 id를 읽어와서 0번 cpu의 정보로 기입하고 디버그 표시

static inline u64 __attribute_const__ read_cpuid_mpidr(void)
{
    return read_cpuid(MPIDR_EL1);
}
static inline u32 __attribute_const__ read_cpuid_id(void)
{
    return read_cpuid(MIDR_EL1);
}

mpidr : multiprocessor affinity regitser로 아래와 같은 정보를 포함한다.

mpidr bit 설명

 

midr : main id register로 아래와 같은 정보를 포함한다.

midr bit 설명

void __init debug_objects_early_init(void)
{
    int i;

    for (i = 0; i < ODEBUG_HASH_SIZE; i++)
        raw_spin_lock_init(&obj_hash[i].lock);

    for (i = 0; i < ODEBUG_POOL_SIZE; i++)
        hlist_add_head(&obj_static_pool[i].node, &obj_pool);
}

> debug_objects의 초기화 : debug object에 관하여 Documentation/core-api/debug-objects.rst 참고

 

void __init init_vmlinux_build_id(void)
{
    extern const void __start_notes __weak;
    extern const void __stop_notes __weak;
    unsigned int size = &__stop_notes - &__start_notes;

    build_id_parse_buf(&__start_notes, vmlinux_build_id, size);
}

> read only로 build되어 있는 linux의 builtin된 symbol영역을 vmlinux_build_id로 copy하는 과정 => debugging에 이용

 

int __init cgroup_init_early(void)
{
    static struct cgroup_fs_context __initdata ctx;
    struct cgroup_subsys *ss;
    int i;

    ctx.root = &cgrp_dfl_root;
    init_cgroup_root(&ctx);
    cgrp_dfl_root.cgrp.self.flags |= CSS_NO_REF;

    RCU_INIT_POINTER(init_task.cgroups, &init_css_set);

    for_each_subsys(ss, i) {
        WARN(!ss->css_alloc || !ss->css_free || ss->name || ss->id,
             "invalid cgroup_subsys %d:%s css_alloc=%p css_free=%p id:name=%d:%s\n",
             i, cgroup_subsys_name[i], ss->css_alloc, ss->css_free,
             ss->id, ss->name);
        WARN(strlen(cgroup_subsys_name[i]) > MAX_CGROUP_TYPE_NAMELEN,
             "cgroup_subsys_name %s too long\n", cgroup_subsys_name[i]);

        ss->id = i;
        ss->name = cgroup_subsys_name[i];
        if (!ss->legacy_name)
            ss->legacy_name = cgroup_subsys_name[i];

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

subsystem init

#define for_each_subsys(ss, ssid)                   \
    for ((ssid) = 0; (ssid) < CGROUP_SUBSYS_COUNT &&        \
         (((ss) = cgroup_subsys[ssid]) || true); (ssid)++)
#define SUBSYS(_x) [_x ## _cgrp_id] = &_x ## _cgrp_subsys,
struct cgroup_subsys *cgroup_subsys[] = {
#include <linux/cgroup_subsys.h>
};
#undef SUBSYS

ss는 cgroup_subsys.h파일의 SUBSYS 메크로들을 각 structure 별로 재정의 하여 생성한다.

ss example > 

#define SUBSYS(_x) _x ## _cgrp_id,
enum cgroup_subsys_id {
#include <linux/cgroup_subsys.h>
    CGROUP_SUBSYS_COUNT,
};
#undef SUBSYS
#define SUBSYS(_x) extern struct cgroup_subsys _x ## _cgrp_subsys;
#include <linux/cgroup_subsys.h>
#undef SUBSYS

struct cgroup_subsys cpuset_cgrp_subsys = {
    .css_alloc  = cpuset_css_alloc,
    .css_online = cpuset_css_online,
    .css_offline    = cpuset_css_offline,
    .css_free   = cpuset_css_free,
    .can_attach = cpuset_can_attach,
    .cancel_attach  = cpuset_cancel_attach,
    .attach     = cpuset_attach,
    .post_attach    = cpuset_post_attach,
    .bind       = cpuset_bind,
    .fork       = cpuset_fork,
    .legacy_cftypes = legacy_files,
    .dfl_cftypes    = dfl_files,
    .early_init = true,
    .threaded   = true,
};

 

    local_irq_disable();
    early_boot_irqs_disabled = true;

interrupt disable하고 flag 설정

 

 

 

 

 

 

출처 >

Arm® Cortex® -A53 MPCore Processor Revision: r0p4 Technical Reference Manua