linux如何初始化根文件系统,Linux在启动时利用NFS方式挂在根文件系统时没法初始化console的问题...

前几天在FriendlyARM的 mini2440板子上跑Linux的时候碰到了一个很费解的现象,按照教程上说,是能够利用NFS的方式来挂载Host开发机上的根目录来开发的。教程中给的kernel_cmd_line 是:linux

param set linux_cmd_line "console=ttySAC0 root=/dev/nfs nfsroot=192.168.1.111:/opt/FriendlyARM/mini2440/root_qtopia ip=192.168.1.70:192.168.1.111:192.168.1.111:255.255.255.0:sbc2440.arm9.net:eth0:off"windows

后面很长的部分主要是ip地址设置和nfs的目录,这里首先碰到的问题是它写了console=ttySAC0。这个不是很理解为何,ttySAC0不是应该是windows上的超级终端么,我是在Fedora13下面用minicom链接的,系统里面显示的设备名字是/dev/ttyUSB0。可是奇怪的是这个参数是对的,我改为ttyUSB0以后反而启动的时候就收不到串口的数据了。函数

以后就是正常启动,而后到VFS mount以后忽然说 unable to initial console之类的,而后串口就失去控制了,可是板子上的系统仍是能够正常启动,并且起来以后我尝试着打开终端而后往串口发送数据竟然成功了。也就是说通讯驱动之类的问题应该都是好的,只是设备文件名弄的不太对之类的问题。手动创建个这个设备应该就能够了。网上找到有人说在/dev下面 mknod –m 600 console c 5 1就能够了,我原本以为是不行的,结果死马当活马医的试了试竟然行了,我以为很奇怪。按照个人理解,虽然我在host上面在mknod了这个设备,可是系统启动的时候会从新挂载一个/dev文件系统在/dev下面啊,应该会有个脚本执行了相似于mount –t /dev 之类的命令,那么原来的建立的文件不是应该就看不见了么?不理解是为何。this

我仍是想知道这个设备启动的过程当中在什么时候由哪一个函数建立的。查了些资料以及内核的代码,大概有如下的理解:spa

首先真正意义上的Linux开始启动是在bootloader将系统的控制权交给Linux Kernel的时候开始的,也就是在start_kernel()这个函数中。这个函数定义在init/main.c里。而后你会发如今这个函数干了一大堆初始化的事情,其中有一个函数叫作console_init(),.net

/*

* HACK ALERT! This is early. We're enabling the console before

* we've done PCI setups etc, and console_init() must be aware of

* this. But we do want output early, in case something goes wrong.

*/

console_init();

if (panic_later)

panic(panic_later, panic_param);线程

这应该是个对咱们有用的函数,就像注释里面说的,This is early,咱们先记着这回子事,等一下子再说它,先日后看。rest

正常人都知道start_kernel()这个函数若是返回了的话致使的惟一结果一定是系统会挂掉,因此它必定会在哪一个函数中一直跑下去。而后看来看去发现最后一个函数:rest_init() 函数貌似比较像,教程

/* Do the rest non-__init'ed, we're now alive */

rest_init();ip

人家注释里面也写着呢,we’re now alive,看来应该是进到这个里面去了,看看这个函数:

static noinline void __init_refok rest_init(void)

__releases(kernel_lock)

{

int pid;

rcu_scheduler_starting();

/*

* We need to spawn init first so that it obtains pid 1, however

* the init task will end up wanting to create kthreads, which, if

* we schedule it before we create kthreadd, will OOPS.

*/

kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);

numa_default_policy();

pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);

rcu_read_lock();

kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);

rcu_read_unlock();

complete(&kthreadd_done);

unlock_kernel();

/*

* The boot idle thread must execute schedule()

* at least once to get things moving:

*/

init_idle_bootup_task(current);

preempt_enable_no_resched();

schedule();

preempt_disable();

/* Call into cpu_idle with preempt disabled */

cpu_idle();

}

我看到这个函数先注意它的最后,这丫调用了cpu_idle(),那说明开始死循环了。果真前面调用了schedule()开启了调度器,开始任务调度。看到这里内心就踏实了,事儿确定是在这个以前干的,这以后没东西了。因而咱们往前看,发现它在这里开始分支了。用的是kernel_thread(),产生两个内核线程,一个是kernel_init(),一个是kthreadd,内核线程的守护线程。咱们关注的事情确定是在kernel_init()里面,再往下找到kernel_init()函数,发现了使人惊喜的东西:

/* Open the /dev/console on the rootfs, this should never fail */

if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)

printk(KERN_WARNING "Warning: unable to open an initial console./n");

咱们发现红的那一句就是咱们见到的提示信息,而后看了一下大概意思应该是说,若是在这个时候可以成功打开/dev/console这个文件,就没事,不然就有那个提示。也就是说到这一刻,应该已经有/dev/console这个设备建立好了,因此我要关注的必定是在这前面的某个地方。

未完待续,仍是没找到究竟是哪里建立的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux内核的文件系统初始化是系统启动过程中的一个重要步骤,它负责加载文件系统载为系统的目录。 在启动过程中,BIOS或UEFI首先加载引导加载程序(bootloader),如GRUB或Syslinux等。引导加载程序会加载内核映像(vmlinuz)到内存,并将控制权转交给内核。 内核启动后,它会执行一系列初始化操作,其中包括文件系统初始化文件系统通常存储在硬盘或闪存设备上,可以是ext4、XFS、Btrfs文件系统格式。 文件系统初始化的过程主要包括以下几个步骤: 1. 设备初始化:内核会初始化硬件设备,如磁盘控制器、网络接口等,以便后续能够访问文件系统所在的设备。 2. 文件系统驱动加载:内核会加载相应的文件系统驱动模块,以支持对特定文件系统格式的读写操作。 3. 设备载:内核会据引导参数或配置文件指定的设备信息(如硬盘分区、NFS共享等),找到文件系统所在的设备,并将其载为系统的目录(/)。 4. 初始化进程:一旦文件系统成功载,内核会运行用户空间的第一个进程,通常是init或systemd。这个进程负责启动其他用户空间进程和服务。 总而言之,文件系统初始化Linux系统启动过程中的一个关键步骤,它负责加载和文件系统,并启动用户空间的初始化进程,从而完成系统的初始化工作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值