`
jandroid
  • 浏览: 1899174 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Linux Kernel 2:用户空间的初始化

 
阅读更多
上篇我们知道,kernel初始化后将启动init进程,那么这个进程将干些什么呢?除此之外,kernel还需要做些什么事情呢?(想想文件系统、根存储设备是在什么时候初始化的呢?)
先从文件系统初始化说起。以前一直不明白,有了kernel为何还需要一个文件系统?经过反复琢磨,明白一个道理,kernel加载到内存后,kernel运行起来是没有问题的,但是如果没有Root FS,就好像PC上没有硬盘.....。另外,Linux中很多虚拟文件系统(proc,sys,dev等)都是挂靠在RootFS中的,所以RootFS在Linux中更加关键(必要条件简直就是)。(kernel中的FS是另外一个庞大的部分)
一 根文件系统
1 FHS:File system Hierachy Standard:Linux上文件系统布局的标准,例如 usr目录大概是干吗的,tmp目录大概是干嘛的。有空可以瞧瞧....其实使用LINUX OS多了,自然就理解了。
2 常用的文件夹布局:其实就是ES上普遍的文件目录:
  • bin;dev;etc;home;lib;sbin;tmp;usr;var;
二 Post Boot
这里讲的是execve init之前的事情,因为源码中:
  • run_init_process("/usr/bin/init"):这个时候已经有FS的布局了,也就是init程序本身必须放在一个FS中。
三 init
init进程很重要,不过android上的init进程的工作流程比较简单。这里介绍非Android上的init。一般它读取的配置文件是/etc/inittab中(ubuntu上似乎没有这个文件了,以后得找个FCore的系统看看)。
另外,这里还有一个叫run level的概念。见图1.

图1 run level
Run level说白了就是将系统运行状态分成几个级别,例如shutdown的时候init需要执行一些操作,reboot的时候需要执行一些操作。
这里关于Init的东西就不介绍了,很多关于linux系统配置的知识都有涉及。(确实比android的init要复杂多了)
四 Initial RAM Disk
LK在早期初始化的过程中,需要mount一个FS,目前有新旧两种方法:
  • old方法就是使用initial ram disk,也叫initrd
  • new方法就是使用iniramfs
这两个东西非常常见,咱们要好好研究下。
4.1 initrd
这个功能需要配置kernel的编译选项。
ARM支持将前面的initrd和vmlinux打包到一个image中。实际上只有ARM架构支持。(内核编译的时候要选择这一项)。讲了这么多,那么到底怎么用呢?
  • initrd也是一个image。由bootloader启动的时候,或者bootloader下载到某个地方
  • bootloader把initrd的地址告诉内核。内核启动时候把这个image解压并挂载
  • 另外一种办法,编译的时候将initrd和kernel放到一个image中,这种方法只有ARM架构支持。使用这种办法话,建议用initramfs。注意,android中使用的就是一个kernel+initramfs的单一image。也就是第二种办法
(这里有很多细节问题,以后我们分析源码再来搞懂它)
BL启动内核的时候,需要给LK传递参数,即告诉LK这个initrd在什么位置...很简单不是?
KL如何使用这个initrd呢?
  • KL先根据参数指定的initrd地址,将这个image拷贝到内存中,然后解压,并挂载为/
  • 找到这个disk中的linuxrc文件,然后执行里边的语句《====这给了我们定制化自己ES的好计划
  • 处理完linuxrc后,KL unmount这个initrd,并加载真正的root device(看到没,这个initrd就是做些初始化的工作,但是你也可以不umount这个initrd。)这里的处理稍有差异。如果BL在参数中指明root=/dev/ram0,(代码中可见到这些语句),那么KL就不会执行linuxrc,并且也不会umount initrd。也就是这个initrd就是最终的根文件系统了。
那么如何制作这个Initrd呢?
其实就是一个gzip打包的文件夹....
(这部分代码在do_mounts.c中的prepare_namespace函数中)
4.2 initramfs
(详细说明:参考kernel/documentations/filesystems/ramfs-rootfs-initramfs.txt)
kernel默认支持这个initramfs,所以编译的时候,会整一个default的initramfs放到内核中。initramfs是一个cpio的打包文件。我特意查了下cpio的info。一般用法就是:读取一个目录下所有文件的信息及其所有文件的内容(可能是直接read数据到一个buffer中),然后把这些信息写到一个文件中。说白了,可能就是一个序列化的工具。然后LK用同样的方法就可以反序列化,恢复原来目录中的内容了。
前面说,LK编译的时候默认会有一个简单的initramfs目录结构。这个结构由kernel/scripts/gen_initramfs_list.sh脚本生成。这个脚本很简单:

dir /dev 0755 0 0
nod /dev/console/ 0600 0 0 c 5 1
dir /root 0700 0 0

执行的时候,前面加上mk...就生成一个目录了,然后用cpio打包,生成iniramfs,最后由LK解包并挂载
(具体内容,参考ramfs-rootfs-initramfs.txt)
如何制作自己的initramfs呢?
  • 搞一个文件夹吧,可仿照PC机器上linux的文件结构。也可以把busybox放上去。
  • findtestramfs -depth -print | cpio -ov > testramfs.cpio cpio的输入是文件名,输出通过>定向到testramfs.cpio。大家可以试试。
  • 解压的话,cpio -ivd < testramfs.cpio。这样就能还原testramfs文件夹中的内容了。
cpio:-o表示output,-v表示打印一些verbose信息,-i表示input,-d表示建立整个文件夹结构。没有-d的话,会出问题。
不过有了kernel编译的支持,我们不用自己调用cpio了,在编译选项中有一个INITRAMFS_SOURCE,把它指向目标文件夹,编译的时候自然会生成这个initramfs了。
参考文献:
这些参考文献中,最重要的是最后一个,ols2k-9.ps,下载并处理后得到一个pdf,实际上一篇论文。主要介绍了
Linux启动的一些问题。
再三解释一下,为什么需要init ram disk。FS一般安装在存储介质上,而读取这些存储介质需要驱动。内核启动的时候如果把这些驱动都加载的话,会非常麻烦,即使你把驱动静态编译到内核中,也不是一个完美的解决办法。所以。先整一个简单的,基于内存的FS,这样初始化工作都可以顺利进行。最后,等驱动都加载完后,再把实际存储上的FS挂载上来。这里要明白一点,没有一个FS的话,LK是没法正常工作的。
五 U-Boot
全名为Das U-Boot,是一个使用非常广泛的Bootloader。以后会专门撰文介绍UB。这里简单说两个点:
  • UB的代码结构,先从CPU的start.S开始,这里会根据不同的CPU进行初始化,大部分代码都不需要我们修改
  • 再是Board的启动,这个和具体的板子有关。现在改名叫lowlevel_init.S了。
(最难的部分在于各个设备的初始化了,需要结合开发板的datasheet来做)
这里列出以下参考书:

其中,关于SDRAM.pdf,网址已经移到了:http://www.maxwell.com/products/microelectronics/docs/INTRO_TO_SDRAM.PDF
各位看官可以下载看看。

分享到:
评论

相关推荐

    Understanding the Linux Kernel

     初始化中断描述符表  异常处理  中断处理  软中断及tasklet  工作队列  从中断和异常返回  第五章内核同步  内核如何为不同的请求提供服务  同步原语  对内核数据结构的同步访问  避免竞争条件的实例  ...

    基于exec函数族分析Linux初始化进程运行环境的过程

    本文结合Understanding Linux Kernel英文版第三版以及Linux2.6.11源代码详细分析了Linux exec函数族调用时内核对于进程切换所完成的一系列关于进程运行环境的初始化的过程。

    understanding linux network internals

    Kernel Infrastructure for Component Initialization 组件初始化的底层内核(实现) Section 7.1. Boot-Time Kernel Options 内核启动选项 Section 7.2. Module Initialization Code 模块初始化 Section 7.3. ...

    drivers_实验资料\kernel课程\内核课程.chm

    包括main.c、创建早期用户空间的代码以及其他初始化代码。 Kernel:内核中最核心的部分,包括进程的调度(kernel/sched.c),以及进程的创建和撤销(kernel/fork.c和kernel/exit.c)等,和平台相关的另外一部分核心的...

    ARM_Linux启动分析.pdf

    “head.S”文件提供了对 OSF PAL/1的调用入口,它将被编译后置于引导扇区(ARC的分区首扇区或SRM的磁盘0扇区),得到控制后初始化一些数据结构,再将控制转给“main.c”中的start_kernel(), start_kernel()向控制台...

    精通LINUX设备驱动程序开发

    目 录 第1章 引言 1 1.1 演进 1 1.2 gnu copyleft 2 1.3 kernel.org 2 1.4 邮件列表和论坛 3 1.5 linux发行版 3 1.6 查看源代码 4 1.7 编译内核 7 1.8 可加载的模块 8 1.9 整装待发 9 第2章 内核 11 2.1...

    《精通Linux 设备驱动程序开发》.(Sreekrishnan).pdf

    5.2.1 驱动程序初始化83 5.2.2 打开与释放86 5.2.3 数据交换88 5.2.4 查找92 5.2.5 控制94 5.3 检测数据可用性95 5.3.1 轮询95 5.3.2 fasync98 5.4 和并行端口交互99 5.5 rtc子系统108 5.6 伪...

    Bootloader详解(源码+实验)研究BOOT必读

     硬件设备初始化;  拷贝Boot Loader 的程序到RAM 空间中;  设置好堆栈;  跳转到阶段2 的C 入口点。 (2)、Boot Loader 的阶段2 通常主要包括以下步骤:  初始化本阶段要使用到的硬件设备;  系统...

    深入分析Linux内核源码

    6.2 Linux内存管理的初始化 6.2.1 启用分页机制 6.2.2 物理内存的探测 6.2.3 物理内存的描述 6.2.4 页面管理机制的初步建立 6.2.5页表的建立 6.2.6内存管理区 6.3 内存的分配和回收 6.3.1 伙伴算法 6.3.2 ...

    嵌入式设计及linux驱动开发指南——基于ARM9处理器.pdf

    9.8.1 OHCI驱动初始化 9.8.2 与USBD连接 9.8.3 OHCI根HUB 9.9 扫描仪设备驱动程序 9.9.1 USBD接口 9.9.2 文件系统接口 9.10 USB主机驱动在S3C2410X平台的实现 9.10.1 USB主机控制器简介 9.10.2 驱动程序的...

    linux内核 0.11版本源码 带中文注释

    // 字符设备初始化(kernel/chr_drv/tty_io.c, 347 行) extern void hd_init (void); // 硬盘初始化程序(kernel/blk_drv/hd.c, 343 行) extern void floppy_init (void); // 软驱初始化程序(kernel/blk_drv/...

    C_KernelTap:在内核空间实现UDP Socket和TAP Tunnel

    内核初始化/退出函数。 系统调用 在内核空间中重写一些系统调用。 ktap.c 在内核空间中创建和使用 tap 隧道。 ktx.c 隧道 tx 部分(udp 或 netpoll)。 ktunnel.h linux heraders、定义的值、宏、类型/函数...

    u-boot移植实验

    1 阶段1,汇编代码,对于s3c2410是cpu/arm920t/start.s文件...当用户输入启动linux的命令的时候,u-boot会将 kernel 映像(zImage)和从 nand flash 上读到 RAM 空间中,为内核设置启动参数,调用内核,从而启动linux。

    Linux操作系统基础教程

    据我所知,大多数的 Linux 发行版本(Linux distribution)和核心(Kernel)都是可以 从网上下载的,但是我不推荐易用这种方法得到 Linux,因为仅仅核心就有几十个 Mbit 的 数据量,而一个完整的发行版本大概都是 1...

    基于Linux 的防火墙技术研究

    (2) 设置初始规则/sbin/ipchains-Ainput-jACCEPT/sbin/ip chains-Aoutput-jACCEPT/sbin/ipchains-AforwardjACCEPT (3) 设置本地...

    1-oracle傻瓜手册(自己修订版)

    2 初始化文件配置 15 2.1 Oracle 8 & 8i 15 2.2 Oracle 9i 17 3 工具 18 3.1 sqlldr 18 3.2 exp 19 3.3 imp 20 3.4 sqlplus 21 3.4.1 命令行参数 21 3.4.2 提示符命令 21 3.4.3 SET选项 22 3.4.4 例子 22 4 备份及...

    嵌入式Linux系统移植步步通

    2.2 Linux下工作用户及环境....................................................................................................9 2.2.1 交叉工具的安装........................................................

    ARM-Linux系统移植

    2.2 Linux下工作用户及环境....................................................................................................9 2.2.1 交叉工具的安装......................................................

Global site tag (gtag.js) - Google Analytics