【嵌入式开发】 Linux Kernel 下载 配置 编译 安装 及 驱动简介(一)

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 【嵌入式开发】 Linux Kernel 下载 配置 编译 安装 及 驱动简介(一)

一. Linux 内核简介





1. 内核功能简介





(1) 操作系统 和 内核 简介



操作系统 :


-- 功能 : 完成基本功能 和 系统管理;


-- 组成 : 内核(kernel), 设备驱动程序(driver), 启动引导程序(bootloader), 命令行(shell), 用户界面(UI), 文件系统(filesystem), 管理工具;




内核组成 :


-- 中断 : 响应中断的中断服务程序;


-- 调度 : 管理进程间调度的程序, 主要是调度 CPU 执行时间;


-- 内存 : 内存管理模块;


-- 通信 : 网络 进程间通信模块;




内核提供的保护机制 :


-- 系统态 : 能访问所有的内存空间 和 硬件设备, 用户态不能访问的空间是内核空间;


-- 用户态 : 只允许使用部分硬件资源的部分功能, 只能访问内核分配的内存;






(2)  系统调用



系统调用 : 应用程序 通过 系统调用 与内核通信;


-- 调用过程 : 一般先调用 库函数, 在通过库函数 调用内核方法;




库函数与系统调用关系 :


-- 系统调用是库函数的一部份 : 有的库函数需要多个系统调用来完成;


-- 一一对应 : 有的库函数 与 系统调用是一一对应的关系, 这种情况下, 相当与应用程序直接在内核运行, 即陷入内核;






(3) 硬件设备管理 和 中断



设备与内核通信过程 :


-- a. 打断内核 : 先发出异步中断信号, 打断处理器当前操作, 打断内核操作;


-- b. 查找中断 : 内核根据中断号查找中断服务程序, 调用程序的中断处理函数;


-- c. 中断示例 : 在编辑器中滑动鼠标滚轮, 鼠标会发出一个中断信号给内核, 鼠标的缓冲区有数据出现, 内核查找到中断来自鼠标, 调用中断处理程序, 执行想要的操作;




中断程序简介 :


-- 内核作用 : 执行哪个中断需要依靠内核来判断;


-- 中断运行环境 : 中断程序在一个与进程无关的, 专门用于运行中断处理程序的空间中执行, 这样做能保证在第一时间响应中断处理请求;




CPU的三个操作 : 每个 CPU 必定是三个中的一个;


-- 用户 进程 : 在用户空间, 执行用户进程;


-- 内核 进程 : 在内核空间, 处于进程上下文, 执行进程相关操作;


-- 内核 中断 : 在内核空间, 处于中断上下文, 处理中断;






(4) 内核划分



内核划分 : 内核是个很大的可执行文件, 会处理很多请求, 内核维持这几个并发的进程, 每个进程都会请求系统资源, 如 内存, 网络 CPU 等;


-- 进程管理 : 负责创建 销毁进程, 处理进程的输入输出, 以及进程间的交互;


-- 内存管理 : 内核的多个模块 与 内存管理系统通过一套函数进行交互操作;


-- 文件系统 : 内核在非结构化的硬件上建立起一套结构化的文件系统, Linux 支持多个文件系统, ext 是标准的文件系统;


-- 设备控制 : 每个操作系统都要映射到一个物理设备上, 内核中需要包含所有的驱动;


-- 网络控制 : 网络是由操作系统进行控制的, 其消息一般是异步的;






(5) 用户空间 和 内核空间



用户空间 : 权限较低的空间, 该空间对 设备 和 内存的访问都会受到限制;




内核空间 : 权限最高, 该空间可以执行任何操作, 可以访问所有的设备 和 内存空间;




用户空间转到内核空间 : 应用程序发出一个系统调用 或者 被硬件中断挂起的时候, 会从用户空间转到内核空间;






(6) 内核模块



模块特点 :


-- 注册 : 模块需要预先注册, 才能进行动态加载;


-- 功能 : 模块实现驱动程序, 文件系统等功能;


-- 加载 : 加载之后模块运行于内核空间, 与内核组成一体;




模块相关函数 :


-- init_module : 加载模块时调用, 预先准备模块中的函数和变量;


-- cleanup_module : 模块卸载前调用;




模块相关命令 :


-- insmod : 加载模块, 格式 insmod file_name ;


-- rmmod : 卸载模块, 格式 rmmod file_name ;


