3.5.1.257. set_cpu_active
//cpu: 指向特定的cpu的id号
static inline void set_cpu_active(unsigned int cpu, bool active)
{
if(active)
cpumask_set_cpu(cpu, &__cpu_active_mask);
else
cpumask_clear_cpu(cpu, &__cpu_active_mask);
}
set_cpu_active
用于设置特定CPU为active或inactive状态.
注解
内核使用__cpu_active_mask位图维护着系统内CPU的active和inactive信息
3.5.1.258. set_cpu_online
//cpu: 指向特定的cpu的id号
static inline void set_cpu_online(unsigned int cpu, bool online)
{
if(online)
cpumask_set_cpu(cpu, &__cpu_online_mask);
else
cpumask_clear_cpu(cpu, &__cpu_online_mask);
}
3.5.1.259. set_task_stack_end_magic
void set_task_stack_end_magic(struct task_struct *tsk)
{
unsigned long *stackend;
stackend = end_of_stack(tsk);
*stackend = STACK_END_MAGIC;
}
set_task_stack_end_magic
用于标记进程生长顶端地址.
注解
由于堆栈可以向上增长或向下增长,并且内核将进程的thread_info结构与进程的内核态堆栈放在同一块空间中, 为了防止两块数据相互覆盖,所以在thread_info的末尾也就是堆栈的栈顶位置记录上标志
--- +----------------+
A | |
| | |
| | stack |
| | | |
| | | |
| | | |
| | | |
| | V |
| | |
| | | +---------------+
| | | | |
| | | | |
| | | | task_struct |
| | | | |
| | | o-------------| |
| | | | | |
| +----------------+ task | | |
| | |------------(+)----------->+---------------+
| | | |
| | thread_info | |
| | structure | |
| | | |
| | | |
V | | |
--- +----------------+<------------o
3.5.1.260. setup_dma_zone
void __init setup_dma_zone(const struct machine_desc *mdesc)
{
#ifdef CONFIG_ZONE_DMA
if(mdesc->dma_zone_size) {
arm_dma_zone_size = mdesc->dma_zone_size;
arm_dma_limit = PHYS_OFFSET + arm_dma_zone_size - 1;
} else {
arm_dma_limit = 0xffffffff;
}
arm_dma_pfn_limit = arm_dma_limit >> PAGE_SHIFT;
#endif
}
setup_dma_zone
用于设置DMA阈值
3.5.1.261. setup_machine_fdt
const struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys)
{
const struct machine_desc *mdesc, *mdesc_best = NULL;
#if defined(CONFIG_ARCH_MULTIPLATFORM) || defined(CONFIG_ARM_SINGLE_ARMV7M)
DT_MACHINE_START(GENERIC_DT, "Generic DT based system")
.l2c_aux_val = 0x0,
.l2c_aux_mask = ~0x0;
MACHINE_END
mdesc_best = &__mach_desc_GENERIC_DT;
#endif
if(!dt_phys || !early_init_dt_verify(phys_to_virt(dt_phys)))
return NULL;
mdesc = of_flat_dt_match_machine(mdesc_best, arch_get_next_mach);
if(!mdesc) {
const char *prop;
int size;
unsigned long dt_root;
dt_root = of_get_flat_dt_root();
prop = of_get_flat_dt_prop(dt_root, "compatible", &size);
while(size > 0) {
size -= strlen(prop) + 1;
prop += strlen(prop) + 1;
}
dump_machine_table();
}
if(mdesc->dt_fixup)
mdesc->dt_fixup();
early_init_dt_scan_nodes();
__machine_arch_type = mdesc->nr;
return mdesc;
}
setup_machine_dt
用于获得系统的dtb,并对dtb的合法性和有效性做检测,检测通过后从dtb中获取内核初始化相关的内存信息
和cmdline信息.
3.5.1.262. setup_processor
static void __init setup_processor(void)
{
unsigned int midr = read_cpuid_id();
struct proc_info_list = lookup_processor(midr);
cpu_name = list->cpu_name;
__cpu_architecture = __get_cpu_architecture();
init_proc_vtable(list->proc);
#ifdef MULTI_TLB
cpu_tlb = *list->tlb
#endif
#ifdef MULTI_USER
cpu_user = *list->user;
#endif
#ifdef MULTI_CACHE
cpu_cache = *list->cache;
#endif
snprintf(inti_utsname()->machine, __NEW_UTS_LEN + 1, "%s%c", list->arch_name, ENDIANNESS);
snprintf(elf_platform, ELF_PLATFORM_SIZE, "%s%c", list->elf_name, ENDIANNESS);
elf_hwcap = list->elf_hwcap;
cpuid_init_hwcaps();
patch_aeabi_idiv();
#ifndef CONFIG_ARM_THUMB
elf_hwcap &= ~(HWCAP_THUMB | HWCAP_IDIVT);
#endif
#ifdef CONFIG_MMU
init_default_cache_policy(list->__cpu_mm_mmu_flags);
#endif
elf_hwcap_fixup();
cacheid_init();
cpu_init();
}
setup_processor
用于初始化体系相关的处理器
3.5.1.263. skip_spaces
char *skip_spaces(const char *str)
{
while(isspace(*str))
++str;
return (char *)str;
}
EXPORT_SYMBOL(skip_spaces);
3.5.1.264. smp_setup_processor_id
void __init smp_setup_processod_id(void)
{
int i;
u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0;
u32 cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
cpu_logical_map(1) = cpu;
for(i = 1; i < nr_cpu_ids; ++i)
cpu_logical_map(i) = i == cpu ? 0 : i;
set_my_cpu_offset(0);
}
3.5.1.265. start_kernel
asmlinage __visible void __init start_kernel(void)
{
char *command_line;
cahr *after_dashes;
set_task_stack_end_magic(&init_task);
smp_setup_processor_id();
debug_objects_early_init();
cgroup_init_early();
local_irq_disable();
early_boot_irqs_disabled = true;
boot_cpu_init();
page_address_init();
early_security_init();
setup_arch(&command_line);
setup_command_line(&command_line);
setup_nr_cpu_ids();
setup_per_cpu_areas();
smp_prepare_boot_cpu();
boot_cpu_hotplug_init();
build_all_zonelists(NULL);
page_alloc_init();
jump_label_init();
parse_early_param();
after_dashes = parse_args("Booting kernel", static_command_line, __start___param,
__stop___param - __start___param, -1, -1, NULL, &unknown_bootoption);
if(!IS_ERR_OR_NULL(after_dashes))
parse_args("Setting init args", after_dashes, NULL, 0, -1, -1, NULL, set_init_arg);
setup_log_buf(0);
vfs_caches_init_early();
sort_main_extable();
trap_init();
mm_init();
ftrace_init();
early_trace_init();
sched_init();
preempt_disable();
if(WARN(!irqs_disable(), "Interrupts were enabled *very* early, fixing it\n"))
local_irq_disable();
radix_tree_init();
housekeeping_init();
workqueue_init_early();
rcu_init();
trace_init();
if(initcall_debug)
initcall_debug_enable();
context_tracking_init();
early_irq_init();
init_IRQ();
tick_init();
rcu_init_nohz();
init_timers();
hrtimers_init();
softirq_init();
timekeeping_init();
rand_initialize();
add_latent_entropy();
add_device_randomness(comand_line, strlen(command_line));
boot_init_stack_canary();
time_init();
perf_event_init();
profile_init();
call_function_init();
early_boot_irqs_disabled = false;
local_irq_enable();
kmem_cache_init_late();
console_init();
if(panic_later)
panic("Too many boot %s vars at '%s'", panic_later, panic_param);
lockdep_init();
locking_selftest();
mem_encrypt_init();
#ifdef CONFIG_BLK_DEV_INITRD
if(initrd_start && !initrd_below_start_ok && page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) {
pr_crit("initrd overwritten (0x%081x < 0x%081x) - disabing it.\n", page_to_pfn(virt_to_page((void *)initrd_start)), min_low_pfn);
initrd_start = 0;
}
#endif
setup_per_cpu_pageset();
numa_policy_init();
acpi_early_init();
if(late_time_init)
late_time_init();
sched_clock_init();
calibrate_delay();
pid_idr_init();
anon_vma_init();
thread_stack_cache_init();
cred_init();
fork_init();
proc_caches_init();
ute_ns_init();
buffer_init();
key_init();
security_init();
dbg_late_init();
vfs_caches_init();
pagecache_init();
signals_init();
seq_file_init();
proc_root_init();
nsfs_init();
cpuset_init();
cgroup_init();
taskstats_init_early();
delayacct_init();
poking_init();
check_bugs();
acpi_subsystem_init();
arch_post_acpi_subsys_init();
sfi_init_late();
arch_call_rest_init();
prevent_tail_call_optimization();
}