linux init_task 的初始化
来源:互联网 发布:知乎双肩包推荐 编辑:程序博客网 时间:2024/06/01 10:13
linux init_task 的初始化
日期
内核版本
架构
作者
2017-03-17
Linux-3.4.0
arm
jlovej
前言:
Init_task 是系统的0号进程,又称swapper进程,又称idle任务。它是所有进程、线程的祖宗,包括1号进程init,2号内核线程kthreadd。
Init_task的栈针sp:
进入start_kernel,可以说就已经运行在init_task的上下文了,因为此时栈针sp已经指向init_task的栈了。
Init_task的栈:
linux/arch/arm/kernel/init_task.c中:
structtask_struct init_task = INIT_TASK(init_task);
unionthread_union init_thread_union __init_task_data =
{ INIT_THREAD_INFO(init_task) };
init_thread_union即为init_task的栈,也是一个8K对齐的thread_info结构体。init_thread_union为静态变量,被编译到内核的data段。
系统栈针sp的初始化:
linux/arch/arm/kernel/head.S中:
ENTRY(stext)
…
ldr r13, =__mmap_switched @address to jump to after
@mmu has been enabled
adr lr, BSYM(1f) @return (PIC) address
mov r8, r4 @set TTBR1 to swapper_pg_dir
ARM( add pc, r10, #PROCINFO_INITFUNC )
1: b __enable_mmu
系统使能mmu时,跳转到__turn_mmu_on,enablemmu后跳转到r13,即__mmap_switched,最后跳转到start_kernel。
linux/arch/arm/kernel/head-common.S中
__mmap_switched:
adr r3, __mmap_switched_data
ldmia r3!, {r4, r5, r6, r7}
cmp r4, r5 @Copy data segment if needed
1: cmpne r5, r6
ldrne fp, [r4], #4
strne fp, [r5], #4
bne 1b
mov fp, #0 @Clear BSS (and zero fp)
1: cmp r6,r7
strcc fp, [r6],#4
bcc 1b
ARM( ldmia r3, {r4, r5, r6, r7, sp})
str r9, [r4] @Save processor ID
str r1, [r5] @Save machine type
str r2, [r6] @Save atags pointer
bic r4, r0, #CR_A @Clear 'A' bit
stmia r7, {r0, r4} @Save control register values
b start_kernel
ENDPROC(__mmap_switched)
.align 2
.type __mmap_switched_data, %object
__mmap_switched_data:
.long __data_loc @r4
.long _sdata @r5
.long __bss_start @r6
.long _end @r7
.long processor_id @r4
.long __machine_arch_type @r5
.long __atags_pointer @r6
.long cr_alignment @r7
.long init_thread_union + THREAD_START_SP @ sp
.size __mmap_switched_data, . - __mmap_switched_data
其中,ARM( ldmia r3, {r4, r5, r6,r7, sp})赋值sp
sp = init_thread_union +THREAD_START_SP,即init_task的栈顶。
所以,之后start_kernel中的任务都是基于此sp。当然,中断有中断的栈。
Init_task的后续初始化:
http://blog.csdn.net/gatieme/article/details/51484562
进程userspace栈的由来:
一个普通进程,其userspace栈大小可以通过cat/proc/$pid/limits |grep stack 看到。栈大小是由task_struct->signal->rlim[RLIMIT_STACK]决定的,在该进程被创建时,rlim是复制从父进程的rlim:
do_fork àcopy_processà copy_signal:
memcpy(sig->rlim, current->signal->rlim, sizeofsig->rlim);
父进程又是复制爷爷的,爷爷又是复制祖宗的,最终还是拷贝的init_task的rlim。
而init_task的rlim在这定义的:
#define INIT_RLIMITS \
{ \
[RLIMIT_CPU] = { RLIM_INFINITY, RLIM_INFINITY }, \
[RLIMIT_FSIZE] = { RLIM_INFINITY, RLIM_INFINITY }, \
[RLIMIT_DATA] = { RLIM_INFINITY, RLIM_INFINITY }, \
[RLIMIT_STACK] = { _STK_LIM, _STK_LIM_MAX }, \
[RLIMIT_CORE] = { 0, RLIM_INFINITY }, \
[RLIMIT_RSS] = { RLIM_INFINITY, RLIM_INFINITY }, \
[RLIMIT_NPROC] = { 0, 0 }, \
[RLIMIT_NOFILE] = { INR_OPEN_CUR, INR_OPEN_MAX }, \
[RLIMIT_MEMLOCK] = { MLOCK_LIMIT, MLOCK_LIMIT }, \
[RLIMIT_AS] = { RLIM_INFINITY, RLIM_INFINITY }, \
[RLIMIT_LOCKS] = { RLIM_INFINITY, RLIM_INFINITY }, \
[RLIMIT_SIGPENDING] = { 0, 0 }, \
[RLIMIT_MSGQUEUE] = { MQ_BYTES_MAX, MQ_BYTES_MAX }, \
[RLIMIT_NICE] = { 0, 0 }, \
[RLIMIT_RTPRIO] = { 0, 0 }, \
[RLIMIT_RTTIME] = { RLIM_INFINITY, RLIM_INFINITY }, \
}
在我的系统上,#define_STK_LIM (8*1024*1024),用户态栈大小默认是8M。
- linux init_task 的初始化
- init_task
- 一个Linux内核利用init_task进行进程管理的简单例子
- 一个Linux内核利用init_task进行进程管理的简单例子
- Linux下0号进程的前世(init_task进程)今生(idle进程)----Linux进程的管理与调度(五)
- Linux下0号进程的前世(init_task进程)今生(idle进程)----Linux进程的管理与调度
- Linux进程的管理与调度(五) -- Linux下0号进程的前世(init_task进程)今生(idle进程)
- Linux下0号进程的前世(init_task进程)今生(idle进程)----Linux进程的管理与调度(五)
- Linux内核中的init_task进程和idle进程
- Linux内核中的init_task进程和idle进程
- Linux内核中的init_task进程和idle…
- Linux内核中的init_task进程和idle…
- Linux内核中的init_task进程和idle进程
- Linux内核中的init_task进程和idle进程
- Linux内核中的init_task进程和idle进程
- Linux的内存初始化
- linux的swapper_pg_dir的初始化
- linux的swapper_pg_dir的初始化
- 彻底理解android中的内部存储与外部存储
- Rx常用操作符
- rx+retrofit 学习笔记
- [我眼中的C#]委托和Lambda表达式
- 【LeetCode】520. Detect Capital
- linux init_task 的初始化
- CSDN博客页面去广告的解决
- MySQL数据库学习笔记(五)----MySQL字符串函数、日期时间函数
- NOIP普及2016悲惨翻车记
- Jmeter使用流程及简单分析监控
- apt-get出现失败时
- ee
- Cranking the Coding Interview: Recursion and Dynamic Programming
- Java socket通信已经被封装好了主要使用两个类ServerSocket 和Socket