Linux内核移植:内核的启动过程分析、启动配置与rootfs必要文件

这篇具有很好参考价值的文章主要介绍了Linux内核移植:内核的启动过程分析、启动配置与rootfs必要文件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、启动过程

 内核启动通常包括4个阶段:

  1. iROM代码启动(BIOS启动)。开发板上电后,先执行内部iROM中的固化代码,类似于BIOS,执行通电自检和初始化过程,包括初始化CPU、存储器、时钟、总线等一些必要的硬件资源。
  2. 启动引导加载程序BootLoader。根据启动引脚的电平,读取相应的存储介质上的Uboot到RAM。接着,启动Uboot。U-Boot再根据用户传的参数加载内核、设备树、根文件系统。
  3. 装载内核。Linux内核镜像文件uImage被载入内存后,首先将自身解压,然后进行系统的一系列初始化工作,包括初始化存储器、中断表、必要的设备驱动,设定分页机制、任务调度机制,接着根据bootargs环境变量载入根文件系统。
  4. 系统初始化。根文件系统加载成功后,根据bootargs尝试执行/init命令。如果是RAMDisk,就尝试执行/init命令,否则,就尝试执行/sbin/init、 /etc/init、 /bin/init、 /bin/sh。如果其中任意一个能成功执行,就进人下一阶段,否则,内核启动失败。

二、启动配置

Linux通常有3中系统初始化方式:SysV、systemd、UpStart。

(一)SysV初始化

init是系统的1号进程,可以是可执行脚本,或sysvinit,或者busybox的二进制程序。ramdisk常用可执行程序脚本程序的init,二进制程序常依照/etc/inittab文件执行初始化任务。管理员可以定制/etc/inittab 配置文件来建立所需的系统运行环境。所以,/etc/inittab是rootfs中的重要文件。验证如下:

~$ ls /sbin/init -l
lrwxrwxrwx  1  1000  1000  14 Jan 25  2023 sbin/init -> ../bin/busybox

System V initialization是基于运行级别(Runlevel)来启动系统,用来设置不同环境下所运行的程序和服务。使用运行级别和对应的链接文件(位于etc/rcn.d 目录中,n为运行级别,分别链接到/etc/init.d中的init 脚本)来启动和关闭系统服务。假设当前inittab 中设置的默认运行级别是2,则init 进程会运行/etc/init.d/rc2命令,该命令会依据系统服务的依赖关系遍历执行/etc/rc2.d中的脚本或程序。/etc/rc2.d目录中的文件实际都是指向/etc/init.d/下对应的脚本或程序的软链接。
init 进程根据/etc/inittab中的配置初始化系统,设置系统运行级别及进入各运行级别对应的要执行的命令。inittab 提供了0~6的运行级别选项,runlevels是运行级别列表(如下)。其中,1级(单用户模式)和5级(多用户标准模式)比较常用。系统工作不正常时使用单用户模式维护,工作正常时使用多用户标准模式。在资源受限时(如没有网络环境或没有图形终端)可选择2级。以S开头的表示启动,以K开头的表示停止,并且S或K后面的两位数数字代表了服务的启动顺序,具体由服务依赖关系决定

# Runlevel 0:Halt.
# Runlevel 1:Single-user mode without networking,only for root.
# Runlevel 2:Multi-user mode without networking and daemons.
# Runlevel 3:Multi-user mode with networking.
# Runlevel 4:Not used or user-defined.
# Runlevel 5:Runlevel3+X-window,full functionally.
# Runlevel 6:Reboot.

(二)systemd初始化

新版本的Ubuntu使用systemd来初始化系统,验证如下:

~$ ls /sbin/init -l
lrwxrwxrwx I root root 20 330 00:40 /sbin/init -> /lib/systemd/systemd

systemd最主要的功能包括系统的主机名称、网络设置定、语言处理、文件系统格式及其他系统服务和应用服务的启动等。所有的这些任务都会通过systemd的默认启动目标(/etc/systemd/system/default.target)来配置。
systemd依次执行相应的各项任务来完成系统的最终启动。例如,systemd 首先执行initrd.target所有单元,包括挂载/etc/fstab,最后执行 graphical所需的服务以启动图形界面来让用户以图形界面登录。如果系统的defaulttarget 指向multi-user.target,那么此步骤就不会执行。

三、rootfs中的启动配置文件

1、inittab

基本的ininttab内容如下:

#this is run first except when booting in single-user mode.
::sysinit:/etc/init.d/rcS
# /bin/sh invocations on selected ttys
# start an "askfirst" shell on the console (whatever that may be)
::askfirst:-/bin/sh
# stuff to do when restarting the init process
::restart:/sbin/init
# stuff to do before rebooting
::ctrlaltdel:/sbin/reboot

inittab 文件中的每一项按下面的格式设置:

id: runlevels: action: process

每一项有四个字段,字段之间用冒号隔开。每个字段的含义如下。
(1)起d由1~4个字符组成,作为inittab项的唯一标识。
(2)runlevedls 是运行级别列表。
(3)action指明执行什么动作
(4)process字段包含init执行的进程。
与系统启动相关的文件和目录如下:

|--/etc/
|    |-- inittab	(init脚本)
|    |-- init.d/
|        |-- rc	(启动脚本)
|        |-- rcS	(启动脚本)
|        |-- rc.local(附加启动脚本)
|        |-- ....	(其他系统服务脚本)
|    |--rcS.d/		(S级服务管理目录)
|        |-- ....	(init.d服务脚本链接)
|    |-- rc0.d/		(0级服务管理目录)
|        |-- ....	(init.d服务脚本链接)

2、/etc/init.d/rcS 脚本

   #!/bin/sh
    #
    # rcS           Call all S??* scripts in /etc/rcS.d in
    #               numerical/alphabetical order.
    #
    # Version:      @(#)/etc/init.d/rcS  2.76  19-Apr-1999  miquels@cistron.nl
    #
  
    PATH=/sbin:/bin:/usr/sbin:/usr/bin
    runlevel=S
    prevlevel=N
    umask 022
    export PATH runlevel prevlevel
  
    #    Make sure proc is mounted
    #
    [ -d "/proc/1" ] || mount /proc
  
    #
    #       Source defaults.
    # 设置环境变量
    #./etc/default/rcS
  
    #
    #       Trap CTRL-C &c only in this shell so we can interrupt subprocesses.
    #
    trap ":" INT QUIT TSTP
  
    #
    #   Call all parts in order.
    # 
    # exec /etc/init.d/rc S
    
    /bin/mount -a

不要忘记为 rcS 添加可执行权限:

$ chmod +x init.d/rcS

3、fstab

/etc/init.d/rcS中的mount -a。意思是将/etc/fstab的所有内容重新加载。
/etc/fstab 文件负责配置Linux开机时自动挂载的分区。

  • fstab中的文件挂载操作如下:
      <file system> <mount point> <type> <options> <dump> <pass>
       <file system>:描述要挂载的特殊的块设备或远程文件系统,如/dev/cdrom /dev/sdb等,远程文件系统使用<host>:<dir>.
       <mount point>:描述文件系统的挂载点;如果是一个交换分区(swap partitions),这个域应写为‘none’.
       <type>:描述文件系统的类型,Linux支持许多文件系统类型,如adfs, affs, autofs, coda, coherent, cramfs,devpts, efs, ext2, ext3, hfs, hpfs, iso9660, jfs, minix, msdos, ncpfs, nfs,ntfs, proc, qnx4, reiserfs, romfs, smbfs, sysv, tmpfs, udf, ufs, umsdos,vfat, xenix, xfs,等。
       <options>:描述关于这个文件系统的挂载选项,基本的选项如下:
         default:使用默认选项,rw, suid, dev, exec, auto, nouser, and async
         noauto:当启动时给出“mount -a”命令时并不挂载。
         user:允许用户挂载
         owner:允许设备自己挂载
         comment:供fstab维护程序使用
         nofail:如果这个设备不存在,不报告错误信息
       <dump>:当其值设置为1时将允许dump备份程序备份;设置为0时忽略备份操作;如果文件系统需不需要被dump,则设置为0即可
       <pass>:该字段由fsck程序用于确定在重新启动时文件系统检查完成的顺序,启动用的文件系统需要制定为1,其他文件系统需要指定为2,如果没有此域或设置为0表示不检查。其值是一个顺序。当其值为0时,永远不检查;而 / 根目录分区永远都为1。其它分区从2开始,数字越小越先检查,如果两个分区的数字相同,则同时检查

参考博文: 根文件系统(linuxrc、inittab、fstab)
例1:

#device mount-point type options dump fsck order
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0

例2:

none /dev/pts devpts gid=5,mode=620 0 0
none /proc proc defaults 0 0
nonc /dev/shm tmpfs defaults 0 0
/dev/hda4 swap swap dcfaults o 0
/dev/edrom /mntcdrom iso9660 noauto,owner,kudzu,ro 0 0
/dev/fd0 /mnt/floppy auto noauto,owner,kudzu 0 0
/dev/hdal /mnt/c vfat exec,dev,suid,rw,umask=0, iocharset=gb2312,codepage=936 0 0

例3:fstab中添加了mount nfs的配置:

192.168.1.7:/CBT-SuperIOT/ /mnt/nfs/ nfs nolock 0 0

4、profile 文件

#!/bin/sh
export HOSTNAME=farsight
export USER=root
export HOME=root
export PS1="[$USER@$HOSTNAME \W]\# "
PATH=/bin:/sbin:/usr/bin:/usr/sbin
LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
export PATH LD_LIBRARY_PATH

5、其他文件

service,inetd.conf,passwd文件,可以配置telnet服务器的配置和开启:
确保fstab 文件中存在none /dev/pts devpts mode=0622 0 0这一行
确保services文件中存在 telnet 23/tcp这一行
确保 inetd.conf中存在telnet stream tcp nowait root /sbin/telnetd telnetd
确保passwd 文件中存在 root::0:0:root:/:/bin/sh ,表示没有密码的root 帐号文章来源地址https://www.toymoban.com/news/detail-548740.html

