- 论坛徽章:
- 0
|
uClinux初始化阶段start_kernel()会调用sched_init()函数:
asmlinkage void __init start_kernel(void)
{
char * command_line;
extern char saved_command_line[];
/*
* Interrupts are still disabled. Do necessary setups, then
* enable them
*/
lock_kernel();
printk(linux_banner);
setup_arch(&command_line);
printk("Kernel command line: %s\n", saved_command_line);
parse_options(command_line);
trap_init();
init_IRQ();
sched_init();
......
}
/* kernel/sched.c, L1383: */
void __init sched_init(void)
{
......
init_bh(TIMER_BH, timer_bh);
init_bh(TQUEUE_BH, tqueue_bh);
init_bh(IMMEDIATE_BH, immediate_bh);
/*
* The boot idle thread does lazy MMU switching as well:
*/
atomic_inc(&init_mm.mm_count);
enter_lazy_tlb(&init_mm, current, cpu);
}
其中enter_lazy_tlb()函数使用current变量做为一个参数。以前只知道current表示当前任务。然而在初始化阶段“当前任务”又是谁呢,又是从哪里获得的呢?
/* include/asm-armnommu/current.h */
static inline struct task_struct *get_current(void) __attribute__ (( __const__ ));
static inline struct task_struct *get_current(void)
{
register unsigned long sp asm ("sp");
return (struct task_struct *)(sp & ~0x1fff);
}
#define current (get_current())
也就是说,当前堆栈指针SP的值取高19位,即2^13 = 8182字节的边界处。此结论如何得出的呢?见下:
/* arch/armnommu/kernel/head-armv.S, L459 */
.long init_task_union+8192 @ sp
/* arch/armnommu/kernel/init_task.c, L17 */
/*
* Initial task structure.
*
* We need to make sure that this is 8192-byte aligned due to the
* way process stacks are handled. This is done by making sure
* the linker maps this in the .text segment right after head.S,
* and making head.S ensure the proper alignment.
*
* The things we do for performance..
*/
union task_union init_task_union __attribute__((__section__(".init.task"))) =
{ INIT_TASK(init_task_union.task) };
/* include/linux/sched.h, L577 */
#ifndef INIT_TASK_SIZE
# define INIT_TASK_SIZE 2048*sizeof(long)
#endif
union task_union {
struct task_struct task;
unsigned long stack[INIT_TASK_SIZE/sizeof(long)];
};
这表示task_union占用2048 * sizeof(long) = 8192字节,即2个page。
而在arch/armnommu/vmlinux.lds里
...
. = ALIGN(8192);
.data : {
__data_start = .;
/*
* first, the init task union, aligned
* to an 8192 byte boundary.
*/
*(.init.task)
以此就能保证init_task是在8192字节的边界上了。
于是,include/asm-armnommu/current.h里get_current函数自然就能得到指向init_task控制块的指针了。
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/17532/showart_2068940.html |
|