第二章、基础准备——Linux 系统定制原理

Linux 系统的组成及架构

共享库和静态库

在 Linux 系统中,函数库包含两种形式:共享库和静态库。

共享库

共享库在程序运行时,为其提供所需要的函数,所以程序运行时该共享库必须存在系统中,且能够被系统找到并且使用。

静态库

静态库在编译程序的期间就将各种函数编译到程序中,程序运行的时候,即使该静态库不存在也可以正常调用其中的函数。

C 库及各类功能库

在常规的 Linux 系统中,一般提供一个 C 函数库的实现,所谓的 C 函数库就是将标准 C 语言中的各种函数功能(如标准输入/输出)进行实现的库程序文件,在 Linux 中很多程序都是采用 C 语言来进行编写的,所以 C 函数库是作为一个比较重要的函数库存在于系统中的。

除了标准的 C 库实现外,还需要实现一些通用的或者特定的功能,这些功能也被组织成为函数库形式存在与系统中,有了这些丰富的函数库,Linux 系统的功能得到了不断的增强,编写各类程序也越来越容易了,这些函数库也成为了 Linux 系统中常见的组成部分。

在常规的 Linux 系统中, C 库一般采用 Glibc,各类功能的函数库则非常丰富,如 Zlib、Ncurses 等。

FHS 与 LSB

为了使各种发行版之间有良好的兼容性,国际相关组织对 Linux 系统中重要目录的命名,存放为止和用途都做了规定,这份规定则称为 FHS

FHS 包含在 LSB(Linux standards Bases)规则中,为了能够保证不同 Linux 发行版提供的应用程序能够很好的相互兼容,LSB 规则中包含了目录,文件和函数库等的明明,存放及一系列要求。

Linux 系统的基本目录组成及其主要作用



Linux 系统的启动

BIOS/启动器

一般的计算机设备都会有一个 BIOS 固化软件,BIOS 会对计算机设备进行最基本的很粗实话工作,而启动器则承担了从逻辑状态设备进入操作系统控制设备的链接作用。

启动器一般通过引导程序来实现。

不同架构的计算机常用的启动器是不一样的,有的启动器独立于 BIOS ,如 x86 下的 GRUB 和 LILO,BIOS 初始化完成后读取存储设备中的固定区域,GRUB 或者 LILO 等启动器会降一部分代码存放在这个区域中,这样会从 BIOS 中获得计算机的控制权。

一些嵌入式的设备则会使用一些带有 BIOS 功能的启动器,如 U-Boot,这类启动器一般将直接固话在计算机中。

不同的启动器使用的设置方式是不同的,大多数具备相对高级功能的启动器会使用配置文件的方法,如 GRUB,启动器按照可以识别的设备进行读取内核。

完成读取后会将计算机的控制权交给读取的内核中去处理,通常是跳转到内核的执行起始位置。

Linux 内核的初始化

内核在活的了计算机的控制权之后就会惊醒各种设备的初始化工作,虽然部分初始化工作已经在 BIOS 中进行了,但是内核为了保证设备的初始化的可靠性会再次进行初始化。

Linux 内核也会进行各种自身功能的初始化工作,比如内存管理,进程管理等。

这个阶段的 Linux 内核是无法加载模块的,因此启动设备及其文件系统的驱动必须要编译进内核,不能使用模块的方式。

Linux 内核启动完成后会将计算机的控制交给启动控制程序,分别有三个程序。

Initramfs

这是 Linux 2.5 内核中最新加入的启动控制方式,Initramfs 是一个使用 CPIO 格式打包的文件,还原该文件将得到一个小型的 Linux 系统,Linux 内核将以该系统作为启动系统,并且将执行权交给其中的 /init 命令。

initrd

initrd 文件是一个小型的文件系统,内部包含了启动所需要的命令及其内核模块,内核将该文件镜像到 /dev/ram0 设备中,/deb/ram0 是内存磁盘设备。

镜像还原后 Linux 内核会执行其中的 /linuxrc 文件,该文件执行结束后返回 Linux 内核,内核将执行权限交给了根文件系统中的 /sbin/init 命令。

/sbin/init

这个是一个标准的 启动控制程序的启动位置和命令名称。

神奇的 Initramfs 和 initrd

Linux 内核启动时,启动器传递给内核的启动参数中可以指定 init 程序,内核在完成初始化后会将执行权交给该命令。