到了这里,关于Linux内核移植:内核的启动过程分析、启动配置与rootfs必要文件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 嵌入式开发之linux内核移植

    目录  前言 一、下载内核源码 1.1 下载linux-3.0.1 1.2 解压源码文件 二、 内核添加yaffs2文件系统支持 2.1 下载yaffs2 2.2 内核添加yaffs2文件补丁 三、配置开发板 3.1 修改机器ID 3.2 添加开发板初始化文件 3.3 配置NandFalsh 3.3.1 添加NandFlash设备 3.3.2 添加NandFlash驱动 3.3 修改Kconfig(支持

    2024年02月07日
    浏览(103)
  • 新唐NUC980使用记录(5.10.y内核):u-boot & linux & rootfs 编译与烧录测试(基于SD1位置SD卡)

    从去年(2022)开始新塘官方的NUC980 5.10.y内核的项目开始展开,这篇文章将测试在NUC980上使用5.10.y内核。 这篇文章中内容均在下面的开发板上进行测试: 《新唐NUC980使用记录:自制开发板(基于NUC980DK61YC)》 对于NUC980芯片本身的一些内容可以参考: 《新唐NUC980使用记录:基

    2024年02月03日
    浏览(66)
  • 分享一种快速移植OpenHarmony Linux内核的方法

    本文面向希望将 OpenHarmony 移植到三方芯片平台硬件的开发者,介绍一种借助三方芯片平台自带 Linux 内核的现有能力,快速移植 OpenHarmony 到三方芯片平台的方法。 内核态层和用户态层 为了更好的解释整个内核移植,首先需要介绍一些概念: 我们可以把 OpenHarmony 简单的分为

    2024年04月26日
    浏览(51)
  • 嵌入式Linux底层系统开发 +系统移植+内核文件系统(基础)

    搭建交叉编译开发环境 bootloader的选择和移植 kernel的配置、编译、移植和调试 根文件系统的制作 前两个要点通常芯片厂家提供。后边两个要点是公司的工作重点。 学习方法:先整体后局部,层层推进 如何编译—如何添加命令和功能—如何定义自己的开发板。 移植的基本步

    2024年02月03日
    浏览(71)
  • uboot 启动内核代码分析

    uboot的本质就是一个复杂点的裸机程序。内核本身也是一个\\\"裸机程序“,和uboot、和其他裸机程序并没有本质区别。 区别就是操作系统运行起来后在软件上分为内核层和应用层,分层后两层的权限不同,在内存访问和设备操作的管理上更加精细(内核可以随便访问各种硬件,

    2024年02月11日
    浏览(60)
  • (三)内核移植--从零开始自制linux掌上电脑(F1C200S)<嵌入式项目>

    目录 一、bootloader、kernel、rootfs联系 二、内核移植 1. 内核源码获取 2. 内核配置与编译 🍍 基础配置与编译 🍍 TF卡分区 🍍 内核烧录 三、参考内容 kernel可以理解为一个 庞大的裸机程序 ,和uboot以及其他比如点灯类似的裸机程序没有本质区别,只是kernel分为 用户态和内核态

    2024年02月15日
    浏览(84)
  • i.MX6ULL移植NXP官方Linux内核imx_5.4.47_2.2.0

    系统:Ubuntu18.04 参考资料:百问网 IMX6ULL开发板(从零移植篇-预览版)-V0.1,正点原子驱动开发指南 开发板:100ask i.MX6ULL PRO 交叉编译工具链的获取就不写了 打开 .bashrc 文件。 vi ~/.bashrc 。在该文件最后面添加如下(根据自己的交叉编译工具链) (1)直接从官网下载,非常慢而

    2024年02月12日
    浏览(62)
  • Linux 内核线程启动以及内核调用应用层程序

    #include linux/kthread.h //内核线程头文件   static task_struct *test_task; test_task = kthread_run(thread_function, NULL, \\\"test_thread_name\\\"); if(IS_ERR(test_task)) {         pr_err(\\\"test_thread_name create failn\\\"); } static int thread_function(void *arg) {     char *envp[3];     char *argv[3];     int ret= 0;     argv[0] = \\\"/bin/sh\\\";  

    2024年02月12日
    浏览(57)
  • 【Linux内核解析-linux-5.14.10-内核源码注释】内核启动kernel_init解释

    static int __ref kernel_init(void *unused) : 声明一个静态整型函数 kernel_init() ,该函数不会被其他文件访问,使用 __ref 标记表示该函数是可重定位的,并且该函数不需要任何参数。 wait_for_completion(kthreadd_done); : 等待 kthreadd 线程完成初始化, wait_for_completion() 函数会阻塞当前进程,直到

    2024年02月02日
    浏览(70)
  • Linux 内核模块加载过程之重定位

    1.1.1 struct load_info info 加载模块只需要读入模块的二进制代码即可,然后执行init_module系统调用。 我们先介绍下struct load_info info结构体。 struct load_info 是一个用于加载模块时存储相关信息的数据结构。 该结构体包含以下成员: name:模块的名称,以字符串形式存储。 mod:指向

    2024年02月10日
    浏览(138)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包