-- lsmod : 列出当前使用的模块, 或者查看 /proc/modules 目录;


-- modprobe : 探测并加载内核模块, 给出模块名称, 自动寻找加载模块, 与 insmod 命令的不同之处是可以自动寻找依赖的模块;


-- depmod : 给模块生成依赖文件, 生成 /lib/modules/3.11.0-15-generic 文件;






2. Linux 与 UNIX 内核 对比



UNIX 内核运行状况 : UNIX 内核是一个 不可分割的静态可执行库, 其运行的时候 必须在一个 单独的地址空间中运行 这个可执行块;




Linux UNIX 内存管理比较 : MMU 方面;


-- UNIX 内存管理 : UNIX 必须有 MMU (Memory Management Unit 内存管理单元) 页机制, 该页机制加强对内存保护, 每个进程运行在不用的虚拟地址上;


-- Linux 内存管理 : Linux 可以运行在没有 MMU 的系统上;




单内核 : 从整体上将内核作为一个单独的过程来实现, 运行在一个单独的地址空间中;


-- 内核间服务通信 : 所有的内核服务都运行在同一空间, 可以直接互相调用;


-- 特点 : 该设计使系统简单, 性能比较高;


-- 但内核系统 : 多数的 UNIX 系统, Linux 系统;




微内核(设计) : 内核的功能分为多个独立过程, 每个过程叫做服务器, 所有的服务器都运行在独立空间中;


-- 服务器运行空间 : 只有一部份服务器能运行在内核空间中, 其它的服务器在用户空间中运行;


-- 服务器间消息传递 : 采用 进程间通信 IPC 机制, 内核的各个服务器通过 IPC 机制进行通信;


-- 服务器空间切换 : 在用户空间运行的服务器可以切换到内核空间运行;




微内核的一些设计缺陷 :


-- 开销大 : 微内核的 IPC 进程间通信开销很大, 比函数调用要多;


-- 上下文切换 : 运行在 内核空间 和 用户空间的 服务器之间进行切换需要时间;




实际实施的微内核 :


-- 服务器位置 : 多数的服务器位于内核空间, 服务器之间可以相互进行函数调用, 尽量避免使用 IPC 机制 和 上下文切换;


-- 微内核系统 : Windows 和 Mac OS;




Linux 内核设计 : 模块化的 多线程 以及内核可调度;


-- 运行空间 : Linux 内核是单内核, 运行在内核空间, 直接调用函数, 无需 IPC 消息传递;


-- 吸取的微内核的精华 : 模块化设计, 抢占式内核, 支持内核线程, 动态装载内核模块;




Linux 与 UNIX 差异 :


-- 对动态加载模块的支持 : Linux 在需要的时候 动态卸载 和 加载部分内核代码, UNIX 内核是不可分割的可执行库;


-- 对 SMP 机制的支持 : SMP (Symmetric Multi-Processing) 对称多处理机制, 多 CPU 机器上 各 CPU 共享内核和总线资源, Linux 支持, 传统 UNIX 不支持;  


-- 对抢占支持 : Linux 内核允许在内核执行任务的时候, 优先执行一些任务; 多数 UNIX 不支持;


-- 对线程支持 : Linux 内核不区分线程和进程, 所有的进程对与内核都是一样的;






二. 下载 配置 编译内核源码





1. 下载内核源码





(1) 从官网下载内核



内核官网 : https://www.kernel.org/ ;


-- 2.6 最稳定版下载地址 : https://www.kernel.org/pub/linux/kernel/v2.6/longterm/v2.6.32/linux-2.6.32.63.tar.xz ;


-- 3.16.1 最新的稳定版本内核地址 : https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.16.1.tar.xz ;


-- 3.14.17 最新内核下载地址(不稳顶) : https://www.kernel.org/pub/linux/kernel/v3.x/testing/linux-3.17-rc1.tar.xz ;




tar.xz 压缩文件解压方法 : tar -xvJf linux-2.6.32.63.tar.xz ;






(2) 使用 Git 下载



Git下载地址 : git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git ;


-- 下载代码命令 : git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git;


-- 提交代码命令 : git pull;


-- 下载过程 :



octopus@octopus:~/develop/git/linux_kernel$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Cloning into 'linux-2.6'...
remote: Counting objects: 3754628, done.
remote: Compressing objects: 100% (566292/566292), done.
remote: Total 3754628 (delta 3165631), reused 3747365 (delta 3158382)
Receiving objects: 100% (3754628/3754628), 793.85 MiB | 435 KiB/s, done.
Resolving deltas: 100% (3165631/3165631), done.




