x86系统引导(4)

上一篇说到了下面这个函数,接着说。前面已经建立了内存页面管理所需的数据结构,现在进一步完善页面映射机制。

paging_init();

此函数源码如下:

/*
 * paging_init() sets up the page tables - note that the first 8MB are
 * already mapped by head.S.

 *
 * This routines also unmaps the page at virtual kernel address 0, so
 * that we can trap those pesky NULL-reference errors in the kernel.
 */
void __init paging_init(void)
{
#ifdef CONFIG_X86_PAE
.....
#endif


pagetable_init();通过此函数扩充在系统初始化(那些汇编代码)创建的页面映射目录和页面映射表。看上面那行红色的注释。


load_cr3(swapper_pg_dir);装载页面目录到cr3


#ifdef CONFIG_X86_PAE
.........
#endif
.........
}

/*
* NOTE: at this point the bootmem allocator is fully available.
*/


#ifdef CONFIG_EARLY_PRINTK
{
........
}
#endif




dmi_scan_machine();

此函数的作用

SMBIOS/DMI : System Management BIOS/Desktop Management Interface. PC的BIOS规范。(摘于网络)



#ifdef CONFIG_X86_GENERICARCH
.......
#endif


register_memory(max_low_pfn);物理页面是一种资源,从另外一个角度,地址空间本身也是一种资源吗,所以要加以管理,分配。 对系统I/O资源生成资源树 ,源码如下:

/*
 * Request address space for all standard resources
 */

这里涉及到一个很重要的数据结构,它描述了一片可以通过访问内存操作或I/O操作加以访问的连续空间。每个resource结构通过struct resource *parent, *sibling, *child;等指针联系在一起,形成树状结构。内核中有两颗这样的树,分别代表着两类不同性质的地址资源。



/* PC/ISA/whatever - the normal PC address spaces: IO and memory */

struct resource ioport_resource = {
.name = "PCI IO",
.start = 0x0000,
.end = IO_SPACE_LIMIT,
.flags = IORESOURCE_IO,
};

struct resource iomem_resource = {
.name = "PCI mem",
.start = 0UL,
.end = ~0UL,
.flags = IORESOURCE_MEM,
};

/*
 * Resources are tree-like, allowing
 * nesting etc..
 */
struct resource {
const char *name;
unsigned long start, end;
unsigned long flags;
struct resource *parent, *sibling, *child;
};
static void __init register_memory(unsigned long max_low_pfn)
{
unsigned long low_mem_size;
int      i;


if (efi_enabled)
efi_initialize_iomem_resources(&code_resource, &data_resource);

前几篇对这个EFI都没说什么,因为实在不知道他是什么?后来查了下资料,EFI是可扩展固件接口(英文名Extensible Firmware Interface 或EFI)是由英特尔,一个主导个人电脑技术研发的公司推出的一种在未来的类PC的电脑系统中替代BIOS的升级方案。BIOS技术的兴起源于IBM PC/AT机器的流行以及第一台由康柏公司研制生产的“克隆”PC。在PC启动的过程中,BIOS担负着初始化硬件,检测硬件功能,以及引导操作系统的责任,在早期,BIOS还提供一套运行时的服务程序给操作系统及应用程序使用。BIOS程序存放于一个掉电后内容不会丢失的只读存储器中,系统加电时处理器的第一条指令的地址会被定位到BIOS的存储器中,便于使初始化程序得到执行。
else
legacy_init_iomem_resources(&code_resource, &data_resource);

这些是内核代码段和数据段中的地址信息。
......

/* request I/O space for devices used on all i[345]86 PCs */
for (i = 0; i < STANDARD_IO_RESOURCES; i++)
request_resource(&ioport_resource, &standard_io_resources[i]);

看一下它的参数standard_io_resources[i],是系统的固有I/O资源。只列出几个

static struct resource standard_io_resources[] = { {
.name = "dma1",
.start = 0x0000,
.end = 0x001f,
.flags = IORESOURCE_BUSY | IORESOURCE_IO
}, {
.name = "pic1",
.start = 0x0020,
.end = 0x0021,
.flags = IORESOURCE_BUSY | IORESOURCE_IO
}, {
.name   = "timer0",
.start = 0x0040,
.end    = 0x0043,
.flags  = IORESOURCE_BUSY | IORESOURCE_IO
}

最重要的就是这个函数,我们先列出其源码:

int request_resource(struct resource *root, struct resource *new)
{
struct resource *conflict;


write_lock(&resource_lock);
conflict = __request_resource(root, new);

继续

/* Return the conflict entry if you can't request it */对资源的合理性加以判定,不能冲突。
static struct resource * __request_resource(struct resource *root, struct resource *new)
{
unsigned long start = new->start;
unsigned long end = new->end;
struct resource *tmp, **p;


if (end < start)
return root;
if (start < root->start)
return root;
if (end > root->end)
return root;
p = &root->child;
for (;;) {
tmp = *p;
if (!tmp || tmp->start > end) {
new->sibling = tmp;
*p = new;
new->parent = root;
return NULL;
}
p = &tmp->sibling;
if (tmp->end < start)
continue;
return tmp;
}
}
write_unlock(&resource_lock);
return conflict ? -EBUSY : 0;
}


.........

}



#ifdef CONFIG_VT
.......
#endif
}

}

setup_arch函数终于完了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值