start_kernel函数详解系列之【fork_init】
一、开篇小聊
在start_kernel()
中会调用fork_init()
函数,该函数定义在(/kernel/fork.c)文件中:
void __init fork_init(void)
{
#ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR
#ifndef ARCH_MIN_TASKALIGN
#define ARCH_MIN_TASKALIGN L1_CACHE_BYTES
#endif
/* create a slab on which task_structs can be allocated */
task_struct_cachep =
kmem_cache_create("task_struct", sizeof(struct task_struct),
ARCH_MIN_TASKALIGN, SLAB_PANIC | SLAB_NOTRACK, NULL);
#endif
/* do the arch specific task caches init */
arch_task_cache_init();
set_max_threads(MAX_THREADS);
init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2;
init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2;
init_task.signal->rlim[RLIMIT_SIGPENDING] =
init_task.signal->rlim[RLIMIT_NPROC];
}
下文,就来分析一下该函数。
首先,会调用kmem_cache_create()
函数分配task_struct_cachep
slab描述符,这部分操作由CONFIG_ARCH_TASK_STRUCT_ACLLOCATOR内核配置宏来管控,如果内核中没有定义该宏定义,那么将不会进行task_struct_cachep slab内存分配、释放等操作,如下代码:
#ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR
#ifndef ARCH_MIN_TASKALIGN
#define ARCH_MIN_TASKALIGN L1_CACHE_BYTES
#endif
/* create a slab on which task_structs can be allocated */
task_struct_cachep =
kmem_cache_create("task_struct", sizeof(struct task_struct),
ARCH_MIN_TASKALIGN, SLAB_PANIC | SLAB_NOTRACK, NULL);
#endif
接着,会计算内核中允许的默认最大线程数,,如下代码:
set_max_threads(MAX_THREADS);
其中MAX_THREADS宏定义如下:
#define FUTEX_TID_MASK 0x3fffffff
#define MAX_THREADS FUTEX_TID_MASK
在fork_init()
函数的最后,会初始化信号handler,如下代码片段:
init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2;
init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2;
init_task.signal->rlim[RLIMIT_SIGPENDING] =
init_task.signal->rlim[RLIMIT_NPROC];
这里出现了init_task这个全局量。init_task是struct task_struct
结构的一个实例,该结构中包含信号字段,用于表示信号处理程序。在上述代码中的前2行,会设置当前(rlim_cur
)和最大资源(rlim_max
)限制。每个进程都有一组与其相关的资源限制。这些限制指定了当前进程可以使用的资源数量。rlim
是资源控制的极限,其结构定义如下:
struct rlimit {
__kernel_ulong_t rlim_cur;
__kernel_ulong_t rlim_max;
};
在linux shell命令行下输入cat /proc/self/limits
命令,可查看内核中的资源控制数。如下图所示:
这里有一个测试,如果写一个linux的测试程序:在一个函数中定义一个“超级大”的数组,编译运行,linux内核会有怎样的反应呢?从上图中“Max stack size”一栏可见,内核限制了最大的stack大小,约为8M,如果我们的数组大小超过了这个值,就有问题啦…
搜索关注【嵌入式小生】wx公众号获取更多精彩内容。