Linux内核编译流程
删除之前编译生成的文件和配置文件
make mrproper
生成.config文件
make menuconfig
编译
make -j4
1. No rule to make target ‘debian/canonical-certs.pem‘, needed by ‘certs/x509_certificate_list‘
vim .config
修改CONFIG_SYSTEM_TRUSTED_KEYS为""
修改CONFIG_SYSTEM_REVOCATION_KEYS为""
2.BTF: .tmp_vmlinux.btf: pahole (pahole) is not available Failed to generate BTF for vmlinux
sudo apt install linux-tools-common
编辑.config文件,将CONFIG_DEBUG_INFO_BTF设置为n
后续
root@100ask:/home/book/Downloads/linux-5.19/arch/x86/boot# file bzImage
bzImage: Linux kernel x86 boot executable bzImage, version 5.19.0 (root@100ask) #2 SMP PREEMPT_DYNAMIC Wed Aug 2 09:35:26 EDT 2023, RO-rootFS, swap_dev 0xA, Normal VGA
- 编译busybox
make menuconfig
勾选 Build static binary 生成静态链接的busybox二进制文件再make -j4进行编译
- 安装
make install
会安装在当前busybox目录的_install目录下
- 制作initramfs.img
写如下Makefile文件:initramfs:cd ./initramfs_dir && find . -print0 | cpio -ov --null --format=newc | gzip -9 > ../initramfs.imgrun:qemu-system-x86_64 \-kernel bzImage \-initrd initramfs.img \-m 512M \-nographic \-append "earlyprintk=serial,ttyS0 console=ttyS0"
在启动Linux时,会执行以下步骤:
1.引导加载器加载内核映像(这里是bzImage)
2.内核加载并挂载根文件系统启动init进程
3.init进程使用根文件系统下的/init脚本来继续启动系统
root@100ask:/home/book/linux-demo#下
执行make initramfs即可生成根文件系统的映像文件initramfs.img
执行make run就会启动qemu虚拟机
-
/init脚本
#!/bin/busybox sh/bin/busybox mkdir -p /proc && /bin/busybox mount -t proc none /proc /bin/busybox echo "Hello"/bin/busybox sh -
文件结构
├── bzImage
├── initramfs_dir
│ ├── bin
│ │ └── busybox
│ └── init
├── initramfs.img
└── Makefile -
使用
root@100ask:/home/book/Downloads/busybox-1.36.1/_install/bin# busybox echo 123 123 -
退出:ctrl+a,then press x
-
将内核中的proc文件系统挂载到/proc文件夹,这样就可以通过访问/proc下的文件和目录,获取到与内核和系统相关的信息
-
显示进程
init中加入下面这行:/bin/busybox mkdir -p /proc && /bin/busybox mount -t proc none /proc这样执行busybox ps就可以显示进程了
-
修改shell提示符
加一行 export $PS1='(kernel) =>'
文件系统
文件系统常用格式:ext2、yaffs2
内存文件系统:ramdisk:用内存模拟块设备,并格式化为文件系统格式ramfs:利用linux会把块设备的数据缓存到内存中的机制实现,不会将数据写回到存储设备tmpfs:tmpfs是ramfs的衍生物,有容量大小限制、允许向交换空间(swap) 写入数据
内核早期启动的临时根文件系统:initramfs:
linux最终使用的完整的文件系统:rootfs:是ramfs和tmpfs的一个实现,包含系统所有基本文件和目录,是完整的Linux文件系统
内核在启动初始化过程中会解压缩initrd文件,然后将解压后的initrd挂载为根目录,然后执行根目录中的/init脚本,您就可以在这个脚本中运行initrd文件系统中的内核模块自动加载机制udevd,让它来自动加载realfs(真实文件系统)存放设备的驱动程序,以及在/dev目录下建立必要的设备节点。在udevd自动加载磁盘驱动程序之后,就可以mount真正的根目录,并切换到这个根目录中来。
详细描述
initfd和initramfs
- initrd:有image格式和cpio格式。基于ramdisk的小型根目录,包含启动阶段中需要的文件和脚本,会在系统启动时被读入到内存,执行其中的/init脚本。
为了精简内核代码,将加载各种设备驱动和模块的代码写在init脚本中,放在大小固定大小的块设备上,放在用户态来做。
由于其基于块设备,因此需要内核有文件系统驱动 - initramfs:本质上是cpio格式的initrd
initramfs是initrd的继承者,都用来做一些内核不容易做的事情,比如挂载文件系统、加载模块等
怎样在linux中添加一个系统调用
下面以获得cpu个数为例:
- 在arch/x86/entry/syscalls/syscall_64.tbl中注册系统调用号
451 common get_cpu_number sys_get_cpu_number - 在include/linux/syscalls.h中声明系统调用函数
asmlinkage long sys_get_cpu_number(void); - 在kernel/sys.c中实现系统调用函数
SYSCALL_DEFINE0(get_cpu_number) {return num_present_cpus(); } - 然后重新编译linux内核(使用默认配置即可)
- 测试程序get_cpu.c:
结构和之前的linux-demo类似,只是bzImage是重新编译内核生成的#include <sys/syscall.h>int main() {int cpu_numbers= syscall(451);return 0; }
├── get_cpu.c 测试程序
├── bzImage 编译内核生成的镜像
├── initramfs_dir 目录
│ ├── bin 目录
│ │ └── busybox 编译busybox生成的可执行文件
│ └── get_cpu 可执行文件
│ └── init 脚本文件
├── initramfs.img 执行Makefile下的make initramfs会生成该镜像文件
└── Makefile 也和linux-demo中写的一样
执行gcc -static get_cpu.c -o get_cpu生成静态可执行文件,所有的依赖库都会被静态链接到可执行文件中,从而使可执行文件在其他系统上运行时不需要依赖动态库
qemu的按键驱动程序
-
编译内核
我的linux内核目录为~/100ask_imx6ull-qemu/linux-4.9.88-
设置环境变量
export ARCH=arm export CROSS_COMPILE=arm-linux-gnueabihf- -
生成.config文件 make menuconfig
为避免后期报错:button_drv: version magic '4.9.88-g8f6c88de SMP mod_unload modversions ARMv7 p2v8 ’ should be '4.9.88-g8f6c88de SMP preempt mod_unload modversions ARMv7 p2v8 ',要做如下设置
编译内核时使用抢占式模型,需要设置Kernel Features -> Preemption Model为Preemptible Kernel (Low-Latency Desktop)
-
make -j4
-
修改内核源码的version magic
为避免加载的驱动所使用的内核版本和系统运行的版本不一致,导致后期报错:Unknown symbol __gnu_mcount_nc
打开内核include/generated/utsrelease.h文件,修改version magic为开发板的版本。
#define UTS_RELEASE "4.9.88-g8f6c88de"
-
-
编译按键驱动程序
-
在Makefile中指定内核路径KERN_DIR
KERN_DIR = /home/book/100ask_imx6ull-qemu/linux-4.9.88 all:make -C $(KERN_DIR) M=`pwd` modules$(CROSS_COMPILE)gcc -o button_test button_test.c clean:make -C $(KERN_DIR) M=`pwd` modules cleanrm -rf modules.orderrm -f ledtest obj-m += button_drv.o obj-m += board_100ask_imx6ull-qemu.o -
make编译,然后将ko文件和程序复制到nfs文件夹
cp *.ko button_test /home/book/nfs_rootfs/
-
-
启动qemu,挂载nfs
mount -t nfs -o nolock,vers=3 10.0.2.2:/home/book/nfs_rootfs /mnt -
安装模块
insmod button_drv.ko
insmod board_100ask_imx6ull-qemu.ko -
查看内核日志
dmesg | grep hello
相关文章:
Linux内核编译流程
删除之前编译生成的文件和配置文件 make mrproper生成.config文件 make menuconfig编译 make -j41. No rule to make target ‘debian/canonical-certs.pem‘, needed by ‘certs/x509_certificate_list‘ vim .config 修改CONFIG_SYSTEM_TRUSTED_KEYS为"" 修改C…...
昇思25天学习打卡营第2天 | 张量Tensor
张量Tensor 张量(Tensor)基础 张量是MindSpore中的基本数据结构的一种,类似于NumPy中数组和矩阵非常相似。它具有以下重要属性: 形状(shape)和数据类型(dtype):每个张量…...
时间安排 |规划
计算机网络(记得完成作业本上的习题) 先看王道知识点讲解 然后不懂得看 计算机网络微课堂(有字幕无背景音乐版)_哔哩哔哩_bilibili 最后做本章习题 【乱讲的】《计算机网络》(第8版)课后习题讲解_哔哩…...
PS系统教程28
Alpha通道(透明通道) 8位的灰度通道,也有256个位置记录图片当中的透明度信息 作用:定义透明、半透明、不透明通道信息。保存、存储选区。 白色不透明区域黑色透明区域灰色半透明区域 案例 为了将我们抠出来的人物方便下次修改…...
如何在web页面下做自动化测试?
自动化测试是在软件开发中非常重要的一环,它可以提高测试效率并减少错误率。在web页面下进行自动化测试,可以帮助我们验证网页的功能和交互,并确保它们在不同浏览器和平台上的一致性。本文将从零开始,详细介绍如何在web页面下进行…...
spring源码环境的搭建
为什么要编译spring源码 为了高效调试Spring源码、验证个人猜想,并从开发者的视角深化理解,编译自定义的Spring源码版本显得尤为重要。这样可以避免因缺乏预编译版本而带来的不便,并允许直接在源码上进行注释或修改,以记录学习心…...
小山菌_代码随想录算法训练营第三十四天| 56. 合并区间、
56. 合并区间 文档讲解:代码随想录.合并区间 视频讲解:贪心算法,合并区间有细节!LeetCode:56.合并区间 状态:已完成 代码实现 class Solution { public:vector<vector<int>> merge(vector<…...
让工厂像手机一样更“聪明”
手机,作为我们日常生活中不可或缺的一部分,以其智能、便捷、高效的特点,彻底改变了我们的沟通、娱乐和工作方式。那么,想象一下,如果工厂能像手机一样便捷,那么生产过程中的每一个环节都将变得触手可及。通…...
vue2与vue3数据响应式对比之检测变化
vue2 由于javascript限制,vue不能检测数组和对象的变化 什么意思呢,举例子来说吧 深入响应式原理 对象 比如说我们在data里面定义了一个info的对象 <template><div id"app"><div>姓名: {{ info.name }}</div><…...
Spring Cloud - 开发环境搭建
1、JDK环境安装 1、下载jdk17:下载地址,在下图中红色框部分进行下载 2、双击安装,基本都是下一步直到完成。 3、设置系统环境变量:参考 4、设置JAVA_HOME环境变量 5、在PATH中添加%JAVA_HOME%/bin 6、在命令行中执行:j…...
绘制图形
自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在前3节的实例中,我们一直绘制的都是直线,实际上,海龟绘图还可以绘制其他形状的图形,如圆形、多边形等…...
SpringAop实战(xml文件/纯注解两种方式)
AOP的概述 什么是AOP? 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程 • AOP是一种编程范式,隶属于软工范畴,指导开发者如何组织程序结构 • AOP最早由AOP联盟的组织提出的,制定了…...
(八)Linux的进程与线程
多任务处理是指用户可以在同一时间内运行多个应用程序,每个正在执行的程序被称为一个任务。一个任务包含一个或多个完成独立功能的子任务,其中子任务可以是进程或线程。Linux就是一个支持多任务的操作系统,比起单任务系统它的功能增强许多。 一.进程 进程:一个具有独立功…...
Map-JAVA面试常问
1.HashMap底层实现 底层实现在jdk1.7和jdk1.8是不一样的 jdk1.7采用数组加链表的方式实现 jdk1.8采用数组加链表或者红黑树实现 HashMap中每个元素称之为一个哈希桶(bucket),哈希桶包含的内容有以下4项 hash值(哈希函数计算出来的值) Key value next(…...
prometheus+grafana搭建监控系统
1.prometheus服务端安装 1.1下载包 使用wget下载 (也可以直接去官网下载包Download | Prometheus) wget https://github.com/prometheus/prometheus/releases/download/v2.44.0/prometheus-2.44.0.linux-amd64.tar.gz1.2解压 tar xf prometheus-2.44…...
flink学习-flink sql
动态表 在flink的数据处理中,数据流是源源不断的,是无界的,所以对于flink处理的数据表是一张动态表,所以对于动态表的查询也是持续的,每接收一条新数据会进行一次新的查询。 持续查询 因为数据在一直源源不动的到来…...
高考填报志愿攻略,5个步骤选专业和院校
在高考完毕出成绩的时候,很多人会陷入迷茫中,好像努力了这么多年,却不知道怎么规划好未来。怎么填报志愿合适?在填报志愿方面有几个内容需要弄清楚,按部就班就能找到方向,一起来了解一下正确的步骤吧。 第…...
Kubernetes排错(十)-处理容器数据磁盘被写满
容器数据磁盘被写满造成的危害: 不能创建 Pod (一直 ContainerCreating)不能删除 Pod (一直 Terminating)无法 exec 到容器 如何判断是否被写满? 容器数据目录大多会单独挂数据盘,路径一般是 /var/lib/docker,也可能是 /data/docker 或 /o…...
使用QtGui显示QImage的几种方法
问题描述 我是一名刚学习Qt的新手,正在尝试创建一个简单的GUI应用程序。当点击一个按钮时,显示一张图片。我可以使用QImage对象读取图片,但是否有简单的方法调用一个Qt函数,将QImage作为输入并显示它? 方法一:使用QLabel显示QImage 最简单的方式是将QImage添加到QLabe…...
C++ lamda
1 lamada 的函数指针存在哪里?需要通过分析编译后的二进制; 2 捕获了什么? 为什么捕获?捕获的范围是什么? 捕获的生命周期是什么? lambda 定义匿名函数,使得代码更加灵活简洁; lam…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