Initramfs 和 initrd 都提供了一个小型的系统,该系统可以根据不同的硬件环境来进行特定的工作,这使得 Linux 系统可以适应很多的硬件平台。

在 LiveCD 中就采用 initramfs 或者 initrd 来保证在大多数的同类计算机上正常的使用, Initramfs 和 initrd 还可以用来帮助使得系统的启动过程更加灵活。

本地定制 Linux 系统的原理

如何确定依赖的共享库?

对于一个二进制的程序文件,确定其依赖的共享库可以通过使用如下命令:

ldd <文件名>

牛逼的 Glibc

编译工具中包含了 GCC、Binutils,辅助命令则包括 Make 等编译相关的命令程序,他们和其他程序一样必须要有运行的环境。

而基本这些工具都会依赖 Glibc(当然并不是所有的编译相关的命令都会依赖这个库,但是基本大多数都是依赖这个库的)

工具链

工具连是由编译器、汇编器、链接器及其函数库组成的,在 Linux 系统中常识用 GCC、Binutils 和 Glibc 的组合。

需要记住一条工具连的原则是

由某一个工具链编译出来的二进制程序文件或者函数库文件,必然链接该工具连中的函数库,无论是静态链接方式还是动态连接方式。

工具链的「外部依赖」和「内部依赖」

根据上面说的工具链的原则,可以知道,如果一个程序,它的运行需要依赖工具链之外的 Glibc 或者其他库,就叫做外部依赖,它必然不是由含有 Glibc 的库的工具链编译出来的。

而如果它的运行根本就不需要外部的其他库,而是依赖工具链中的 Glibc ,也就是编译它的工具链中含有 Glibc 我们就说这个程序是内部依赖。

变换工具链的依赖方式

假如你有一个完整的工具链,我们称他为 A 组,内里含有「Glibc_A」「GCC_A」「Binutils_A」

你用它编译出了 B 组工具链,内里含有「Glibc_B」「Binutils_B」唯独不含有「Glibc_B」,这样的工具链我们称为是不完整的工具链。

你如果用 B 组工具链去编译一个程序,这个程序生成后依赖的库将会是 A 组的 「Glibc_A」,因为 B 组工具链是由 A 组工具链编译出来的,因为 B 组没有 Glibc_B 这个库,但是根据工具链的原则,他含有 Glibc_A 这个库,所以你用 B 组工具链来编译一个程序,当然是链接的 A 组的 Glibc_A

然后你用 B 组工具链,**使用外部的 Glibc 而不是内部的 Glibc_A **编译出了一个 Glibc_B ,并且分别编译出了「GCC_C」「Binutils_C」,这个时候这三个程序合称为 C 组工具链。

需要注意的是,最后的这个工程,就体现了通过一定的设置,内部依赖和外部依赖可以相互转换,实际的制作过程中,工具链 B 的依赖模式的确是从内部依赖变为了外部依赖,而这个设置的过程,就叫做「调整工具链」

初始工具链

工具链 A 称为「初始工具链」或者叫做「原工具链」

过渡工具链

可以看出,工具链 B 的存在就是为了形成工具链 C ,所以工具链 B 也成为「过渡工具链」或者叫做「临时工具链」

目的工具链

工具链 C 称为「目的工具链」或者叫做「目标工具链」

