【NVMEM子系统深入剖析】四、efuse驱动实现流程
Jan 18, 2024
本文阅读量次我的圈子: 高级工程师聚集地 创作理念:专注分享高质量嵌入式文章,让大家读有所得! 亲爱的读者,你好: 感谢你对我的专栏的关注和支持,我很高兴能和你分享我的知识和经验。如果你喜欢我的内容,想要阅读更多的精彩技术文章,可以扫码加入我的社群。 欢迎关注【嵌入式艺术】,董哥原创!
我的圈子: 高级工程师聚集地 创作理念:专注分享高质量嵌入式文章,让大家读有所得! 亲爱的读者,你好: 感谢你对我的专栏的关注和支持,我很高兴能和你分享我的知识和经验。如果你喜欢我的内容,想要阅读更多的精彩技术文章,可以扫码加入我的社群。 欢迎关注【嵌入式艺术】,董哥原创!
四、Uboot命令行模式分析 # 前几篇文章,我们也了解了Uboot的启动流程,那么这节就主要讲讲Uboot的命令行模式。 另外,文章末尾还提供eMMC5.1官方标准协议.pdf和eMMC4.51官方标准协议-中文.pdf下载渠道,方便深入了解底层协议。 正文如下: 4.1 如何进入命令行模式 # 我们正常启动流程,默认是直接跳过Uboot命令行模式的,因为Uboot主要的作用是引导Kernel,一般我们不进行uboot开发时,都默认跳过进入命令行模式。 那么,我们要想进入Uboot命令行模式,需要进行哪些配置呢? 打开我们准备好一份Uboot源码,进入menuconfig配置菜单,主要设置下列几个配置信息! CONFIG_CMDLINE:命令行模式开关 CONFIG_SYS_PROMPT:命令行模式提示符 CONFIG_HUSH_PARSER:使用hush shell 来对命令进行解析 BOOTDELAY:设置启动延时 Tip:meneconfig中查找苦难?实时/符号,输入1或2或3,直接查找指定标识。 打开之后,重新编译,并将Uboot镜像烧录到开发板中,再次启动,我们就能够看到倒计时。 [2022-03-02:13:33:47]U-Boot 2020.10-rc1-00043-ge62a6d17c6-dirty (Feb 08 2022 - 10:14:14 +0800) [2022-03-02:13:33:47] [2022-03-02:13:33:47]Model: xxxxxx [2022-03-02:13:33:47]MMC: mmc1@xxxxxx: 1 [2022-03-02:13:33:47]In: serial [2022-03-02:13:33:47]Out: serial [2022-03-02:13:33:47]Err: serial [2022-03-02:13:33:47]Model: xxxxxx [2022-03-02:13:33:49]Hit any key to stop autoboot: 2 Hit any key to stop autoboot:我们在倒计时结束前,任意键入一个按键,即可进入! 4.2 Uboot基本命令解析 # 进入Uboot命令行模式后,键入help或者?,可以查看所有支持的Uboot命令。 注意:Uboot支持的命令大都远远超过显示的,还有好多没有打开,可以在menuconfig中,打开相应的功能,如mmc相关的,md内存相关的。 常用命令如下: version #查看uboot版本 reset #重启Uboot printenv #打印uboot环境变量 setenv name value #设置环境变量 md addr #查看内存指令 nm addr #修改内存值 mm addr #自增修改内存值 mmc dev id #选择mmc卡 mmc rescan #扫描卡 echo $name #打印环境变量 更多指令使用,可以见文末整理的文档 ...
Linux内存管理 | 四、物理地址空间设计模型 # 前面几篇文章,主要讲解了虚拟内存空间的布局和管理,下面同步来聊聊物理内存空间的布局和管理。 1、物理内存 # 什么是物理内存? 我们平时聊的内存,也叫随机访问存储器(random-access memory),也叫RAM。 RAM分为两类: SRAM:静态RAM,其主要用于CPU高速缓存 L1Cache,L2Cache,L3Cache,其特点是访问速度快,访问速度为 1 - 30 个时钟周期,但是容量小,造价高。 DRAM:动态RAM,其主要用于我们常说的主存上,其特点的是访问速度慢(相对高速缓存),访问速度为 50 - 200 个时钟周期,但是容量大,造价便宜些(相对高速缓存)。 DRAM经过组合起来,就作为我们的计算机内存,也是物理内存。 2、物理内存访问模型 # 上面介绍了物理内存的基本组成,那么CPU是如何访问物理内存的呢? 对于CPU访问物理内存,Linux提供了两种架构:UMA(Uniform Memory Access)一致内存访问,NUMA(Non-Uniform Memory Access)非一致内存访问。 2.1 UMA # 在UMA架构下,多核处理器中的多个CPU,位于总线的一侧,所有的内存条组成的物理内存位于总线的另一侧。 所有的CPU访问内存都要经过总线,并且距离都是一样的,所以在UMA架构下,所有CPU具有相同的访问特性,即对内存的访问具有相同的速度。 2.2 NUMA # 这种架构,系统中的各个处理器都有本地内存,处理器与处理器之间也通过总线连接,以便于其他处理器对本地内存的访问。 与UMA不同的是,处理器访问本地内存的速度要快于对其他处理器本地内存的访问。 3、物理内存组织模型 # 内存页是物理内存管理中最小单位,有时也成为页帧(Page Frame)。 内核对物理内存划分为一页一页的连续的内存块,每页大小4KB,并且使用struct page结构体来表示页结构,其中封装了每个页的状态信息,包括:组织结构,使用信息,统计信息等。 page结构体较为复杂,我们后续再深入了解。 更多干货可见:高级工程师聚集地,助力大家更上一层楼! 3.1 FLATMEM平坦内存模型 # FLATMEM即:flat memory model。 我们把物理内存想象成它是由连续的一页一页的块组成的,我们从0开始对物理页编号,这样每个物理页都会有页号。 由于物理地址是连续的,页也是连续的,每个页大小也是一样的。因而对于任何一个地址,只要直接除一下每页的大小,很容易直接算出在哪一页。 如果是这样,整个物理内存的布局就非常简单、易管理,这就是最经典的平坦内存模型(Flat Memory Model)。 如上图,平坦内存模型中,内核使用一个mem_map的全局数组,来组织所有划分出来的物理内存页,下标由PFN表示。 在平坦内存模型下 ,page_to_pfn 与 pfn_to_page 的计算逻辑就非常简单,本质就是基于 mem_map 数组进行偏移操作。 #ifndef ARCH_PFN_OFFSET #define ARCH_PFN_OFFSET (0UL) #endif #if defined(CONFIG_FLATMEM) #define __pfn_to_page(pfn) (mem_map + ((pfn)-ARCH_PFN_OFFSET)) #define __page_to_pfn(page) ((unsigned long)((page)-mem_map) + ARCH_PFN_OFFSET) #endif ARCH_PFN_OFFSET 是 PFN 的起始偏移量。 ...
【一文秒懂】Linux网络性能测试工具——Iperf # Iperf是一个网络性能测试工具,可以测试最大TCP和UDP带宽性能,具有多种参数和UDP特性,可以根据需要调整,可以报告带宽、延迟抖动和数据包丢失。 Iperf3在NLNR/DAST开的的原始版本进行重新设计,其目标是更小、更简单的代码库,并且还提供Iperf所不具备的新功能,如:nuttcp 和netperf iperf有Linux,Windows,android,Mac等版本,下面结合实际网络场景进行iperf工具使用的介绍 确保使用Iperf测试的服务端和客户端都处于同一局域网内! 1、Iperf环境准备 # Iperf下载链接:推荐下载源码路径,官网下载、Github下载或者其他地址2 1.1 Linux源码安装Iperf # 以Ubuntu20.04为例,下载压缩包iperf-3.1.3.tar.gz,解压并进入目录。 tar -zxvf iperf-3.1.3.tar.gz #解压 cd iperf-3.1.3/ #进入解压目录 mkdir linux_install_dir #创建安装目录 ./configure --prefix=/home/dong/WorkSpace/Program/iperf-3.1.3/linux_install_dir #--prefix设置安装目录,即iperf3生成路径,绝对路径 make clean #清除掉之前编译的文件,确保不影响 make #编译 make install #安装 进入linux_install_dir/bin安装目录,可以看到iperf3可执行文件。我们可以通过readelf -h iperf3 | grep Machine可以查看运行平台。 Machine: Advanced Micro Devices X86-64 1.2 Arm交叉编译Iperf # 以Arm平台为例,解压iperf-3.11.tar.gz,并进入目录。 tar -zxvf iperf-3.1.3.tar.gz #解压 cd iperf-3.1.3/ #进入解压目录 mkdir arm_install_dir #创建安装目录 ./configure --host=arm-linux-gnueabihf --prefix=/home/dong/WorkSpace/Program/iperf-3.1.3/arm_install_dir/ CFLAGS=-static# --host设置使用的编译器; --prefix 安装目录; CFLAGS静态编译 make clean #清除掉之前编译的文件,确保不影响 make #编译 make install #安装 进入arm_install_dir/bin安装目录,可以看到iperf3可执行文件。我们可以通过readelf -h iperf3 | grep Machine可以查看运行平台。 ...
我的圈子: 高级工程师聚集地 创作理念:专注分享高质量嵌入式文章,让大家读有所得! 亲爱的读者,你好: 感谢你对我的专栏的关注和支持,我很高兴能和你分享我的知识和经验。如果你喜欢我的内容,想要阅读更多的精彩技术文章,可以扫码加入我的社群。 欢迎关注【嵌入式艺术】,董哥原创!
我的圈子: 高级工程师聚集地 创作理念:专注分享高质量嵌入式文章,让大家读有所得! 亲爱的读者,你好: 感谢你对我的专栏的关注和支持,我很高兴能和你分享我的知识和经验。如果你喜欢我的内容,想要阅读更多的精彩技术文章,可以扫码加入我的社群。 欢迎关注【嵌入式艺术】,董哥原创!
【LED子系统深度剖析】五、核心层详解(二) # 1、前言 # 上篇文章我们了解了子系统的核心层led-class.c,下面我们来分析驱动框架中核心层的led-core.c实现以及作用。 我们接着从led-core.c文件开始分析 2、led_init_core分析 # 上一篇文章,我们知道在将leds_classdev注册进入子系统后,会调用led_init_core函数,初始化核心层,下面我们以led_init_core该函数为突破口分析。 2.1 相关数据结构 # 2.1.1 work_struct # struct work_struct { atomic_long_t data; struct list_head entry; work_func_t func; #ifdef CONFIG_LOCKDEP struct lockdep_map lockdep_map; #endif }; 结构体名称:work_struct 文件位置:include/linux/workqueue.h.h 主要作用:定义一个工作队列,包括了工作项的状态和数据,以及处理工作项的函数指针,用于实现异步执行任务的功能。在工作队列中,每个工作项都是一个work_struct结构体的实例,通过将工作项添加到工作队列中,可以实现后台执行任务的功能。 2.1.2 timer_list # struct timer_list { /* * All fields that change during normal runtime grouped to the * same cacheline */ struct hlist_node entry; unsigned long expires; void (*function)(struct timer_list *); u32 flags; #ifdef CONFIG_LOCKDEP struct lockdep_map lockdep_map; #endif }; 结构体名称:work_struct ...
我的圈子: 高级工程师聚集地 创作理念:专注分享高质量嵌入式文章,让大家读有所得! 亲爱的读者,你好: 感谢你对我的专栏的关注和支持,我很高兴能和你分享我的知识和经验。如果你喜欢我的内容,想要阅读更多的精彩技术文章,可以扫码加入我的社群。 欢迎关注【嵌入式艺术】,董哥原创!
Linux内存管理 | 五、物理内存空间布局及管理 # 上章,我们介绍了物理内存的访问内存模型和组织内存模型,我们再来回顾一下: 物理内存的访问内存模型分为: UMA:一致内存访问 NUMA:非一致内存访问 物理内存的组织模型: FLATMEM:平坦内存模型 DISCONTIGMEM:不连续内存模型 SMARSEMEM:稀疏内存模型 Linux内核为了用统一的代码获取最大程度的兼容性,对物理内存的定义方面,引入了:内存结点(node)、内存区域(zone),内存页(page)的概念,下面我们来一一探究。 更多干货可见:高级工程师聚集地,助力大家更上一层楼! 1、内存节点node # 内存节点的引入,是Linux为了最大程度的提高兼容性,将UMA和NUMA系统统一起来,对于UMA而言是只有一个节点的系统。 下面的代码部分,我们尽可能的只保留暂时用的到的部分,不涉及太多的体系架相关的细节。 在Linux内核中,我们使用 typedef struct pglist_data pg_data_t表示一个节点 /* * On NUMA machines, each NUMA node would have a pg_data_t to describe * it's memory layout. On UMA machines there is a single pglist_data which * describes the whole memory. * * Memory statistics and page replacement data structures are maintained on a * per-zone basis. ...
【一文秒懂】Linux调试工具——GDB介绍 # 1、GDB是什么 # GDB:GNU Project Debugger是GNU工程仿真器,允许开发者能够去看程序内部发生的情况,或者发生crash时候, 知道程序正在做什么!它诞生于 GNU 计划(同时诞生的还有 GCC、Emacs 等),是 Linux 下常用的程序调试器。发展至今,GDB 已经迭代了诸多个版本,当下的 GDB 支持调试多种编程语言编写的程序,包括 C、C++、Go、Objective-C、OpenCL、Ada 等。实际场景中,GDB 更常用来调试 C 和 C++ 程序。 GDB主要功能有四个方面: 启动程序:指定任何可以影响其运行行为的动作 停止程序:使程序在指定条件下停止 检查错误:当程序停止时,检查发生了什么 纠正错误:更改程序中的内容,纠正错误 GDB可以在本地、远程、仿真器上执行。 2、GDB如何使用 # 如何使用GDB? 要想回答这个问题,从正统角度来分析,有两种方式: GDB官方手册:https://sourceware.org/gdb/ GDB帮助信息:help all(命令行输入) 简单来说,GDB调试方法有3种: 直接调试:gdb [exec file],用于直接仿真一个执行程序 附属调试:gdb attach pid,用于直接调试一个已运行的程序(ubuntu注意权限问题) 核心转存调试:gdb [exec file] [core-dump file],用于调试core-dump文件 Tips:GDB调试的[exec file],该文件最好编译的时候带上-g选项,生成带调试信息的可执行文件。 3、GDB常用指令 # 3.1 基础指令 # 指令 含义 file [exec file] 选择要调试的可执行文件 run/r 重新开始运行文件 start 暂时断点,停在第一执行语句处 list/l 查看源代码 next/n 单步调试,逐过程,函数直接执行 step/s 单步调试,逐语句,跳入函数执行 backtrace/bt 查看函数调用的堆栈信息 finish 结束当前函数,返回函数调用点 continue 继续执行 print/p 打印变量 break/b [filename:line_number] 打断点, [文件名:行号],也有多种方式 quit 退出gdb调试 3. ...