2. 内核源码树介绍



Ubuntu 内核源码地址 : /usr/src/linux-headers-3.11.0-15 ;


-- Ubuntu 内核源码目录 :



root@octopus:/usr/src/linux-headers-3.11.0-15# ls
arch   crypto         drivers   fs       init  Kbuild   kernel  Makefile  net      scripts   sound  ubuntu  virt
block  Documentation  firmware  include  ipc   Kconfig  lib     mm        samples  security  tools  usr

标准Linux内核 :

-- 2.6 最稳定版内核 : linux-2.6.32.63.tar.xz, 解压命令 tar -xvJf linux-2.6.32.63.tar.xz ;


-- 内核目录 :



octopus@octopus:~/uplooking/kernel/linux-2.6.32.63$ ls
arch     CREDITS        drivers   include  Kbuild  MAINTAINERS  net             samples   sound  virt
block    crypto         firmware  init     kernel  Makefile     README          scripts   tools
COPYING  Documentation  fs        ipc      lib     mm           REPORTING-BUGS  security  usr

内核目录文件解析 :

-- arch : 特定体系结构源码, 这里为 x86 arm 不同型号的 cpu 准备了不同的源码;


-- block : 块设备相关 I/O 层;


-- crypto : 加密相关的 api;


-- Documention : 内核源码文档;


-- drivers : 设备驱动程序;


-- firmware : 使用驱动程序需要的设备固件;


-- fs : 文件系统;


-- including : 内核头文件;


-- init : 内核引导和初始化;


-- ipc : 进程通信代码;


-- kernel : 内核的核心系统;


-- lib : 通用的内核函数;


-- mm : 内存管理模块;


-- net : 网络系统模块;


-- sample : 示例代码;


-- scripts : 编译内核的脚本;


-- security : 安全模块;


-- sound : 语音模块;


-- usr : 用户空间代码;


-- tools : Linux 工具;


-- virt : 虚拟化基础结构;




文件介绍 :


-- COPYING : 内核许可证;


-- CREDITS : 内核开发者列表;


-- MAINTAINERS : 维护者列表;


-- Makefile : make 编译脚本;






3. 内核配置





(1) 命令行配置



使用 make config 命令 : 该命令会逐一遍历所有配置项, 用户自己选择 yes(y) no(N) module(?), 所需时间很长;


-- 配置详情 :



octopus@octopus:~/uplooking/kernel/linux-2.6.32.63$ make config
scripts/kconfig/conf arch/x86/Kconfig
*
* Linux Kernel Configuration
*
*
* General setup
*
Prompt for development and/or incomplete code/drivers (EXPERIMENTAL) [N/y/?]




(2) 使用图形界面



使用 make menuconfig 命令 :


-- 图形界面 :







(3) make menu 配置解析



配置保存文件 : make menu 图形界面保存的配置文件是在根目录下的 .config 文件, 该文件中保存这 一个个的键值对;


-- 配置文件内容 :



#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.32.63
# Mon Aug 18 17:17:46 2014
#
# CONFIG_64BIT is not set
CONFIG_X86_32=y
# CONFIG_X86_64 is not set
CONFIG_X86=y
CONFIG_OUTPUT_FORMAT="elf32-i386"
CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig"
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_CLOCKSOURCE_WATCHDOG=y
CONFIG_GENERIC_CLOCKEVENTS=y
Kconfig 中变量解析 : 
-- tristate : 能取值 y, n 和 m, 对应配置界面中的 <>;
-- bool : 是 tristate 的一种, 只能取值 y 和 n, 对应配置界面的 [];
-- string : 取值字符串;
-- hex : string 的一种, 取值十六进制数;
-- int : string 的一种, 取值十进制数;




显示详细配置解析 : 在 menuconfig 中将光标停在配置项, 然后按下 ? 键, 即可弹出详细配置信息;


-- 示例图片 : 其中说明了该配置项作用, 以及配置文件位置, 该配置项的位置在 /arch/Kconfig 中的第 5 行;




-- 配置代码 :



config OPROFILE
  tristate "OProfile system profiling (EXPERIMENTAL)"
  depends on PROFILING
  depends on HAVE_OPROFILE
  select RING_BUFFER
  select RING_BUFFER_ALLOW_SWAP
  help
   OProfile is a profiling system capable of profiling the
   whole system, include the kernel, kernel modules, libraries,
   and applications.
   If unsure, say N.