《手把手教你构建自己的 Linux 系统》学习笔记(1)的更多相关文章

  1. Java性能调优笔记

    Java性能调优笔记 调优步骤:衡量系统现状.设定调优目标.寻找性能瓶颈.性能调优.衡量是否到达目标(如果未到达目标,需重新寻找性能瓶颈).性能调优结束. 寻找性能瓶颈 性能瓶颈的表象:资源消耗过多. ...

  2. Java性能调优攻略全分享,5步搞定!(附超全技能图谱)

    对于很多研发人员来说,Java 性能调优都是很头疼的问题,为什么这么说?如今,一个简单的系统就囊括了应用程序.数据库.容器.操作系统.网络等技术,线上一旦出现性能问题,就可能要你协调多方面组件去进行优 ...

  3. Java性能调优(一):调优的流程和程序性能分析

     https://blog.csdn.net/Oeljeklaus/article/details/80656732 Java性能调优 随着应用的数据量不断的增加,系统的反应一般会越来越慢,这个时候我 ...

  4. Java性能调优:利用JMC分析性能

    Java性能调优作为大型分布式系统提供高性能服务的必修课,其重要性不言而喻. 好的分析工具能起到事半功倍的效果,利用分析利器JMC.JFR,可以实现性能问题的准确定位. 本文主要阐述如何利用JMC分析 ...

  5. Java性能调优:利用JFR生成性能日志

    Java性能调优作为大型分布式系统提供高性能服务的必修课,其重要性不言而喻. 好的分析工具能起到事半功倍的效果,利用分析利器JMC.JFR,可以实现性能问题的准确定位. 本文主要阐述如何利用JFR生成 ...

  6. 第六章 Java性能调优工具(待续)

    Java性能调优工具 Windows工具 JDK命令行工具 JConsole工具 Visual VM多合一工具 Visual VM对QQL的支持 MAT内存分析工具 MAT对QQL的支持 JProfi ...

  7. java 性能调优和GC

    JAVA 性能调优和GC http://blog.csdn.net/gzh0222/article/details/7663181 JAVA GC调优手记 http://blog.csdn.net/f ...

  8. Java性能调优概述

    目录 Java性能调优概述 性能优化有风险和弊端,性能调优必须有明确的目标,不要为了调优而调优!!!盲目调优,风险远大于收益!!! 程序性能的主要表现点 执行速度:程序的反映是否迅速,响应时间是否足够 ...

  9. Java性能调优实战,覆盖80%以上调优场景

    Java 性能调优对于每一个奋战在开发一线的技术人来说,随着系统访问量的增加.代码的臃肿,各种性能问题便会层出不穷. 日渐复杂的系统,错综复杂的性能调优,都对Java工程师的技术广度和技术深度提出了更 ...

  10. 《Java性能调优》学习笔记(1)

    性能的参考指标 执行时间 -- 从代码开始运行到结束的时间 CPU时间 -- 函数或者线程占用CPU的时间 内存分配 -- 程序在运行时占用内存的情况 磁盘吞吐量 -- 描述IO的使用情况 网络吞吐量 ...

随机推荐

  1. Python学习初级python3.6的安装配置

    首先我们来安装python 1.首先进入网站下载:点击打开链接(或自己输入网址https://www.python.org/downloads/),进入之后如下图,选择图中红色圈中区域进行下载. 2. ...

  2. Spring5.x源码分析 | 从踩坑到放弃之环境搭建

    Spring5.x源码分析--从踩坑到放弃之环境搭建 前言 自从Spring发行4.x后,很久没去好好看过Spring源码了,加上最近半年工作都是偏管理和参与设计为主,在技术细节上或多或少有点疏忽,最 ...

  3. DDD-CQRS的落地案例

    摘要 在之前的文章DDD-CQRS能解什么问题中,阐述了什么是CQRS.但是并没有业务需求可以应用CQRS.最近需要处理一个文本增量更新的业务,经过需求分析后,尝试使用CQRS来解这个问题 问题分析 ...

  4. django 发布会签到系统web开发

    引言 最近学习了虫师的发布会签到系统demo,结合自己所学django知识,对demo重新塑造了一下.也是为了练练手,巩固知识.现在就分享一下成果~ Django工作流 学习django web开发, ...

  5. 懒人必备,IntelliJ IDEA中代码一键生成

    之前有不少小伙伴问松哥微人事项目(https://github.com/lenve/vhr)使用的 MyBatis 逆向工程在哪里?其实旧版微人事当时没有使用逆向工程,是我自己手动敲出来的,当然手动敲 ...

  6. Codeforces_822

    A.小的那个数的阶乘. #include<bits/stdc++.h> using namespace std; int a,b; int main() { ios::sync_with_ ...

  7. Codeforces 977D Divide by three, multiply by two(拓扑排序)

      Polycarp likes to play with numbers. He takes some integer number xx, writes it down on the board, ...

  8. 输入url地址到展示主页的过程

    过程 1.DNS解析 2.TCP连接 3.发送HTTP请求 4.服务器处理请求并返回HTTP报文 5.浏览器解析渲染页面 6.连接结束

  9. 分布式SnowFlakeID(雪花ID)原理和改进优化

    最近在研究分布式框架的组件和整体设计思路.所有的问题,一旦涉及分布式难度就呈几何倍数的提升.包括最常见的ID生成也是,单机情况下,使用数据库自增ID.UUID都是简单易行的选择 但在分布式环境下,就需 ...

  10. Invoking Descriptors - Python 描述符的用法建议

    描述符用法建议, 内置的 property 类创建的是'覆盖型'(date descriptor), 实现了 __set__ 和 __get__. 特性 property 的 __set__ 方法 默 ...