ARM64 Trust Firmware [一]
ARMv8 启动流程:
在《RK3568上电启动流程 [十五]》中,简单介绍了 RK3568 的上电启动过程,本篇再详细分解其启动流程。
在 ARMv8 架构中,启动流程包含多个阶段,这些阶段被称为 BL (bootloader) 阶段:
- BL1:第一阶段启动固件,在 RK3568 中位于 BootRom 中,负责引导 BL2 并对其进行安全验证;
- BL2:第二阶段启动固件,在 RK3568 中位于 Flash 中(比如 eMMC),负责平台相关的初始化,比如 DRAM 的初始化,并负责加载 BL31 并执行 BL31,在 RK3568 中就是我们的 miniloader.bin;
- BL31:也就是 trust Runtime firmware,BL31 是持久存在的可信固件,负责系统安全服务和在安全非非安全世界之间切换;
- BL32:包含 TEE OS 和安全应用 TAs,运行在 EL1,启动 EL0 的安全应用,完成后返回 BL31;
- BL33:非安全世界的启动固件,通常就是 U-Boot 或者直接启动 Linux 内核;
在 RK3568 中其启动全流程的输出如下:
在支持 ATF 的 ARMv8 中完整的镜像跳转流程如下:
ATF 编译和 uboot image 打包:
为了学习 ATMv8 Trust Firmware,最好的方法就是将开源的 ATF 编译,并在 RK3568 上跑起来,通过打印,调试去理解其工作机制。但是Upstream ARM Trusted Firmware 是不支持 RK3568 的,Rockchip 只提供了官方的 trust bin 文件(ATF - Rockchip open source Document)。但是最后发现在arm-trusted-firmware 的v2.12 版本中还是存在 RK3568 的 Platform,因此用 v2.12 来编译生成 bl31.elf,并将其打包进 uboot.img 中(后来发现该 bl31.elf 会导致 Linux 在初始化 SCMI 时失败,但是先不管了,至少我们可以有源码,并且能够编译和实现初步的运行)。
ATF 的编译:
git clone https://github.com/ARM-software/arm-trusted-firmware.gitcd arm-trusted-firmware
git checkout v2.12.0
make CROSS_COMPILE=aarch64-linux-gnu- PLAT=rk3568
将编译生成的 bl31.elf 拷贝到 u-boot 目录下。
uboot 使用 FIT Image 格式,所以我们需要先生成 u-boot.its,再使用 mkimage 工具根据 u-boot.its 文件做成 uboot.itb
uboot.its 如下:这里我将 OPTEE 的分支删除了,因为我们目前不需要研究 TEE OS。
/** Copyright (C) 2020 Rockchip Electronic Co.,Ltd** Simple U-boot fit source file containing ATF/OP-TEE/U-Boot/dtb/MCU*//dts-v1/;/ {description = "CXJ FIT Image with ATF/OP-TEE/U-Boot/MCU";#address-cells = <1>;images {uboot {description = "U-Boot";data = /incbin/("u-boot-nodtb.bin.gz");type = "standalone";arch = "arm64";os = "U-Boot";compression = "gzip";load = <0x00a00000>;digest {value = /incbin/("./u-boot-nodtb.bin.digest");algo = "sha256";};hash {algo = "sha256";};};atf-1 {description = "ARM Trusted Firmware";data = /incbin/("./bl31_0x00040000.bin.gz");type = "firmware";arch = "arm64";os = "arm-trusted-firmware";compression = "gzip";load = <0x00040000>;hash {algo = "sha256";};digest {value = /incbin/("./bl31_0x00040000.bin.digest");algo = "sha256";};};atf-2 {description = "ARM Trusted Firmware";data = /incbin/("./bl31_0xfdcd0000.bin");type = "firmware";arch = "arm64";os = "arm-trusted-firmware";compression = "none";load = <0xfdcd0000>;hash {algo = "sha256";};};fdt {description = "U-Boot dtb";data = /incbin/("./u-boot.dtb");type = "flat_dt";arch = "arm64";compression = "none";hash {algo = "sha256";};};};configurations {default = "conf";conf {description = "rk3568-evb";rollback-index = <0x0>;firmware = "atf-1";loadables = "uboot", "atf-2";fdt = "fdt";signature {algo = "sha256,rsa2048";key-name-hint = "dev";sign-images = "firmware", "loadables", "fdt";};};};
};
再使用 mkimage 生成 u-boot.itb:
./tools/mkimage -f u-boot.its -E uboot.itb
通过 fdtdump 我们可以看到 uboot img 包含的内容:
cuixujia.cxj@localhost:~/workspace/luban/LubanCat_SDK/u-boot$ fdtdump uboot.itb**** fdtdump is a low-level debugging tool, not meant for general use.
**** If you want to decompile a dtb, you probably want
**** dtc -I dtb -O dts <filename>/dts-v1/;
// magic: 0xd00dfeed
// totalsize: 0x72f (1839)
// off_dt_struct: 0x38
// off_dt_strings: 0x66c
// off_mem_rsvmap: 0x28
// version: 17
// last_comp_version: 16
// boot_cpuid_phys: 0x0
// size_dt_strings: 0xc3
// size_dt_struct: 0x634/ {version = <0x00000000>;totalsize = <0x00095f0d>;timestamp = <0x67adacea>;description = "CXJ FIT Image with ATF/OP-TEE/U-Boot/MCU";#address-cells = <0x00000001>;......
重新烧录uboot.itb,重启后,我们可以看到系统可以成功加载 atf,uboot:
Trying fit image at 0x4000 sector
## Verified-boot: 0
## Checking atf-1 0x00040000 (gzip @0x00240000) ... sha256(3a0e0e29a2...) + sha256(cb9e165ab3...) + OK
## Checking uboot 0x00a00000 (gzip @0x00c00000) ... sha256(69d1989cfb...) + sha256(5f44711400...) + OK
## Checking fdt 0x00b4b478 ... sha256(a474c6bb61...) + OK
## Checking atf-2 0xfdcd0000 ... sha256(e25f5f200c...) + OK
Jumping to U-Boot(0x00a00000) via ARM Trusted Firmware(0x00040000)
Total: 133.134/203.236 msNOTICE: BL31: v2.12.0(release):v2.12.0
NOTICE: BL31: Built : 10:51:56, Feb 13 2025
NOTICE: BL31: Rockchip release version: v1.0
usb dr_mode not found
usb dr_mode not foundU-Boot 2017.09-dirty #cuixujia.cxj (Feb 13 2025 - 16:21:38 +0800)Model: Rockchip RK3568 Evaluation Board
但是在 Linux bringup 过程中 hang 住了,由于开源 ATF 对 RK3568 支持不足,怀疑是在 SCMI 这块的支持有问题:
[ 3.068424] usbcore: registered new interface driver usbfs
[ 3.068510] usbcore: registered new interface driver hub
[ 3.068578] usbcore: registered new device driver usb
[ 3.069218] mc: Linux media interface: v0.10
[ 3.069293] videodev: Linux video capture interface: v2.00
[ 3.069435] pps_core: LinuxPPS API ver. 1 registered
[ 3.069459] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 3.069501] PTP clock support registered
[ 3.069575] EDAC MC: Ver: 3.0.0
[ 3.070837] arm-scmi firmware:scmi: SCMI Notifications - Core Enabled.
关于 FIT Image:
FIT(Flattened image tree)UImage,FIT 和 FDT 比较类似,利用的语法都是 Device Tree Source files 语法,生成的 image 文件也和 dtb 文件基本一样。
FIT uImage 的生成流程可以概括如下:
以 u-boot.its 的 uboot 节点为例,简述一下 its 的 语法结构:
images {uboot {description = "U-Boot";data = /incbin/("u-boot-nodtb.bin.gz");type = "standalone";arch = "arm64";os = "U-Boot";compression = "gzip";load = <0x00a00000>;digest {value = /incbin/("./u-boot-nodtb.bin.digest");algo = "sha256";};hash {algo = "sha256";};};
- description:子镜像文本的描述,可以随便写;
- data:包含该节点二进制文件的路径;
- type:子镜像类型;
- compression:压缩方法,比如 gzip,bzip2 等;
- load:二进制文件的内存加载位置;
- hash:镜像使用的校验算法,如 sha256,crc32 等;
相关文章:
ARM64 Trust Firmware [一]
ARMv8 启动流程: 在《RK3568上电启动流程 [十五]》中,简单介绍了 RK3568 的上电启动过程,本篇再详细分解其启动流程。 在 ARMv8 架构中,启动流程包含多个阶段,这些阶段被称为 BL (bootloader) …...
K8S容器启动提示:0/2 nodes are available: 2 Insufficient cpu.
问题:K8S的容器启动报错0/2 nodes are available: 2 Insufficient cpu. 原因:Pod的资源请求(requests)设置不当:在Kubernetes中,调度器根据Pod的requests字段来决定哪个节点可以运行该Pod。如果一个Pod声明…...
数据结构:图论入门
图论起源于欧拉对哥尼斯堡七桥问题的解决. 他构建的图模型将陆地用点来表示, 桥梁则用线表示, 如此一来, 该问题便转化为在图中能否不重复地遍历每条边的问题. 图论的应用 地图着色 在地图着色问题中, 我们用顶点代表国家, 将相邻国家之间用边相连. 这样, 问题就转化为用最少…...
DataBase【MySQL基础夯实使用说明(下)】
MySQL数据库 🏆当领导表示关心时,您怎么回复? ⚠️不要傻傻的说应该的,这样不仅会抹杀掉你的辛苦,也让领导没办法接话! 🔔文章末尾彩蛋! 文章目录 MySQL数据库前言一、约束1.1.外键…...
Golang的多团队协作编程模式与实践经验
Golang的多团队协作编程模式与实践经验 一、多团队协作编程模式概述 在软件开发领域,多团队协作编程是一种常见的工作模式。特别是对于大型项目来说,不同团队间需要协同合作,共同完成复杂的任务。Golang作为一种高效、并发性强的编程语言&…...
详解spotbugs -textui常用命令(包括生成html测试报告)
用命令运行spotbugs 本文默认大家了解spotbugs的基础使用,如果不了解可以参考文章 使用神器Spotbugs,轻松入门静态代码分析-CSDN博客 我们在使用spotbugs 对Java代码进行静态分析,查找相关的漏洞时通常在使用Maven和Gradle进行构建的过程中…...
C++:Map和Set
目录 一、关联式容器 二、键值对 三、树形结构的关联式容器 A.set的模板参数列表 B.set的构造 C.set的迭代器 D.set的容量 E.set的修改操作 F.set的使用举例 A.map的模板参数列表 B.map的构造 C.map的迭代器 D.map的容量 E.map中元素的修改 operator[ ] insert()…...
【Unity Shader编程】之顶点着色器
来一张AI提供的资料 在shader编程中,定义的结构体,有些是会被自动赋值,有些是必须要手动赋值的,这就涉及到了语义, 例如 struct appdata{float4 vertex : POSITION;float vertex2;float2 uv : TEXCOORD0;};结构体里面定…...
Hive之[Hive]详细安装步骤
hive 是依赖hadoop中的hdfs作为存储,依赖mysql管理元数据 master节点 集群环境 master 192.168.204.130 slave1 192.168.204.131 slave2 192.168.204.132组件下载地址 https://archive.apache.org/dist/hive/hive-1.2.2/ 或 链接: https://pan.baidu.com/s/1…...
3.【线性代数】——矩阵乘法和逆矩阵
三 矩阵乘法和逆矩阵 1. 矩阵乘法1.1 常规方法1.2 列向量组合1.3 行向量组合1.4 单行和单列的乘积和1.5 块乘法 2. 逆矩阵2.1 逆矩阵的定义2.2 奇异矩阵2.3 Gauss-Jordan 求逆矩阵2.3.1 求逆矩阵 ⟺ \Longleftrightarrow ⟺解方程组2.3.2 Gauss-Jordan求逆矩阵 1. 矩阵乘法 1.…...
手动配置IP
手动配置IP,需要考虑四个配置项: 四个配置项 IP地址、子网掩码、默认网关、DNS服务器 IP地址:格式表现为点分十进制,如192.168.254.1 子网掩码:用于区分网络位和主机位 【子网掩码的二进制表达式一定是连续的&#…...
unity is running as administrator 管理员权限问题
每次打开工程弹出unity is running as administrator的窗口 unity版本2022.3.34f1,电脑系统是win 11系统解决方法一:解决方法二: unity版本2022.3.34f1,电脑系统是win 11系统 每次打开工程都会出现unity is running as administr…...
AI在电竞比分网中的主要应用场景
AI在电竞体育比分网的数据应用非常广泛,能够显著提升数据分析、预测、用户体验和商业价值。以下是AI在电竞比分网中的主要应用场景: 1. 实时数据采集与分析 比赛数据实时更新:AI通过自动化系统实时采集比赛数据(如击杀数、经济差、…...
消息中间件:RabbitMQ镜像集群部署配置全流程
目录 1、特点 2、RabbitMQ的消息传递模式 2.1、简单模式(Simple Mode) 2.2、工作队列模式(Work Queue Mode) 2.3、发布/订阅模式(Publish/Subscribe Mode) 2.4、路由模式(Routing Mode&am…...
TCP的拥塞控制
什么是TCP的拥塞控制?它的工作原理是什么?为什么需要拥塞控制? TCP拥塞控制简介 想象一下,你和一群朋友在一条狭窄的小路上跑步。如果每个人都拼命跑,小路很快就会变得拥挤不堪,大家互相碰撞,…...
Jenkins 配置 Git Repository 五
Jenkins 配置 Git Repository 五 这里包含了 Freestyle project 任务类型 和 Pipeline 任务类型 关于 Git 仓库的配置,如下 不同的任务类型,只是在不同的模块找到 配置 Git 仓库 找到 Git 仓库配置位置之后,所有的任务类型配置都是一样的 …...
父组件中循环子组件调用
父组件中循环子组件调用 父组件 //father.vue <template><view><view v-for"(item,index) in list"><son ref"son"></son></view><buton click"submit">123</buton></view> </templ…...
【网络安全.渗透测试】Cobalt strike(CS)工具使用说明
目录 前言 一、工具显著优势 二、安装 Java 运行环境 三、实验环境搭建要点 四、核心操作流程详解 (一)环境准备与连接步骤 (二)主机上线与深度渗透流程 五、其他实用功能应用指南 (一)office 宏 payload 应用 (二)Https Payload 应用 (三)信息收集策略 …...
C++ 设计模式-建造者模式
以下是一个完整的C建造者模式示例,包含产品类、建造者接口、具体建造者、指挥者以及测试代码: #include <iostream> #include <string> #include <memory>// 产品类:汽车 class Car { public:void setBody(const std::str…...
【Unity3D】Unable to detect SDK in the selected directory
某天突然发现SDK选中自己的目录 或 打安卓包时 提示SDK Tools相关的报错 打开Android Studio的SDK Manager更新Android SDK Tools...
QML使用ChartView绘制饼状图
一、工程配置 首先修改CMakeLists.txt,按下图修改: find_package(Qt6 6.4 REQUIRED COMPONENTS Quick Widgets) PRIVATEtarget_link_libraries(appuntitledPRIVATE Qt6::QuickPRIVATE Qt6::Widgets )其次修改main.cpp,按下图修改ÿ…...
ollama本地部署 deepseek离线模型安装 一套从安装到UI运行
一、安装本地ollama 1、下载ollama (1)百度网盘windows版本 通过网盘分享的文件:OllamaSetup.exe 链接: https://pan.baidu.com/s/15ca6WAzrc4wWph5H9BEOzw 提取码: 283u (2)进入官网:Ollama 2、选择你的系统 等待下载完成就可以了。 注:这…...
【linux】ubunbu切换到root
在 Ubuntu 中切换到 root 用户有几种方法,具体取决于你的需求和权限配置。以下是常见的几种方式: 1. 使用 sudo 临时切换到 root 如果你当前用户有 sudo 权限,可以使用以下命令临时切换到 root 用户: bash sudo -i 或者࿱…...
推理框架对比:ReAct、思维链(COT)和思维树(TOT)谁更胜一筹
推理框架作为 AI 解决复杂问题的核心机制,正逐渐成为研究和应用的焦点。ReAct、思维链(Chain-of-Thought,CoT)(Chain-of-Thought (CoT):引导大型语言模型解决问题的有效策略)和思维树࿰…...
electron.vite 项目创建以及better-sqlite3数据库使用
1.安装electron.vite npm create quick-start/electronlatest中文官网:https://cn.electron-vite.org/ 2. 安装项目依赖 npm i3.修改 electron-builder 配置文件 appId: com.electron.app productName: text33 directories:buildResources: build files:- !**/.v…...
Dockerfiles 的 Top 10 常见 DevOps/SRE 面试问题及答案
1. RUN 和 CMD 之间有什么区别? RUN : 在镜像构建过程中执行命令,创建一个新的层。通常用于安装软件包。 示例: RUN apt-get update && apt-get install -y curlCMD : 指定容器启动时默认运行的命令。它在运行时执行,而不是在构建过程…...
Sentinel——Spring Boot 应用接入 Sentinel 后内存开销增长计算方式
接入 Sentinel 对 Spring Boot 应用的内存消耗影响主要取决于 规则数量、资源数量、监控粒度、并发量 等因素。 1. 核心内存消耗来源 (1) Sentinel 核心库 默认依赖:Sentinel Core 本身占用较小,通常在 10~50MB(取决于资源数量和规则复杂度…...
domain 网络安全 网络安全域
文章目录 1、域的概述 1.1、工作组与域1.2、域的特点1.3、域的组成1.4、域的部署概述1.5、活动目录1.6、组策略GPO 2、域的部署实验 2.1、建立局域网,配置IP2.2、安装活动目录2.3、添加用户到指定域2.4、将PC加入域2.5、实验常见问题 3、OU(组织单位…...
OpenCV机器学习(2)提升算法类cv::ml::Boost
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 cv::ml::Boost 是 OpenCV 机器学习模块中的一部分,用于实现提升算法(Boosting Algorithms)。Boosting 是一种…...
【Java 面试 八股文】框架篇
框架篇 1. Spring框架中的单例bean是线程安全的吗?2. 什么是AOP?3. 你们项目中有没有使用到AOP?4. Spring中的事务是如何实现的?5. Spring中事务失效的场景有哪些?6. Spring的bean的生命周期?7. Spring中的…...
基于HAL库的按钮实验
实验目的 掌握STM32 HAL库的GPIO输入配置方法。 实现通过按钮控制LED亮灭(支持轮询和中断两种模式)。 熟悉STM32CubeMX的外部中断(EXTI)配置流程。 实验硬件 开发板:STM32系列开发板(如STM32F103C8T6、N…...
TCP 端口号为何位于首部前四个字节?协议设计的智慧与启示
知乎的一个问题很有意思:“为什么在TCP首部中要把TCP的端口号放入最开始的四个字节?” 这种问题很适合我这种搞历史的人,大年初一我给出了一个简短的解释,但仔细探究这个问题,我们将会获得 TCP/IP 被定义的过程。 文…...
前端实现在PDF上添加标注(1)
前段时间接到一个需求,用户希望网页上预览PDF,同时能在PDF上添加文字,划线,箭头和用矩形框选的标注,另外还需要对已有的标注进行修改,删除。 期初在互联网上一通搜索,对这个需求来讲发现了两个问…...
Springboot 中如何使用Sentinel
在 Spring Boot 中使用 Sentinel 非常方便,Spring Cloud Alibaba 提供了 spring-cloud-starter-alibaba-sentinel 组件,可以快速将 Sentinel 集成到你的 Spring Boot 应用中,并利用其强大的流量控制和容错能力。 下面是一个详细的步骤指南 …...
如何优化React应用的性能?
文章目录 1. 引言2. 渲染优化2.1 使用 React.memo 避免不必要的重新渲染2.2 使用 shouldComponentUpdate 或 PureComponent2.3 使用 useMemo 和 useCallback 3. 异步渲染与懒加载3.1 使用 React.lazy 和 Suspense 实现懒加载3.2 分割代码(Code-Splitting)…...
ES的java操作
ES的java操作 一、添加依赖 在pom文件中添加依赖包 <dependencies><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.8.0</version></dependency><!-- elastic…...
八大排序——简单选择排序
目录 1.1基本操作: 1.2动态图: 1.3代码: 代码解释 1. main 方法 2. selectSort 方法 示例运行过程 初始数组 每轮排序后的数组 最终排序结果 代码总结 1.1基本操作: 选择排序(select sorting)也…...
算法学习笔记之贪心算法
导引(硕鼠的交易) 硕鼠准备了M磅猫粮与看守仓库的猫交易奶酪。 仓库有N个房间,第i个房间有 J[i] 磅奶酪并需要 F[i] 磅猫粮交换,硕鼠可以按比例来交换,不必交换所有的奶酪 计算硕鼠最多能得到多少磅奶酪。 输入M和…...
【数据结构】(8) 二叉树
一、树形结构 1、什么是树形结构 根节点没有前驱,其它节点只有一个前驱(双亲/父结点)。所有节点可以有 0 ~ 多个后继,即分支(孩子结点)。每个结点作为子树的根节点,这些子树互不相交。 2、关于…...
前端大屏适配方案:从设计到实现的全流程指南
引言 随着数据可视化需求的增长,大屏展示项目在前端开发中越来越常见。然而,大屏开发面临独特的挑战: 屏幕分辨率多样:从1080P到4K甚至8K,如何保证清晰度?布局复杂:多图表、多组件如何合理排列…...
10. Hbase Compaction命令
一. 什么是Compaction 在 HBase 中,频繁进行数据插入、更新和删除操作会生成许多小的 HFile,当 HFile 数量增多时,会影响HBase的读写性能。此外,垃圾数据的存在也会增加存储需求。因此,定期进行 Compact操作ÿ…...
完善sql盲注中的其他函数 dnslog+sqlmap外带数据
2. 布尔盲注 布尔盲注是通过观察应用程序的响应(如页面内容、HTTP 状态码等)来判断查询条件是否为真。 <?php // 数据库连接配置 $host localhost; $dbname testdb; $user root; $password password; // 创建数据库连接 $conn new mysqli($ho…...
Python 识别图片和扫描PDF中的文字
目录 工具与设置 Python 识别图片中的文字 Python 识别图片中的文字及其坐标位置 Python 识别扫描PDF中的文字 注意事项 在处理扫描的PDF和图片时,文字信息往往无法直接编辑、搜索或复制,这给信息提取和分析带来了诸多不便。手动录入信息不仅耗时费…...
Java 有哪些锁,他们的区别是什么
Java 锁的分类 Java 中的锁可以从多个维度进行分类: 悲观锁 vs. 乐观锁公平锁 vs. 非公平锁独占锁 (互斥锁) vs. 共享锁 (读写锁)可重入锁 vs. 不可重入锁自旋锁偏向锁 vs. 轻量级锁 vs. 重量级锁 (JVM 锁优化) 1. synchronized 关键字: 类型: 悲观锁…...
CSS实现单行、多行文本溢出显示省略号(…)
在网页设计中,我们常常遇到这样的情况:文本内容太长,无法完全显示在一个固定的区域内。为了让界面看起来更整洁,我们可以使用省略号(…)来表示内容溢出。这不仅能提升用户体验,还能避免内容溢出…...
网络协议/MQTT Paho.MQTT客户端库接口基础知识
开源c版mqtt客户端:https://github.com/eclipse-paho/paho.mqtt.cMQTT 客户端与服务器之间支持的通信协议主要包括: 协议地址格式加密默认端口适用场景服务器地址示例TCPtcp://不加密1883局域网或对安全性要求不高的场景tcp://localhost:1883TLS/SSLssl://加密8883对安全性要…...
VSCode C/C++ 开发环境完整配置及常见问题(自用)
这里主要记录了一些与配置相关的内容。由于网上教程众多,部分解决方法并不能完全契合我遇到的问题,因此我选择以自己偏好的方式,对 VSCode 进行完整的配置,并记录在使用过程中遇到的问题及解决方案。后续内容也会持续更新和完善。…...
深入解析 Go 中的 `io.Pipe()`:实现高效的并发通信
在 Go 语言中,io.Pipe() 是一个强大且灵活的工具,用于在不同的 goroutine 之间实现高效的同步和通信。它通过创建一对连接的 I/O 流,允许数据在管道的两端安全地传递。本文将详细介绍 io.Pipe() 的工作原理、主要特点、使用方法以及一些实际应…...
【Kubernetes】常用命令全解析:从入门到实战(中)
🐇明明跟你说过:个人主页 🏅个人专栏:《Kubernetes航线图:从船长到K8s掌舵者》 🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、什么是k8s 2、K8s的核心功能 二、资…...
嵌入式八股文面试题(二)C语言算法
相关概念请查看文章:C语言概念。 1. 如何实现一个简单的内存池? 简单实现: #include <stdio.h> #include <stdlib.h>//内存块 typedef struct MemoryBlock {void *data; // 内存块起始地址struct MemoryBlock *next; // 下一个内…...