姓名:陈方园 学号:19020100239 学院:电子工程学院https://blog.csdn.net/HaaSTech/article/details/116486192
转自:
https://max.book118.com/html/2021/0122/6011000144003053.shtm
【嵌牛导读】嵌入式一般指嵌入式系统。嵌入式系统由硬件和软件组成。是能够独立进行运作的器件。Linux,全称GNU/Linux,是一种免费使用和自由传播的类UNIX操作系统,其内核由林纳斯·本纳第克特·托瓦兹于1991年10月5日首次发布,它主要受到Minix和Unix思想的启发,是一个基于POSIX的多用户、多任务、支持多线程和多CPU的操作系统。
【嵌牛鼻子】内核
【嵌牛提问】什么是引导内核?
【嵌牛正文】
2.2.3 引导内核
现在U-Boot已经初始化了硬件、串行端口和以太网接口,在其短暂但有益的生命中还剩一件工作:加载并引导Linux内核。所有的引导加载程序都提供了命令用于加载和执行操作系统镜像。代码清单2-2显示了使用U-Boot手动加载并引导Linux内核的一种常用方法。
代码清单2-2
加载Linux内核代码清单2-2开头的tftp命令指示U-Boot使用TFTP[3]协议将内核镜像uImage通过网络加载到内存。在这个例子中,内核镜像存放于开发工作站(通常,这个开发工作站就是通过串行端口与目标板相连的那台主机)。执行tftp命令时,需要传入一个地址参数,这个地址用于指定内核镜像将要被加载到的目标板内存的物理地址。读者现在不用担心这些细节,第7章将会详细介绍U-Boot。
第2次执行tftp命令加载了一个目标板配置文件,称为设备树(device tree),这个文件还有其他的名字,包括扁平设备树(flat device tree)和设备树二进制文件(device tree binary)或dtb。你将在第7章了解到这个文件的更多信息。现在,你只要知道这个文件与具体目标板相关,包含了内核所需的用于引导目标板的信息就足够了。这些信息包括内存大小、时钟核直至在目标板上出现控制台命令行提示符,如同登录提示符所示。
注意bootm命令为U-Boot敲响了丧钟。这是一个重要的概念。与桌面PC的BIOS不同,大多数的嵌入式系统都采用这样一种架构:当Linux内核掌握控制权时,引导加载程序就不复存在了。Linux内核会要求收回那些之前被引导加载程序所占用的内存和系统资源。将控制权交回给引导加载程序的唯一方法就是重启目标板。
最后还需要注意一点。在代码清单2-2的串行端口输出中,下面这行之前的信息(包含这一行)都是由U-Boot引导加载程序产生的:
其余引导信息是由Linux内核产生的。对于这一点,我们在后续章节还要详细说明,但我们需要注意U-Boot是在哪儿离开的以及Linux内核是在哪儿取得控制权的。
2.2.4 内核初始化:概述
当Linux内核开始执行时,它会在其相当复杂的引导过程中输出大量状态消息。在当前讨论的这个例子中,在显示登录提示符之前,Linux内核大约显示了200行printk[4]打印信息(代码清单中省略了这些打印行以便讨论的重点更加清晰)。代码清单2-3再现了登录提示符之前的最后几行输出。这个练习的目的不是要深入到内核初始化的细节中去(第5章会讲述这方面的内容),而是要对正在发生的事情,以及对嵌入式系统中引导Linux内核需要哪些组件有一个概览。
代码清单2-3 Linux内核加载的最后几行引导消息
Linux在串行端口终端上显示登录提示符之前,会挂载一个根文件系统。在代码清单2-3中,Linux通过一系列必要步骤,从一个NFS[5]服务器来远程(通过以太网)挂载其根文件系统,这个NFS服务器程序运行于IP地址为192.168.0.9的主机之上。通常这个主机就是你的开发工作站。根文件系统包含构成整个Linux系统的应用程序、系统库和工具软件。
重申一下这里讨论的重点:Linux必须有一个文件系统。很多老式的嵌入式操作系统不需要文件系统,因此那些从老式嵌入式操作系统迁移到嵌入式Linux系统的工程师往往会感到惊讶。一个文件系统由一组预定义的系统目录和文件组成,这些目录和文件按照特定的布局存储在硬盘或其他存储介质上,而Linux内核可以挂载这些介质作为其根文件系统。
注意Linux也可以从其他设备挂载根文件系统。最常见的情况当然是挂载一个硬盘分区作为根文件系统,就像笔记本或工作站中的Linux系统所做的那样。实际上,当你将嵌入式Linux小玩意带出房门或远离开发环境时,NFS就没什么用处了。然而,在读这本书的过程中,你会逐渐体会到在开发环境中挂载NFS根文件系统带来的威力和灵活性。
2.2.5 第一个用户空间进程:init
继续探讨其他内容之前,还有一个重点需要强调一下。请注意代码清单2-3中的这一行:
直到这时,内核都是自己在执行代码,它在一个称为内核上下文(kernel context)的环境中完成大量的初始化工作。在这个运行状态下,内核拥有所有的系统内存并且全权控制所有的系统资源。内核能够访问所有的物理内存和所有的I/O子系统。它在内核虚拟地址空间中执行代码,使用一个由内核自己创建和支配的栈。
当内核完成其内部初始化并挂载了根文件系统后,默认会执行一个名为init的应用程序。内核一启动init,它随即进入用户空间(user space)或用户空间上下文运行。在这个运行状态下,用户空间进程对系统的访问是受限的,必须使用内核系统调用(system call)来请求内核服务,比如设备和文件I/O。这些用户空间进程或程序,运行在一个由内核随机[6]选择和管理的虚拟内存空间中。在处理器中专门的内存管理硬件的协助下,内核为用户空间进程完成虚拟地址到物理地址的转换。这种架构的最大好处是某个进程中的错误不会破坏其他进程的内存空间。这是老式嵌入式系统的一个普遍缺陷,会产生那些最难查找的故障。
对这些概念不熟悉也不用惊慌。本节的目标只是提纲挈领地作个介绍,在此基础上,你会在阅读本书的过程中逐步获得更加深入的理解。后续章节将详细解释这些概念。