浅谈分析Arm linux 内核移植及系统初始化的过程二
设备描述主要两个结构体完成:structresource和structplatform_device。
先来看看着两个结构体的定义:
structresource{
resource_size_tstart;
resource_size_tend;
constchar*name;
unsignedlongflags;
structresource*parent,*sibling,*child;
};
Resource结构体主要是描述了设备在系统中的起止地址、名称、标志以及为了链式描述方便指向本结构体类型的指针。Resource定义的实例将被添加到platform_device结构体对象中去。
structplatform_device{
constchar *name;
u32 id;
structdevice dev;
u32 num_resources;
structresource *resource;
};
Platform_device结构体包括结构体的名称、ID号、平台相关的信息、设备的数目以及上面定义的resource信息。Platform_device结构对象将被直接通过设备操作函数注册导系统中去。具体注册和注销过程在下一节介绍。
4.3. 处理器、设备4.4. 操作
(1)intplatform_device_register(structplatform_device*pdev);注册设备
(2)voidplatform_device_unregister(structplatform_device*pdev);注销设备
(3)intplatform_add_devices(structplatform_device**devs,intnum);添加设备,通过调用上面两个函数实现。
4.5. 添加Nandflash设备4.6.
下面以nandflash设备的描述为例,具体介绍下设备的描述和注册过程。
//resource结构体实例s3c_nand_resource对nandflash控制器描述,包括控制器的起止地址和标志。
staticstructresources3c_nand_resource[]={
[0]={
.start=S3C2410_PA_NAND,
.end=S3C2410_PA_NAND+S3C24XX_SZ_NAND-1,
.flags=IORESOURCE_MEM,
}
};
//platform_device结构体实例s3c_device_nand定义了设备的名称、ID号并把resource对象作为其成员之一。
structplatform_devices3c_device_nand={
.name ="s3c2410-nand",
.id =-1,
.num_resources =ARRAY_SIZE(s3c_nand_resource),
.resource =s3c_nand_resource,
};
//nandflash的分区情况,由mtd_partition结构体定义。
staticstructmtd_partitionsmdk_default_nand_part[]={
[0]={
.name ="BootAgent",
.size =SZ_16K,
.offset =0,
},
[1]={
.name ="S3C2410flashpartition1",
.offset=0,
.size =SZ_2M,
},
[2]={
.name ="S3C2410flashpartition2",
.offset=SZ_4M,
.size =SZ_4M,
},
[3]={
.name ="S3C2410flashpartition3",
.offset =SZ_8M,
.size =SZ_2M,
},
[4]={
.name ="S3C2410flashpartition4",
.offset = SZ_1M * 10,
.size = SZ_4M,
},
[5] = {
.name = "S3C2410 flash partition 5",
.offset = SZ_1M * 14,
.size = SZ_1M * 10,
},
[6] = {
.name = "S3C2410 flash partition 6",
.offset = SZ_1M * 24,
.size = SZ_1M * 24,
},
[7] = {
.name = "S3C2410 flash partition 7",
.offset = SZ_1M * 48,
.size = SZ_16M,
}
};
static struct s3c2410_nand_set smdk_nand_sets[] = {
[0] = {
.name = "NAND",
.nr_chips = 1,
.nr_partitions = ARRAY_SIZE(smdk_default_nand_part),
.partitions = smdk_default_nand_part,
},
};
/* choose a set of timings which should suit most 512Mbit
* chips and beyond.
*/
static struct s3c2410_platform_nand smdk_nand_info = {
.tacls = 20,
.twrph0 = 60,
.twrph1 = 20,
.nr_sets = ARRAY_SIZE(smdk_nand_sets),
.sets = smdk_nand_sets,
};
/* devices we initialise */
// 最后将nand flash 设备加入到系统即将注册的设备集合中。
static struct platform_device __initdata *smdk_devs[] = {
&s3c_device_nand,
&smdk_led4,
&smdk_led5,
&smdk_led6,
&smdk_led7,
};
然后通过smdk_machine_init()函数,调用设备添加函数platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs)) 完成设备的注册。具体过程参见系统初始化的相关部分。
5. 系统初始化
5.1. 系统初始化的主干线
Start_kernel() èsetup_arch() èreset_init() è kernel_thread(init …) è init() è do_basic_setup() èdriver_init() è do_initcall()
Start_kernel()函数负责初始化内核各个子系统,最后调用reset_init(),启动一个叫做init的内核线程,继续初始化。Start_kernel()函数在init/main.c中实现。
asmlinkage void __init start_kernel(void)
{
char * command_line;
extern struct kernel_param __start___param[], __stop___param[];
smp_setup_processor_id();
/*
* Need to run as early as possible, to initialize the
* lockdep hash:
*/
lockdep_init();
local_irq_disable();
early_boot_irqs_off();
early_init_irq_lock_class();
Armlinux内核移植系统初始 相关文章:
- Arm linux 内核移植及系统初始化过程分析(11-09)
- 浅谈分析Arm linux 内核移植及系统初始化的过程四(11-09)
- 浅谈分析Arm linux 内核移植及系统初始化的过程一(11-09)
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)