Kconfig 中的配置解析 :


-- config : 变量名;


-- tristate : menuconfig 界面中显示的选项名称;


-- default : 默认值;


-- depends on : 依赖哪些变量;


-- select : 选择变量;


-- help : 帮助信息, menuconfig 中光标移动到选项上, 点击 ? 显示的信息;




Makefile 对 .config 的依赖 :


a. obj-$(CONFIG_PLIP) + = plip.o 选项 : CONFIG_PLIP 这个选项定义在 .config 文件中;


-- CONFIG_PLIP=y : 那么将编译本目录下的 plip.c 文件并将其功能集成进 zimage;


-- CONFIG_PLIP=n : 不编译;


-- CONFIG_PLIP=m : 那么将编译本目录下的 plip.c 文件生成模块 plip.ko;




b. obj-$(CONFIG_GIANFAR) + = gianfar_driver.o 选项 :


-- CONFIG_GIANFAR = y : 编译本目录下的 ianfar.c,gianfar_ethtool.c,gianfar_mii.c,gianfar_sysfs.c 文件并将其功能集成进 zimage;


-- CONFIG_GIANFAR = n : 不编译;


-- CONFIG_GIANFAR = m : 以上文件生成模块gianfar_driver.ko;




c. obj-$(CONFIG_ATL1) + = atl1 选项 :


-- CONFIG_ATL1 = y : 递归进入本目录的字目录 atl1, 并根据该子目录下的 Makefile 文件的内容决定该子目录如何进行编译;


-- 其它状况 : 不编译;





目录
相关文章
|
10天前
|
Linux 数据安全/隐私保护
适用于 Linux 的最佳命令行下载加速器
适用于 Linux 的最佳命令行下载加速器
30 3
|
5天前
|
缓存 资源调度 安全
深入探索Linux操作系统的心脏——内核配置与优化####
本文作为一篇技术性深度解析文章,旨在引领读者踏上一场揭秘Linux内核配置与优化的奇妙之旅。不同于传统的摘要概述,本文将以实战为导向,直接跳入核心内容,探讨如何通过精细调整内核参数来提升系统性能、增强安全性及实现资源高效利用。从基础概念到高级技巧,逐步揭示那些隐藏在命令行背后的强大功能,为系统管理员和高级用户打开一扇通往极致性能与定制化体验的大门。 --- ###
24 9
|
7天前
|
存储 安全 数据管理
如何在 Rocky Linux 8 上安装和配置 Elasticsearch
本文详细介绍了在 Rocky Linux 8 上安装和配置 Elasticsearch 的步骤,包括添加仓库、安装 Elasticsearch、配置文件修改、设置内存和文件描述符、启动和验证 Elasticsearch,以及常见问题的解决方法。通过这些步骤,你可以快速搭建起这个强大的分布式搜索和分析引擎。
18 5
|
21天前
|
Java Linux 网络安全
NIFI在Linux服务区上的部署配置过程是什么?
【10月更文挑战第21天】NIFI在Linux服务区上的部署配置过程是什么?
38 2
|
29天前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
81 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
1月前
|
Linux 编译器 C语言
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
|
1月前
|
Ubuntu Linux 编译器
Linux/Ubuntu下使用VS Code配置C/C++项目环境调用OpenCV
通过以上步骤,您已经成功在Ubuntu系统下的VS Code中配置了C/C++项目环境,并能够调用OpenCV库进行开发。请确保每一步都按照您的系统实际情况进行适当调整。
260 3
|
15天前
|
Linux
Linux - 如何编译源码安装软件
源码编译安装通常包括三个步骤:1) `./configure` 检测平台特征和依赖项,生成 Makefile;2) `make` 编译源码,生成可执行文件;3) `make install` 将可执行文件安装到指定目录并配置环境变量。
30 0
|
1月前
|
Linux 编译器 C语言
Linux c/c++之多文档编译
这篇文章介绍了在Linux操作系统下使用gcc编译器进行C/C++多文件编译的方法和步骤。
39 0
Linux c/c++之多文档编译
|
1月前
|
Linux 开发工具
【Linux快速入门(二)】Linux与ROS学习之编译基础(make编译)
【Linux快速入门(二)】Linux与ROS学习之编译基础(make编译)