linux内核启动顺序,嵌入式Linux内核启动顺序【简析】

嵌入式Linux内核启动顺序【简析】

看了点代码,就我了解的kernel启动的顺序,说说情况:

从initmain.c中的start_kernel()开始:

该函数中,主要做了下列事情:

(1)先是

boot_cpu_init();

初始化了启动相关的内容后

然后

printk(KERN_NOTICE);

printk(linux_banner);

打印内核信息,比如我这里的:

Linux version 2.6.22.2 (crifan@localhost.localdomain) (gcc version 4.3.2 (GCC) ) #89 Fri May 15 11:25:09 CST 2009

(2)

其后主要初始化了中断,时钟等:

init_IRQ();

init_timers();

softirq_init();

(3)

再打印出命令行:

printk(KERN_NOTICE "Kernel command line: %sn", boot_command_line);

如此处的:

Kernel command line: root=/dev/mtdblock2 rw init=/linuxrc console=ttyS0,115200 mem=64M rootfstype=jffs2

(4)

后来才是调用

console_init();

去初始化Uart的,就是调用uart的probe函数。

(5)

先预初始化:

cpuset_init_early();

(6)

初始化内存:

mem_init();

(7)

初始化buffer:

buffer_init();

再初始化cpu(组):

cpuset_init();

(8)

用check_bugs();

去测试CPU的相关情况:

CPU: Testing write buffer coherency: ok

(9)

最后调用:

rest_init();

去启动线程

kernel_init

{

。。。

do_basic_setup();

。。。

init_post();

}

其中调用

do_basic_setup();

{

。。。

driver_init();

。。。

do_initcalls();

。。。

}

去初始化Linux kernel相关的内容

其中

driver_init()

{

/* These are the core pieces */

devices_init();

buses_init();

classes_init();

firmware_init();

hypervisor_init();

/* These are also core pieces, but must come after the

* core core pieces.

*/

platform_bus_init();

system_bus_init();

cpu_dev_init();

memory_dev_init();

attribute_container_init();

}

初始化真正的系统的

device,bus,class等等内容,

然后的

do_initcalls()

{

//从__Start 开始 到 __End 结束,

//以此调用之前内核中相关的__init前缀的那些初始化函数

}

其中,这些用__init标明的函数,可以在system.map中看到对应的信息,

包括对应的变量和其对应的地址

c001d164 t __initcall_ptrace_break_init1

c001d164 T __initcall_start

c001d168 t __initcall_consistent_init1

c001d16c t __initcall_sysctl_init1

c001d170 t __initcall_init_jiffies_clocksource1

c001d174 t __initcall_pm_init1

c001d178 t __initcall_ksysfs_init1

。。。。。。。。。。。。。。。

c001d194 t __initcall_sock_init1

c001d198 t __initcall_netlink_proto_init1

c001d19c t __initcall_kobject_uevent_init2

c001d1a0 t __initcall_amba_init2

c001d1a4 t __initcall_tty_class_init2

c001d1a8 t __initcall_vtconsole_class_init2

c001d1ac t __initcall_customize_machine3

。。。。。。。。。。。

c001d1b0 t __initcall_clk_init3

c001d1b4 t __initcall_dma_init3

c001d1bc t __initcall_topology_init4

c001d1c0 t __initcall_param_sysfs_init4

。。。。。。。。。。。。。

c001d200 t __initcall_init_pipe_fs5

c001d204 t __initcall_eventpoll_init5

。。。。。。。。。。。。。。

c001d24c t __initcall_init6

c001d250 t __initcall_kallsyms_init6

c001d254 t __initcall_utsname_sysctl_init6

c001d258 t __initcall_init_per_zone_pages_min6

c001d25c t __initcall_pdflush_init6

。。。。。。。。。。

c001d2e8 t __initcall_loop_init6

c001d2ec t __initcall_net_olddevs_init6

c001d2f0 t __initcall_loopback_init6

c001d2f4 t __initcall_init_mtd6

c001d2f8 t __initcall_afs_parser_init6

c001d2fc t __initcall_init_mtdchar6

c001d300 t __initcall_init_mtdblock6

c001d304 t __initcall_init_nftl6

。。。。。。。。。。。。

c001d388 t __initcall_ip_auto_config7

。。。。。。。。。。。

可以看出,这些函数经过系统处理后,

加了前缀__initcall_和后缀的数字,看起来是表示启动的阶段。

也就是加了和函数对应的一个个变量(标示)。

当然,也可以找到函数对应的首地址,比如

变量

c001d1b0 t __initcall_clk_init3

对应的函数clk_init放在c000e624 :

c000e624 t clk_init

然后,调用

init_post()

{

1.打开console:

sys_open("/dev/console", O_RDWR, 0)

2.运行命令:

run_init_process(ramdisk_execute_command);

run_init_process(execute_command);

3.运行系统初始化文件:

run_init_process("/sbin/init");

run_init_process("/etc/init");

run_init_process("/bin/init");

run_init_process("/bin/sh");

}

最后,我们才进入我们熟悉的嵌入式Linux环境,

才能输入用户名和密码(如果有的话),比如:

Welcome to Embedded Linux

(none) login: root

Dec 31 17:00:11 login[704]: root login on ‘ttyS0’

# cd /

。。。

【附录】

关于系统架构中,如何把函数和系统联系起来

注:我这里是arm架构的板子

在archarmkernelsetup.c 的

void __init setup_arch(char **cmdline_p)

{

init_arch_irq = mdesc->init_irq;

system_timer = mdesc->timer;

init_machine = mdesc->init_machine;

}

而mdesc即使machine description,

对应的是你在archarmmach-XXXXXXX_pb.c

中定义的,类似于如下的内容:

MACHINE_START(XXXX, "XXXX PB")

/* Maintainer: Austriamicrosystems Ltd */

.phys_io = XXXX,

.io_pg_offst = XXXX,

.boot_params = XXXX,

.map_io   = XXXX_map_io,

.init_irq = XXXX_init_irq,

.timer   = &XXXX_timer,

.init_machine = XXXX_init,

MACHINE_END

其中XXX代表你的板子(架构)名字。

而XXXX_init就赋值给上面的init_machine了,对应的这些函数放在

archarmmach-XXXcore.c

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值