精华内容
下载资源
问答
  • Uboot启动内核和根文件系统命令分析

    千次阅读 2021-08-26 19:35:43
    uboot有两种启动 Linux 内核和rootfs的方法,一种是直接从flash(nand或emmc)启动,一种是从网络...这些命令一般都是用来启动 Linux 内核的,比如读取 EMMC 或者 NAND Flash 中的 Linux 内核镜像文件和设备树文件到 DRAM

      uboot有两种启动 Linux 内核和rootfs的方法,一种是直接从flash(nand或emmc)启动,一种是从网络启动。这里面用到了两个非常重要的环境变量bootcmd 和 bootargs。

    一、bootcmd 和 bootargs 环境变量

      bootcmd 保存着 uboot 默认命令, uboot 倒计时结束以后就会执行 bootcmd 中的命令。这些命令一般都是用来启动 Linux 内核的,比如读取 EMMC 或者 NAND Flash 中的 Linux 内核镜像文件和设备树文件到 DRAM 中,然后启动 Linux 内核。可以在 uboot 启动以后进入命令行设置 bootcmd 环境变量的值。如果 EMMC 或者 NAND 中没有保存 bootcmd 的值,那么 uboot 就会使用默认的值。
      bootargs 保存着 uboot 传递给 Linux 内核的参数。bootargs 就是设置了很多的参数的值,这些参数 Linux 内核会使用到,常用的参数有:

    1、 console

      console 用来设置 linux 终端(或者叫控制台),也就是通过什么设备来和 Linux 进行交互,是串口还是 LCD 屏幕?如果是串口的话应该是串口几等等。一般设置串口作为 Linux 终端,这样我们就可以在电脑上通过 SecureCRT 来和 linux 交互了。

    2、 root

      root 用来设置根文件系统的位置,例如 root=/dev/mmcblk1p2 用于指明根文件系统存放在mmcblk1 设备的分区 2 中。root 后面有“rootwait rw”,rootwait 表示等待 mmc 设备初始化完成以后再挂载,否则的话mmc 设备还没初始化完成就挂载根文件系统会出错的。 rw 表示根文件系统是可以读写的,不加rw 的话可能无法在根文件系统中进行写操作,只能进行读操作。

    3、 rootfstype

      此选项一般配置 root 一起使用, rootfstype 用于指定根文件系统类型,如果根文件系统为ext 格式的话此选项无所谓。如果根文件系统是 yaffs、 jffs 或 ubifs 的话就需要设置此选项,指定根文件系统的类型。

    二、从 EMMC 启动 Linux 系统

      从 EMMC 启动也就是将编译出来的 Linux 镜像文件 zImage 和设备树文件保存在 EMMC中, uboot 从 EMMC 中读取这两个文件并启动,设置 bootargs 和 bootcmd这两个环境变量

    setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
    setenv bootcmd 'mmc dev 1; fatload mmc 1:1 80800000 zImage; fatload mmc 1:1 83000000 Test.dtb; bootz 80800000 - 83000000;'
    saveenv
    boot
    

      首先两个命令setenv 和 saveenv,命令 setenv 用于设置或者修改环境变量的值。命令 saveenv 用于保存修改后的环境变量。另一个boot 命令是用来启动 Linux 系统的。
      uboot传给linux内核的参数保存在bootargs环境变量中,保存了linux 终端是什么和根文件系统的位置。
    uboot的命令:

    setenv bootcmd 'mmc dev 1; fatload mmc 1:1 80800000 zImage; fatload mmc 1:1 83000000 Test.dtb; bootz 80800000 - 83000000;'
    

      用到的命令有:

    1、mmc dev 命令

      mmc dev 命令用于切换当前 MMC 设备,命令格式如下:
      mmc dev [dev] [part]
      [dev]用来设置要切换的 MMC 设备号, [part]是分区号。如果不写分区号的话默认为分区 0。
      使用如下命令切换到 MMC 1:
      mmc dev 1 //切换到 MMC 1

    2、fatload 命令

      fatload 命令用于将指定的文件读取到 DRAM 中,命令格式如下:
      fatload [<dev[:part]> [ [ [bytes [pos]]]]]
      interface 为接口,比如 mmc, dev 是设备号, part 是分区, addr 是保存在 DRAM 中的起始地址, filename 是要读取的文件名字。 bytes 表示读取多少字节的数据,如果 bytes 为 0 或者省略的话表示读取整个文件。 pos 是要读的文件相对于文件首地址的偏移,如果为 0 或者省略的话表示从文件首地址开始读取。我们将 EMMC 分区 1 中的 zImage 文件读取到 DRAM 中的0X80800000 地址处,命令如下:
      fatload mmc 1:1 80800000 zImage

    3、bootz 命令

      要启动 Linux,需要先将 Linux 镜像文件拷贝到 DRAM 中,如果使用到设备树的话也需要将设备树拷贝到 DRAM 中。可以从 EMMC 或者 NAND 等存储设备中将 Linux 镜像和设备树文件拷贝到 DRAM,也可以通过 nfs 或者 tftp 将 Linux 镜像文件和设备树文件下载到 DRAM 中。不管用那种方法,只要能将 Linux 镜像和设备树文件存到 DRAM 中就行,然后使用 bootz 命令来启动, bootz 命令用于启动 zImage 镜像文件, bootz 命令格式如下:
      bootz [addr [initrd[:size]] [fdt]]
      命令 bootz 有三个参数, addr 是 Linux 镜像文件在 DRAM 中的位置, initrd 是 initrd 文件在DRAM 中的地址,如果不使用 initrd 的话使用‘-’代替即可, fdt 就是设备树文件在 DRAM 中的地址。

    三、从网络启动 Linux 系统

      从网络启动 linux 系统的目的就是为了调试。也就是将 linux 镜像文件和根文件系统都放到 Ubuntu 下某个指定的文件夹中,这样每次重新编译 linux 内核或者某个 linux 驱动以后只需要使用 cp 命令将其拷贝到这个指定的文件夹中即可。我们可以通过 tftp 从 Ubuntu 中下载 zImage 和设备树文件,根文件系统的话可以通过 nfs 挂载。

    setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.1.250:/home/nfs/rootfs,proto=tcp rw ip=192.168.1.251:192.168.1.250:192.168.1.1:255.255.255.0::eth0:off' //设置 bootargs
    setenv bootcmd 'tftp 80800000 zImage; tftp 83000000 Test.dtb; bootz 80800000 - 83000000'
    saveenv
    boot
    

    1、NFS挂在rootfs

      uboot 里面的 bootargs 环境变量会设置“root”的值,所以我们将 root 的值改为 NFS 挂载。格式如下:

    root=/dev/nfs nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>] ip=<client-ip>:<server-ip>:<gwip>:<netmask>:<hostname>:<device>:<autoconf>:<dns0-ip>:<dns1-ip>
    

      < server-ip>:服务器 IP 地址,也就是存放根文件系统主机的 IP 地址,那就是 Ubuntu 的 IP地址,比如我的 Ubuntu 主机 IP 地址为192.168.1.250。
      < root-dir>: 根文件系统的存放路径,比如我的就是/home/nfs/rootfs。
      < nfs-options>: NFS 的其他可选选项,一般不设置。
      < client-ip>: 客户端 IP 地址,也就是我们开发板的 IP 地址, Linux 内核启动以后就会使用此 IP 地址来配置开发板。此地址一定要和 Ubuntu 主机在同一个网段内,并且没有被其他的设备使用,在 Ubuntu 中使用 ping 命令 ping 一下就知道要设置的 IP 地址有没有被使用,如果不能ping 通就说明没有被使用,那么就可以设置为开发板的 IP 地址,比如我就可以设192.168.1.251。
      < server-ip>: 服务器 IP 地址,前面已经说了。
      < gw-ip>: 网关地址,我的就是 192.168.1.1。
      < netmask>:子网掩码,我的就是 255.255.255.0。
      < hostname>:客户机的名字,一般不设置,此值可以空着。
      < device>: 设备名,也就是网卡名,一般是 eth0, eth1….
      < autoconf>: 自动配置,一般不使用,所以设置为 off。
      < dns0-ip>: DNS0 服务器 IP 地址,不使用。
      < dns1-ip>: DNS1 服务器 IP 地址,不使用。
      另外:“proto=tcp”表示使用 TCP 协议,“rw”表示 nfs 挂载的根文件系统为可读可写。

    2、网络下载镜像文件 zImage 和设备树文件

      从网络下载可以使用tftp 命令或 nfs 命令

    1、tftp 命令

      tftp 命令是用于通过网络下载东西到 DRAM 中,tftp 命令使用的 TFTP 协议。uboot 中的 tftp 命令格式如下:

    tftpboot [loadAddress] [[hostIPaddr:]bootfilename]
    

      loadAddress 是 文 件 在 DRAM 中 的存 放 地 址 ,
    [[hostIPaddr:]bootfilename]是要从 Ubuntu 中下载的文件。但是 tftp 命令不需要输入文件在 Ubuntu 中的完整路径,只需要输入文件名即可。比如我们现在将 tftpboot 文件夹里面的 zImage 文件下载到开发板 DRAM 的 0X80800000 地址处,命令如下:
      tftp 80800000 zImage

    2、nfs 命令

      nfs(Network File System)网络文件系统,通过 nfs 可以在计算机之间通过网络来分享资源,比如我们将 linux 镜像和设备树文件放到 Ubuntu 中,然后在 uboot 中使用 nfs 命令将 Ubuntu 中的 linux 镜像和设备树下载到开发板的 DRAM 中。这样做的目的是为了方便调试 linux 镜像和设备树,也就是网络调试,通过网络调试是 Linux 开发中最常用的调试方法。原因是嵌入式 linux开发不像单片机开发,可以直接通过 JLINK 或 STLink 等仿真器将代码直接烧写到单片机内部的 flash 中,嵌入式 Linux 通常是烧写到 EMMC、 NAND Flash、 SPI Flash 等外置 flash 中,但是嵌入式 Linux 开发也没有 MDK, IAR 这样的 IDE,更没有烧写算法,因此不可能通过点击一个“download”按钮就将固件烧写到外部 flash 中。虽然半导体厂商一般都会提供一个烧写固件的软件,但是这个软件使用起来比较复杂,这个烧写软件一般用于量产的。其远没有 MDK、 IAR的一键下载方便,在 Linux 内核调试阶段,如果用这个烧写软件的话将会非常浪费时间,而这个时候网络调试的优势就显现出来了,可以通过网络将编译好的 linux 镜像和设备树文件下载到 DRAM 中,然后就可以直接运行。
      我们一般使用 uboot 中的 nfs 命令将 Ubuntu 中的文件下载到开发板的 DRAM 中,在使用之前需要开启 Ubuntu 主机的 NFS 服务,并且要新建一个 NFS 使用的目录,以后所有要通过NFS 访问的文件都需要放到这个 NFS 目录中。uboot 中的 nfs 命令格式如下所示:

    nfs [loadAddress] [[hostIPaddr:]bootfilename]
    

      loadAddress 是要保存的 DRAM 地址, [[hostIPaddr:]bootfilename]是要下载的文件地址。
      例如:使用 nfs 命令来将 zImage 下载到开发板 DRAM 的 0X80800000 地址处,命令如下:
      nfs 80800000 192.168.1.253:/home/nfs/zImage

    展开全文
  • linux内核启动后,会对根文件系统进行加载,但是内核是在哪里对根文件进行加载的? ``` List of all partitions: 1f00 256 mtdblock0 (driver?) 1f01 64 mtdblock1 (driver?) 1f02 6272 mtdblock2 (driver?) 1f03...
  • Linux内核启动及根文件系统加载过程

    万次阅读 多人点赞 2014-05-25 14:12:13
    检测机器码类型是在汇编子函数__lookup_machine_type (同样在文件head-common.S实现) 中完成的。与__lookup_processor_type类似,通过代码:“bl __lookup_machine_type”来实现对它的调 用。该函数返回时,会将...

    上接博文u-boot之u-boot-2009.11启动过程分析

    Linux内核启动及文件系统加载过程

    u-boot开始执行bootcmd命令,就进入Linux内核启动阶段,与u-boot类似,普通Linux内核的启动过程也可以分为两个阶段,但针对压缩了的内核如uImage就要包括内核自解压过程了。本文以linux-2.6.37版源码为例分三个阶段来描述内核启动全过程。第一阶段为内核自解压过程,第二阶段主要工作是设置ARM处理器工作模式、使能MMU、设置一级页表等,而第三阶段则主要为C代码,包括内核初始化的全部工作,下面是详细介绍。

    /******************************************************************************************************************************************/

     原创作品,转载时请务必以超链接形式标明文章原始出处:http://blog.csdn.net/gqb_driver/article/details/26954425,作者:gqb666  
    /******************************************************************************************************************************************/

    一、Linux内核自解压过程

    linux内核启动过程中一般能看到图1内核自解压界面,本小节本文重点讨论内核的自解压过程。

                    

                                         图1 解压内核

    内核压缩和解压缩代码都在目录kernel/arch/arm/boot/compressed,编译完成后将产生head.o、misc.o、piggy.gzip.o、vmlinux、decompress.o这几个文件,head.o是内核的头部文件,负责初始设置;misc.o将主要负责内核的解压工作,它在head.o之后;piggy.gzip.o是一个中间文件,其实是一个压缩的内核(kernel/vmlinux),只不过没有和初始化文件及解压文件链接而已;vmlinux是没有(zImage是压缩过的内核)压缩过的内核,就是由piggy.gzip.o、head.o、misc.o组成的,而decompress.o是为支持更多的压缩格式而新引入的。

    BootLoader完成系统的引导以后并将Linux内核调入内存之后,调用do_bootm_linux(),这个函数将跳转到kernel的起始位置。如果kernel没有被压缩,就可以启动了。如果kernel被压缩过,则要进行解压,在压缩过的kernel头部有解压程序。压缩过的kernel入口第一个文件源码位置在arch/arm/boot/compressed/head.S。它将调用函数decompress_kernel(),这个函数在文件arch/arm/boot/compressed/misc.c中,decompress_kernel()又调用proc_decomp_setup(),arch_decomp_setup()进行设置,然后打印出信息“Uncompressing Linux...”后,调用gunzip()将内核放于指定的位置。

    下面简单介绍一下解压缩过程,也就是函数decompress_kernel实现的功能:解压缩代码位于kernel/lib/inflate.c,inflate.c是从gzip源程序中分离出来的,包含了一些对全局数据的直接引用,在使用时需要直接嵌入到代码中。gzip压缩文件时总是在前32K字节的范围内寻找重复的字符串进行编码, 在解压时需要一个至少为32K字节的解压缓冲区,它定义为window[WSIZE]inflate.c使用get_byte()读取输入文件,它被定义成宏来提高效率。输入缓冲区指针必须定义为inptr,inflate.c中对之有减量操作。inflate.c调用flush_window()来输出window缓冲区中的解压出的字节串,每次输出长度用outcnt变量表示。在flush_window()中,还必须对输出字节串计算CRC并且刷新crc变量。在调用gunzip()开始解压之前,调用makecrc()初始化CRC计算表。最后gunzip()返回0表示解压成功。我们在内核启动的开始都会看到这样的输出:

    UncompressingLinux...done, booting the kernel.

    这也是由decompress_kernel函数输出的,执行完解压过程,再返回到head.S中的583行,启动内核

    call_kernel: bl    cache_clean_flush
                 bl    cache_off
                 mov       r0, #0                   @ must be zero
                 mov       r1, r7                   @ restore architecture number
                 mov       r2, r8                   @ restore atags pointer
                 mov       pc, r4                   @ call kernel

    其中r4中已经在head.S的第180行处预置为内核镜像的地址,如下代码:

    #ifdef CONFIG_AUTO_ZRELADDR
                 @determine final kernel image address
                 mov       r4, pc
                 and r4, r4, #0xf8000000
                 add r4, r4, #TEXT_OFFSET
    #else
                 ldr   r4, =zreladdr
    #endif

    这样就进入Linux内核的第一阶段,我们也称之为stage1

    二、Linux内核启动第一阶段stage1

    承接上文,这里所以说的第一阶段stage1就是内核解压完成并出现Uncompressing Linux...done,booting the kernel.之后的阶段。该部分代码实现在arch/arm/kernel的 head.S中,该文件中的汇编代码通过查找处理器内核类型和机器码类型调用相应的初始化函数,再建 立页表,最后跳转到start_kernel()函数开始内核的初始化工作。检测处理器类型是在汇编子函数__lookup_processor_type中完成的,通过以下代码可实现对它的调用:bl__lookup_processor_type(在文件head-commom.S实现)。__lookup_processor_type调用结束返回原程序时,会将返回结果保存到寄存器中。其中r5寄存器返回一个用来描述处理器的结构体地址,并对r5进行判断,如果r5的值为0则说明不支持这种处理器,将进入__error_pr8保存了页表的标志位,r9 保存了处理器的ID 号,r10保存了与处理器相关的struct proc_info_list结构地址。Head.S核心代码如下:

    ENTRY(stext)
    setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @设置SVC模式关中断
          mrc p15, 0, r9, c0, c0        @ 获得处理器ID,存入r9寄存器
          bl    __lookup_processor_type        @ 返回值r5=procinfo r9=cpuid
          movs      r10, r5                       
     THUMB( it eq )        @ force fixup-able long branch encoding
          beq __error_p                   @如果返回值r5=0,则不支持当前处理器'
          bl    __lookup_machine_type         @ 调用函数,返回值r5=machinfo
          movs      r8, r5            @ 如果返回值r5=0,则不支持当前机器(开发板)
    THUMB( it   eq )             @ force fixup-able long branch encoding
          beq __error_a                   @ 机器码不匹配,转__error_a并打印错误信息
          bl    __vet_atags
    #ifdef CONFIG_SMP_ON_UP    @ 如果是多核处理器进行相应设置
          bl    __fixup_smp
    #endif
          bl    __create_page_tables  @最后开始创建页表

    检测机器码类型是在汇编子函数__lookup_machine_type (同样在文件head-common.S实现) 中完成的。与__lookup_processor_type类似,通过代码:“bl __lookup_machine_type”来实现对它的调 用。该函数返回时,会将返回结构保存放在r5、r6 和r7三个寄存器中。其中r5寄存器返回一个用来描述机器(也就是开发板)的结构体地址,并对r5进行判断,如果r5的值为0则说明不支持这种机器(开发板),将进入__error_a,打印出内核不支持u-boot传入的机器码的错误如图2。r6保存了I/O基地址,r7 保存了 I/O的页表偏移地址。 当检测处理器类型和机器码类型结束后,将调用__create_page_tables子函数来建立页表,它所要做的工作就是将 RAM 基地址开始的1M 空间的物理地址映射到 0xC0000000开始的虚拟地址处。对本项目的开发板DM3730而言,RAM挂接到物理地址0x80000000处,当调用__create_page_tables 结束后 0x80000000 ~ 0x80100000物理地址将映射到 0xC0000000~0xC0100000虚拟地址处。当所有的初始化结束之后,使用如下代码来跳到C 程序的入口函数start_kernel()处,开始之后的内核初始化工作: bSYMBOL_NAME(start_kernel) 。

        

                                         图2 机器码不匹配错误

    三、Linux内核启动第二阶段stage2

     从start_kernel函数开始

    Linux内核启动的第二阶段从start_kernel函数开始。start_kernel是所有Linux平台进入系统内核初始化后的入口函数,它主要完成剩余的与 硬件平台相关的初始化工作,在进行一系列与内核相关的初始化后,调用第一个用户进程- init 进程并等待用户进程的执行,这样整个 Linux内核便启动完毕。该函数位于init/main.c文件中,主要工作流程如图3所示:

                                                                                     图3 start_kernel流程图

    该函数所做的具体工作有 :

    1) 调用setup_arch()函数进行与体系结构相关的第一个初始化工作;对不同的体系结构来说该函数有不同的定义。对于ARM平台而言,该函数定义在 arch/arm/kernel/setup.c。它首先通过检测出来的处理器类型进行处理器内核的初始化,然后 通过bootmem_init()函数根据系统定义的meminfo结构进行内存结构的初始化,最后调用 paging_init()开启MMU,创建内核页表,映射所有的物理内存和IO空间。 

    2) 创建异常向量表和初始化中断处理函数; 

    3) 初始化系统核心进程调度器和时钟中断处理机制; 

    4) 初始化串口控制台(console_init); 

    ARM-Linux 在初始化过程中一般都会初始化一个串口做为内核的控制台,而串口Uart驱动却把串口设备名写死了,如本例中linux2.6.37串口设备名为ttyO0,而不是常用的ttyS0。有了控制台内核在启动过程中就可以通过串口输出信息以便开发者或用户了解系统的启动进程。 

    5) 创建和初始化系统cache,为各种内存调用机制提供缓存,包括;动态内存分配,虚拟文件系统(VirtualFile System)及页缓存。 

    6) 初始化内存管理,检测内存大小及被内核占用的内存情况; 

    7) 初始化系统的进程间通信机制(IPC); 当以上所有的初始化工作结束后,start_kernel()函数会调用rest_init()函数来进行最后的初始化,包括创建系统的第一个进程-init进程来结束内核的启动。

    挂载根文件系统并启动init

    Linux内核启动的下一过程是启动第一个进程init,但必须以根文件系统为载体,所以在启动init之前,还要挂载根文件系统。

    四、挂载根文件系统

    根文件系统至少包括以下目录:

     /etc/:存储重要的配置文件。

     /bin/:存储常用且开机时必须用到的执行文件。

     /sbin/:存储着开机过程中所需的系统执行文件。

     /lib/:存储/bin//sbin/的执行文件所需的链接库,以及Linux的内核模块。

     /dev/:存储设备文件。

      注:五大目录必须存储在根文件系统上,缺一不可。

    以只读的方式挂载根文件系统,之所以采用只读的方式挂载根文件系统是因为:此时Linux内核仍在启动阶段,还不是很稳定,如果采用可读可写的方式挂载根文件系统,万一Linux不小心宕机了,一来可能破坏根文件系统上的数据,再者Linux下次开机时得花上很长的时间来检查并修复根文件系统。

        挂载根文件系统的而目的有两个:一是安装适当的内核模块,以便驱动某些硬件设备或启用某些功能;二是启动存储于文件系统中的init服务,以便让init服务接手后续的启动工作。

    执行init服务

    Linux内核启动后的最后一个动作,就是从根文件系统上找出并执行init服务。Linux内核会依照下列的顺序寻找init服务:

    1)/sbin/是否有init服务

    2)/etc/是否有init服务

    3)/bin/是否有init服务

    4)如果都找不到最后执行/bin/sh

    找到init服务后,Linux会让init服务负责后续初始化系统使用环境的工作,init启动后,就代表系统已经顺利地启动了linux内核。启动init服务时,init服务会读取/etc/inittab文件,根据/etc/inittab中的设置数据进行初始化系统环境的工作。/etc/inittab定义init服务在linux启动过程中必须依序执行以下几个Script

     /etc/rc.d/rc.sysinit

     /etc/rc.d/rc

    /etc/rc.d/rc.local

    /etc/rc.d/rc.sysinit主要的功能是设置系统的基本环境,当init服务执行rc.sysinit时 要依次完成下面一系列工作:

    (1)启动udev

    (2)设置内核参数

    执行sysctl –p,以便从/etc/sysctl.conf设置内核参数

    (3)设置系统时间

    将硬件时间设置为系统时间

    (4)启用交换内存空间

    执行swpaon –a –e,以便根据/etc/fstab的设置启用所有的交换内存空间。

    (5)检查并挂载所有文件系统

    检查所有需要挂载的文件系统,以确保这些文件系统的完整性。检查完毕后以可读可写的方式挂载文件系统。

    (6)初始化硬件设备

          Linux除了在启动内核时以静态驱动程序驱动部分的硬件外,在执行rc.sysinit时,也会试着驱动剩余的硬件设备。rc.sysinit驱动的硬件设备包含以下几项:

      a)定义在/etc/modprobe.conf的模块

      b)ISA PnP的硬件设备

      c)USB设备

    (7)初始化串行端口设备

     Init服务会管理所有的串行端口设备,比如调制解调器、不断电系统、串行端口控制台等。Init服务则通过rc.sysinit来初始化linux的串行端口设备。当rc.sysinit发现linux才能在这/etc/rc.serial时,才会执行/etc/rc.serial,借以初始化所有的串行端口设备。因此,你可以在/etc/rc.serial中定义如何初始化linux所有的串行端口设备。

    (8)清除过期的锁定文件与IPC文件

    (9)建立用户接口

    在执行完3个主要的RC Script后,init服务的最后一个工作,就是建立linux的用户界面,好让用户可以使用linux。此时init服务会执行以下两项工作:

    (10)建立虚拟控制台

     Init会在若干个虚拟控制台中执行/bin/login,以便用户可以从虚拟控制台登陆linuxlinux默认在前6个虚拟控制台,也就是tty1~tty6,执行/bin/login登陆程序。当所有的初始化工作结束后,cpu_idle()函数会被调用来使系统处于闲置(idle)状态并等待用户程序的执行。至此,整个Linux内核启动完毕。整个过程见图4。

          

                              图4:linux内核启动及文件系统加载全过程     

    展开全文
  • Linux内核启动文件系统载入过程 当u-boot開始运行bootcmd命令。就进入Linux内核启动阶段,与u-boot类似,普通Linux内核的启动过程也能够分为两个阶段,但针对压缩了的内核如uImage就要包含内核自解压过程了。...

    Linux内核启动及文件系统载入过程

    u-boot開始运行bootcmd命令。就进入Linux内核启动阶段,与u-boot类似,普通Linux内核的启动过程也能够分为两个阶段,但针对压缩了的内核如uImage就要包含内核自解压过程了。本文以linux-2.6.37版源代码为例分三个阶段来描写叙述内核启动全过程。

    第一阶段为内核自解压过程。第二阶段主要工作是设置ARM处理器工作模式、使能MMU、设置一级页表等。而第三阶段则主要为C代码,包含内核初始化的所有工作,以下是具体介绍。

    /******************************************************************************************************************************************/

     原创作品,转载时请务必以超链接形式标明文章原始出处:http://blog.csdn.net/gqb_driver/article/details/26954425,作者:gqb666  
    /******************************************************************************************************************************************/

    一、Linux内核自解压过程

    linux内核启动过程中一般能看到图1内核自解压界面,本小节本文重点讨论内核的自解压过程。

                    

                                         图1 解压内核

    内核压缩和解压缩代码都在文件夹kernel/arch/arm/boot/compressed。编译完毕后将产生head.o、misc.o、piggy.gzip.o、vmlinux、decompress.o这几个文件。head.o是内核的头部文件,负责初始设置。misc.o将主要负责内核的解压工作,它在head.o之后;piggy.gzip.o是一个中间文件。事实上是一个压缩的内核(kernel/vmlinux),仅仅只是没有和初始化文件及解压文件链接而已;vmlinux是没有(zImage是压缩过的内核)压缩过的内核,就是由piggy.gzip.o、head.o、misc.o组成的,而decompress.o是为支持很多其它的压缩格式而新引入的。

    BootLoader完毕系统的引导以后并将Linux内核调入内存之后。调用do_bootm_linux()。这个函数将跳转到kernel的起始位置。

    假设kernel没有被压缩。就能够启动了。

    假设kernel被压缩过,则要进行解压,在压缩过的kernel头部有解压程序。

    压缩过的kernel入口第一个文件源代码位置在arch/arm/boot/compressed/head.S。它将调用函数decompress_kernel()。这个函数在文件arch/arm/boot/compressed/misc.c中。decompress_kernel()又调用proc_decomp_setup(),arch_decomp_setup()进行设置。然后打印出信息“Uncompressing Linux...”后,调用gunzip()将内核放于指定的位置。

    以下简介一下解压缩过程,也就是函数decompress_kernel实现的功能:解压缩代码位于kernel/lib/inflate.c,inflate.c是从gzip源程序中分离出来的。包括了一些对全局数据的直接引用,在使用时须要直接嵌入到代码中。

    gzip压缩文件时总是在前32K字节的范围内寻找反复的字符串进行编码, 在解压时须要一个至少为32K字节的解压缓冲区,它定义为window[WSIZE]

    inflate.c使用get_byte()读取输入文件。它被定义成宏来提高效率。

    输入缓冲区指针必须定义为inptr,inflate.c中对之有减量操作。inflate.c调用flush_window()来输出window缓冲区中的解压出的字节串,每次输出长度用outcnt变量表示。在flush_window()中。还必须对输出字节串计算CRC而且刷新crc变量。在调用gunzip()開始解压之前,调用makecrc()初始化CRC计算表。

    最后gunzip()返回0表示解压成功。我们在内核启动的開始都会看到这种输出:

    UncompressingLinux...done, booting the kernel.

    这也是由decompress_kernel函数输出的。运行完解压过程,再返回到head.S中的583行,启动内核

    call_kernel: bl    cache_clean_flush
                 bl    cache_off
                 mov       r0, #0                   @ must be zero
                 mov       r1, r7                   @ restore architecture number
                 mov       r2, r8                   @ restore atags pointer
                 mov       pc, r4                   @ call kernel

    当中r4中已经在head.S的第180行处预置为内核镜像的地址。例如以下代码:

    #ifdef CONFIG_AUTO_ZRELADDR
                 @determine final kernel image address
                 mov       r4, pc
                 and r4, r4, #0xf8000000
                 add r4, r4, #TEXT_OFFSET
    #else
                 ldr   r4, =zreladdr
    #endif

    这样就进入Linux内核的第一阶段。我们也称之为stage1

    二、Linux内核启动第一阶段stage1

    承接上文。这里所以说的第一阶段stage1就是内核解压完毕并出现Uncompressing Linux...done,booting the kernel.之后的阶段。该部分代码实如今arch/arm/kernel的 head.S中,该文件里的汇编代码通过查找处理器内核类型和机器码类型调用对应的初始化函数,再建 立页表,最后跳转到start_kernel()函数開始内核的初始化工作。

    检測处理器类型是在汇编子函数__lookup_processor_type中完毕的,通过下面代码可实现对它的调用:bl__lookup_processor_type(在文件head-commom.S实现)。__lookup_processor_type调用结束返回原程序时。会将返回结果保存到寄存器中。当中r5寄存器返回一个用来描写叙述处理器的结构体地址。并对r5进行推断,假设r5的值为0则说明不支持这样的处理器,将进入__error_pr8保存了页表的标志位,r9 保存了处理器的ID 号,r10保存了与处理器相关的struct proc_info_list结构地址。

    Head.S核心代码例如以下:

    ENTRY(stext)
    setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @设置SVC模式关中断
          mrc p15, 0, r9, c0, c0        @ 获得处理器ID。存入r9寄存器
          bl    __lookup_processor_type        @ 返回值r5=procinfo r9=cpuid
          movs      r10, r5                       
     THUMB( it eq )        @ force fixup-able long branch encoding
          beq __error_p                   @假设返回值r5=0,则不支持当前处理器'
          bl    __lookup_machine_type         @ 调用函数,返回值r5=machinfo
          movs      r8, r5            @ 假设返回值r5=0。则不支持当前机器(开发板)
    THUMB( it   eq )             @ force fixup-able long branch encoding
          beq __error_a                   @ 机器码不匹配,转__error_a并打印错误信息
          bl    __vet_atags
    #ifdef CONFIG_SMP_ON_UP    @ 假设是多核处理器进行对应设置
          bl    __fixup_smp
    #endif
          bl    __create_page_tables  @最后開始创建页表

    检測机器码类型是在汇编子函数__lookup_machine_type (相同在文件head-common.S实现) 中完毕的。

    __lookup_processor_type类似。通过代码:“bl __lookup_machine_type”来实现对它的调 用。该函数返回时,会将返回结构保存放在r5、r6 和r7三个寄存器中。

    当中r5寄存器返回一个用来描写叙述机器(也就是开发板)的结构体地址,并对r5进行推断,假设r5的值为0则说明不支持这样的机器(开发板),将进入__error_a。打印出内核不支持u-boot传入的机器码的错误如图2。

    r6保存了I/O基地址,r7 保存了 I/O的页表偏移地址。

     当检測处理器类型和机器码类型结束后,将调用__create_page_tables子函数来建立页表。它所要做的工作就是将 RAM 基地址開始的1M 空间的物理地址映射到 0xC0000000開始的虚拟地址处。对本项目的开发板DM3730而言,RAM挂接到物理地址0x80000000处。当调用__create_page_tables 结束后 0x80000000 ~ 0x80100000物理地址将映射到 0xC0000000~0xC0100000虚拟地址处。当全部的初始化结束之后,使用例如以下代码来跳到C 程序的入口函数start_kernel()处,開始之后的内核初始化工作: bSYMBOL_NAME(start_kernel) 。

        

                                         图2 机器码不匹配错误

    三、Linux内核启动第二阶段stage2

     从start_kernel函数開始

    Linux内核启动的第二阶段从start_kernel函数開始。start_kernel是全部Linux平台进入系统内核初始化后的入口函数。它主要完毕剩余的与 硬件平台相关的初始化工作。在进行一系列与内核相关的初始化后,调用第一个用户进程- init 进程并等待用户进程的运行。这样整个 Linux内核便启动完毕。该函数位于init/main.c文件里,主要工作流程如图3所看到的:

                                                                                     图3 start_kernel流程图

    该函数所做的详细工作有 :

    1) 调用setup_arch()函数进行与体系结构相关的第一个初始化工作;对不同的体系结构来说该函数有不同的定义。

    对于ARM平台而言。该函数定义在 arch/arm/kernel/setup.c。它首先通过检測出来的处理器类型进行处理器内核的初始化。然后 通过bootmem_init()函数依据系统定义的meminfo结构进行内存结构的初始化,最后调用 paging_init()开启MMU,创建内核页表,映射全部的物理内存和IO空间。

     

    2) 创建异常向量表和初始化中断处理函数。 

    3) 初始化系统核心进程调度器和时钟中断处理机制; 

    4) 初始化串口控制台(console_init); 

    ARM-Linux 在初始化过程中一般都会初始化一个串口做为内核的控制台,而串口Uart驱动却把串口设备名写死了。如本例中linux2.6.37串口设备名为ttyO0。而不是经常使用的ttyS0。有了控制台内核在启动过程中就能够通过串口输出信息以便开发人员或用户了解系统的启动进程。 

    5) 创建和初始化系统cache,为各种内存调用机制提供缓存,包含;动态内存分配,虚拟文件系统(VirtualFile System)及页缓存。 

    6) 初始化内存管理,检測内存大小及被内核占用的内存情况。 

    7) 初始化系统的进程间通信机制(IPC)。 当以上全部的初始化工作结束后。start_kernel()函数会调用rest_init()函数来进行最后的初始化,包含创建系统的第一个进程-init进程来结束内核的启动。

    挂载根文件系统并启动init

    Linux内核启动的下一过程是启动第一个进程init,但必须以根文件系统为载体,所以在启动init之前,还要挂载根文件系统。

    四、挂载根文件系统

    根文件系统至少包含下面文件夹:

     /etc/:存储重要的配置文件。

     /bin/:存储经常使用且开机时必须用到的运行文件。

     /sbin/:存储着开机过程中所需的系统运行文件。

     /lib/:存储/bin//sbin/的运行文件所需的链接库。以及Linux的内核模块。

     /dev/:存储设备文件。

      注:五大文件夹必须存储在根文件系统上。缺一不可。

    以仅仅读的方式挂载根文件系统。之所以採用仅仅读的方式挂载根文件系统是由于:此时Linux内核仍在启动阶段。还不是非常稳定。假设採用可读可写的方式挂载根文件系统,万一Linux不小心宕机了,一来可能破坏根文件系统上的数据,再者Linux下次开机时得花上非常长的时间来检查并修复根文件系统。

        挂载根文件系统的而目的有两个:一是安装适当的内核模块。以便驱动某些硬件设备或启用某些功能;二是启动存储于文件系统中的init服务,以便让init服务接手兴许的启动工作。

    运行init服务

    Linux内核启动后的最后一个动作。就是从根文件系统上找出并运行init服务。Linux内核会按照下列的顺序寻找init服务:

    1)/sbin/是否有init服务

    2)/etc/是否有init服务

    3)/bin/是否有init服务

    4)假设都找不到最后运行/bin/sh

    找到init服务后,Linux会让init服务负责兴许初始化系统使用环境的工作,init启动后,就代表系统已经顺利地启动了linux内核。

    启动init服务时,init服务会读取/etc/inittab文件,依据/etc/inittab中的设置数据进行初始化系统环境的工作。/etc/inittab定义init服务在linux启动过程中必须依序运行下面几个Script

     /etc/rc.d/rc.sysinit

     /etc/rc.d/rc

    /etc/rc.d/rc.local

    /etc/rc.d/rc.sysinit基本的功能是设置系统的基本环境。当init服务运行rc.sysinit时 要依次完毕以下一系列工作:

    (1)启动udev

    (2)设置内核參数

    运行sysctl –p,以便从/etc/sysctl.conf设置内核參数

    (3)设置系统时间

    将硬件时间设置为系统时间

    (4)启用交换内存空间

    运行swpaon –a –e,以便依据/etc/fstab的设置启用全部的交换内存空间。

    (5)检查并挂载全部文件系统

    检查全部须要挂载的文件系统。以确保这些文件系统的完整性。检查完成后以可读可写的方式挂载文件系统。

    (6)初始化硬件设备

          Linux除了在启动内核时以静态驱动程序驱动部分的硬件外,在运行rc.sysinit时,也会试着驱动剩余的硬件设备。rc.sysinit驱动的硬件设备包括下面几项:

      a)定义在/etc/modprobe.conf的模块

      b)ISA PnP的硬件设备

      c)USB设备

    (7)初始化串行port设备

     Init服务会管理全部的串行port设备。比方调制解调器、不断电系统、串行port控制台等。Init服务则通过rc.sysinit来初始化linux的串行port设备。

    rc.sysinit发现linux才干在这/etc/rc.serial时。才会运行/etc/rc.serial。借以初始化全部的串行port设备。因此,你能够在/etc/rc.serial中定义怎样初始化linux全部的串行port设备。

    (8)清除过期的锁定文件与IPC文件

    (9)建立用户接口

    在运行完3个基本的RC Script后,init服务的最后一个工作,就是建立linux的用户界面,好让用户能够使用linux。此时init服务会运行下面两项工作:

    (10)建立虚拟控制台

     Init会在若干个虚拟控制台中运行/bin/login。以便用户能够从虚拟控制台登陆linuxlinux默认在前6个虚拟控制台。也就是tty1~tty6,运行/bin/login登陆程序。当全部的初始化工作结束后。cpu_idle()函数会被调用来使系统处于闲置(idle)状态并等待用户程序的运行。至此。整个Linux内核启动完成。

    整个过程见图4。

          

                              图4:linux内核启动及文件系统载入全过程 

    展开全文
  • ARM里面,启动MMU以后,我们编程看到的地址都是虚拟地址,经过MMU以后才是具体的物理地址。 4412在上电以后,MMU是关闭的,也就是说这个时候其实和单片机差不多,可以直接跑裸机程序(裸机程序,就是直接对CPU进行...

    以三星的四核处理器Exynos4412为例,该开发板属于armv7架构,contexA9系列,32bit,cpu4核心1.5GHZ主频,eMMC 大小型号为:KLM4G。

    ARM里面,启动MMU以后,我们编程看到的地址都是虚拟地址,经过MMU以后才是具体的物理地址。

    4412在上电以后,MMU是关闭的,也就是说这个时候其实和单片机差不多,可以直接跑裸机程序(裸机程序,就是直接对CPU进行编程),就跟单片机一样,但是,在Linux启动以后,操作系统就会把MMU打开,也就是说,虚拟地址就会出现。

    1. BootLoader启动过程

    ARM上电后,是从0地址开始取指令执行,先看:

    可以看出0地址在iROM中,即上电以后会执行它芯片内部iROM中的一段程序,这段程序是固化在芯片内部的,厂家烧进去的,我们看不到。iROM这段程序作用是什么?

    答:它会做一些初始化的工作,同时大部分开发板都可以从TF卡启动,也可以从EMMC启动,还可以从USB启动,这些功能的切换就是通过IROM来实现的。

    OM 就是启动方式,例如设置如下:

    IROM程序会根据管脚设置(板子上可以搞个拨动开关),选择从eMMC中寻找启动程序,如果找不到有效程序,再选择从TF卡启动。继续:

    已经知道,上电后,先执行iROM程序,会选择好从哪里启动(假如是eMMC),所以,自然而然的就去外部eMMC芯片找启动程序,找到以后,首先会拷贝8K的程序到内部RAM执行(垫脚石),这8k程序在BL1(BootLoader1)中,在这里得8k是被三星固化了隐藏起来的,看不到。执行BL1干嘛呢?

     BL1可以初始化系统时钟,UART,SDRAM等设备,然后会跑到BL2(Bootloader2)中,拷贝其内部程序到SDRAM中执行。BL2干嘛的呢?

    BL2可以支持更强大的功能,它会把我们熟悉的真正的Bootloader(例如Uboot)拷贝到内存中执行,这样BootLoader就可以启动起来了。

    2. 内核启动

    上面介绍了加载引导程序的过程,包括固化在固件中的boot代码(看不见、不能改)和BootLoader(开发者移植)两大部分。但并不是所有嵌入式系统中,都必须有这两部分,有些就没有固件程序,因此整个系统的加载启动任务就完全由BootLoader来完成,同样是从地址0x00000000处开始执行,而这个地址处安排的通常就是系统的BootLoader程序。

    bootloader一上电就拿到了cpu 的使用权,它当然得干一些初始化的工作啊,比如关闭看门狗、设置cpu 的运行模式、设置堆栈等等比较急迫的事情。当然还要对主板的一些其他硬件进行简单的初始化,比如外部DDR内存、网卡、显示屏、nand flash等等的初始化工作,最后当bootloader 完成它的使命之后就会把cpu 的使用权交给下一部分代码:kernel(内核) 。


    内核启动的作用就是进行系统硬件探测硬件驱动的初始化(比如SPI、蓝牙、以太网等等,所有的驱动都在里面,内核空间的相关工作已经完成,开始向用户空间转移,内核空间通过一个间接的initrd(一个虚拟的文件系统)向用户空间过度,然后开始挂载根文件系统。

    3. 挂接文件系统

    文件系统的百科解释:

    文件系统是操作系统用于明确存储设备(常见的是磁盘,也有基于NAND Flash的固态硬盘)或分区上的文件的方法和数据结构;即在存储设备上组织文件的方法。操作系统中负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统。文件系统由三部分组成:文件系统的接口,对对象操纵和管理的软件集合,对象及属性。从系统角度来看,文件系统是对文件存储设备的空间进行组织和分配,负责文件存储并对存入的文件进行保护和检索的系统。具体地说,它负责为用户建立文件,存入、读出、修改、转储文件,控制文件的存取,当用户不再使用时撤销文件等。

    表现出来就是,可视化界面,用户对文件的复制、粘贴、删除等等操作。

    文件系统实现对磁盘空间的统一管理,一方面文件系统对磁盘空间进行统一规划,另外一方面文件系统提供给普通用户人性化的接口。就好比仓库中的货架,将空间进行规划和编排,这样根据编号可以方便地找到具体的货物。而文件系统也是类似,将磁盘空间进行规划和编号处理,这样通过文件名就可以找到具体的数据,而不用关心数据到底是怎么存储的。

    其过程:initrd ----> /sbin/init ----> /etc/inittab

    initrd是一个虚拟的文件系统,里面有lib、bin、sbin、usr、proc、sys、var、dev、boot等一些目录,其目录有点像真的/,所以我们称之为虚拟的根文件系统,作用就是将kernel和真的根文件系统建立关联关系,让kernel去initrd中加载根文件系统所需要的驱动程序,并以读写的方式挂载根文件系统,并让执行用户当中第一个进程init。

    init执行完毕以后会启动系统内的/etc/inittab文件,来完成系统的初始化工作。

    补充:Android系统 = 大改的Linux内核+Android文件系统

     

    展开全文
  • Linux内核与根文件系统的关系详解

    千次阅读 2018-09-14 06:41:16
    Linux内核与根文件系统的关系 开篇题外话:对于Linux初学者来说,这是一个很纠结的问题,但这也是一个很关键的问题! 一语破天机: “尽管内核是 Linux 的核心,但文件却是用户与操作系统交互所采用的主要工具。这...
  • 配置内核支持NFS启动文件系统

    千次阅读 2014-10-01 21:08:36
    内核支持NFS分区(即编译时在File system中选中[*] Root file system on NFS), 以及支持内核IP_PNP(即编译时在Networking中选中[*] IP: kernel level autoconfiguration)  File systems  --->  Network ...
  • Linux系统从uboot到内核启动流程

    千次阅读 2018-11-13 14:13:28
    ARM CPU刚上电时,它的PC寄存器指针指向IC内嵌的一片ROM的起始位置处,这片ROM称之为BROM(boot rom),系统就是通过这片BROM引导起来的。BROM的空间比较小,一般是32/64KB,IC上的ShareRAM大小也不尽相同,所以IC...
  • 嵌入式移植学习第二个内容,通过nfs挂载根文件系统。也是自己第一次做,也遇到了一些问题,但最后还是都解决了。在此记录一下整个流程,也希望能够给别的初学者一个参考。 系统环境 PC端 linux :ubuntu 14.04 ...
  • Linux内核移植与启动 Target borad:FL2440 Bootloader:U-boot-2010.09 交叉编译器:buildroot-2012.08 1.linux内核基础知识 ...在动手进行linux内核移植之前...1.1 Linux内核启动过程概述 一个嵌入式Linux系统
  • 内核添加对yaffs2文件系统的支持

    千次阅读 2016-11-14 12:38:42
    GitHub 内核添加对yaffs2文件系统的支持 AderXCoding/system/tools/yaffs2 本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可, 转载请注明出处, 谢谢合作 1 yaffs介绍YAFFS, Yet ...
  • 1、Linux内核文件系统之间,什么关系?没有文件系统,Linux能运行不能运行? 可以有也可以没有,Linux这个操作系统,很奇怪!必须要挂一个文件系统!像有些操作系统,比如Vxworks就不需要,uCos也不需要,但是,...
  • 先转载别人的文章,然后提出我的问题:内核编译链接过程是依靠vmlinux.lds文件,以arm为例vmlinux.lds文件位于kernel/arch/arm/vmlinux.lds,vmlinux-armv.lds的生成过程在kernel/arch/arm/Makefile中ifeq ($(CONFIG...
  • Linux内核启动文件系统加载过程

    千次阅读 2015-08-26 10:45:41
    Linux内核启动文件系统加载过程 当u-boot开始执行bootcmd命令,就进入Linux内核启动阶段,与u-boot类似,普通Linux内核的启动过程也可以分为两个阶段,但针对压缩了的内核如uImage就要包括内核自解压过程了。...
  • 内核文件系统的关系

    千次阅读 2017-09-30 22:54:29
    Linux内核与根文件系统的关系 开篇题外话:对于Linux初学者来说,这是一个很纠结的问题,但这也是一个很关键的问题! 一语破天机: “尽管内核是 Linux 的核心,但文件却是用户与操作系统交互所采用的主要工具。这...
  • 这类问题很常见,先总体介绍...2. 内核支持这种文件系统格式 3. 文件系统的内容要完备   上面说得简单,一个个介绍。   1. 在正确的位置烧写正确的文件系统映象:   (a). 正确的位置 嵌入式开发中,常通过bo
  • Linux内核编译流程(Menuconfig图形化方式)Menuconfig配置内核原理:在Linux里面我们所看到的menuconfig界面是通过配置内核顶层的Kconfig产生的,而当输入make menuconfig命令的时候系统会读取Makefile来解析...
  • uboot烧写内核文件系统

    千次阅读 2017-09-28 11:02:39
    a) 将u-boot 启动参数修改为网络启动 #setenv serverip 192.168.9.120 #setenv ipaddr 192.168.9.233 #setenv bootcmd tftp 41000000 uImage\;tftp 42000000 exynos4412-fs4412.dtb\;bootm 41000000 - 42000000
  • ubuntu 系统制作 Aut. wmy Dat.2016.11.20 ...不能从android源代码里面把kernel单独抠出来,那样会无法启动ubuntu文件系统。本文参考rk官网和firefly论坛相关文章。 一、内核镜像制作 1.linux-boot.img。
  • Linux内核文件系统分析

    千次阅读 2016-08-18 15:45:29
    1、Linux内核源代码目录结构 arch:包含和硬件体系结构相关的代码,每种平台占一个相应的目录,如i386、arm、powerpc、mips等。block:块设备驱动程序I/O调度。crypto:常用加密和散列算法(如AES、SHA等),还有...
  • 这段时间,零零碎碎地做了不少东西,先是移植了2440的uboot,内核以及根文件系统的制作,这部分有一些参考的视频,2440板子玩的人也比较多,所以参考资料相对较多。。对这一部分就不整理了。之后主要是对一块am3358...
  • 【Linux 内核文件系统(概念篇)

    千次阅读 2015-11-01 12:04:46
    一、开篇Linux下的文件系统为树形结构,入口为/(根目录)树形结构下的文件目录,Linux发行版本之间的差别很少,差别主要表现在系统管理的特色工具以及软件包管理方式的不痛,目录结构基本上是一样的。Windows的文件...
  • 一、编译Linux内核 下载Linux内核  推荐使用国内的镜像网站下载  下载完成后解压 修改Makefile  搜索CROSS_COMPILE交叉编译 ARCH ?= arm CROSS_COMPILE ?= arm-linux-gnueabi-    进入/arch/arm/...
  • 他在一个叫ramfs的cache实现上加了一层很薄的封装,其他内核开发人员编写了一个改进版tmpfs,这个文件系统上的数据可以写出交换分区,而且可以设定一个tmpfs装载点的最大尺寸以免耗尽内存。initramfs就是tmpfs的...
  • 这3部分是怎么相互协作来构成这个系统的呢? 各自有什么用呢? 三者有什么联系?...下面是笔者针对网上bootloader、linuxkernel(linux内核)、rootfile(根文件系统),三者关系的一个总结   1.LINUX中b...
  • linux文件系统启动流程、启动脚本

    千次阅读 2017-06-06 17:07:57
    在了解启动流程之前,我们应该先知道系统的几个重要脚本和配置文件,他们对应的路径为: 1. /sbin/init 2. /etc/inittab 3. /etc/rc.d/rc.sysinit 4. /etc/rc.d/rcN.d //这是几个文件夹N代表数字1,2,3,4.. 5. /etc/...
  • 第一章移植内核 1.1 Linux内核基础知识 1.1.1 Linux版本 ...1.2 Linux内核启动过程概述 1.2.1 Bootloader启动过程 1.2.2 Linux启动过程 1.3 Linux内核移植 1.3.1 移植内核和根文
  • 打开系统文件  vim /boot/grub/grub.conf 默认由0开始计数,因此须将default值改为0即可。 重启服务器  reboot ----------------------------- #boot=/dev/sda default=1 timeout=5 ...
  • linux内核启动过程分析

    千次阅读 2018-10-30 09:36:45
    (4)在内核启动的早期,建立的段式页表,并在内核启动的前期使用;在内核启动的后期,就会再次建立细页表并启用。等内核启动工作起来之后就只有细页表了。 5.__switch_data (1)建立了段式页表后进入了__...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 385,045
精华内容 154,018
关键字:

内核到哪里启动文件系统