1.start_kernel函数中的第一个函数是lock_kernel()
它是指大内核锁,本质上是自旋锁,但又不同于自旋锁,自旋锁不可以递归获得锁的,因为那样会导致死锁,但大内核锁可以递归获得锁,大内核锁用于保护整个内核,而自旋锁用于保护非常特定的某一共享资源。从2.6.11内核起,大内核锁可以通过配置内核来实现,但一般在内核中使用较少。具体定义在文件include/linux/smp_lock.h中,如果定义CONFIG_LOCK_KERNEL的话,它定义为extern void __lockfunc lock_kernel(void) __acquires(kernel_lock),其中的__lockfunc定义在include/linux/spinlock.h中,实现如下:
#define __lockfunc fastcall __attribute__((section(".spinlock.text"))),而fastcall定义在文件include/asm-i386/linkage.h中,实现为:#define fastcall __attribute__((regparm(3))),
__acquires(x)定义在include/linux/compiler.h文件中,实现为# define __acquires(x) __attribute__((context(0,1))),总的来说,如果定义CONFIG_LOCK_KERNEL的话,它的定义:
extern void __attirbute__((regparm(3))) __attribure__((section(“.spinlock.text”))) lock_kernel(void) __attribure__((context(0,1))),如果没有定义CONFIG_LOCK_KERNEL的话,它的定义为:
#define lock_kernel() do{}while(0),什么也不做;
2.start_kernel函数中的第二个函数是page_address_init()
它定义在文件include/linux/mm.h中,具体实现如下:
#if defined(WANT_PAGE_VIRTUAL)
#define page_address_init() do { } while(0)
#if defined(HASHED_PAGE_VIRTUAL)
void page_address_init(void);
#if !defined(HASHED_PAGE_VIRTUAL) && !defined(WANT_PAGE_VIRTUAL)
#define page_address_init() do { } while(0)
当WANT_PAGE_VIRTUAL设定时,系统有直接内存映射,在这种情况下,简单地计算虚拟内存位置可以充分的访问内存位置,如果所有的RAM不是映射到内核地址空间(当himem被设置的话,这种情况经常发生),我们需要其他方式来获得内存地址,这就是初始化页地址必须仅在HASHED_PAGE_VIRTUAL被设定的情况下定义的原因。当我们需要初始化虚拟内存时,内核必须配置HASHED_PAGE_VIRTUAL,在这种情况下内核能接入的内存大小将大于内核地址空间映射的大小(通常为4GB)。
阅读(2110) | 评论(0) | 转发(0) |