基于ARM(RK3399等)的Linux实战
文章平均质量分 71
包括U-Boot、Kernel、文件系统的方方面面
Linux与SoC
这个作者很懒,什么都没留下…
展开
-
U-Boot与kernel之间的参数传递机制完全解析
详细分析u-boot与kernel之间的bootargs传递机制,包括如何传递、解析及应用原创 2022-09-03 18:58:23 · 3041 阅读 · 1 评论 -
U-Boot初始化及工作流程分析
U-Boot启动流程原创 2022-06-28 18:38:21 · 956 阅读 · 0 评论 -
使用kgdb调试树莓派4B平台上的kernel代码
1. RPI 4B 端配置1.1 RPI 串口配置使用 kgdb 调试 kernel 的时候,宿主机的 gdb server 通过串口与目标机进行通讯。RPI 4B 这个板子的硬件串口 ttyAMA0 使用 GPIO 引出,利用 USB-TTL 转接线与宿主机相连。这个串口对应的是 ttyAMA0。默认情况下 serial0 对应软串口 ttyS0:默认没有映射到 ttyAM0 的原因是 ttyAMA0 被蓝牙模块复用了,在 config.txt 文件中禁用掉蓝牙模块:将 serial0 更改到原创 2021-09-11 10:44:13 · 628 阅读 · 0 评论 -
利用busybox构造linux根文件系统
1.busybox概述众所周知,在linux环境下一切都是文件,文件能表示一切。那么文件系统就是这些普通组件的集合。在嵌入式领域使用的文件系统,通常是基于busybox来构建的。busybox从诞生至今已有近20年的历史,目前已经成为嵌入式行业主流的文件系统构建工具。官网https://busybox.net/busybox的代码完全开源。进入到官网点击Get BusyBox下面的Download Source进入到源码下载界面。2. busybox的配置及编译下载源码之后将源码拷贝到编原创 2021-09-11 21:56:53 · 194 阅读 · 0 评论 -
linux kernel version版本号实现原理和细节
文章目录0. 引言1. 为什么要打印version信息2. kernel version实现原理0. 引言kernel 启动时通常会看到下面的第二行的内容,它代表了当前 kernel 的版本、编译工具版本、编译环境等信息。Booting Linux on physical CPU 0x0Linux version 5.4.124+ (funny@funny) (gcc version 6.5.0 (Linaro GCC 6.5-2018.12)) #30 SMP Sat Sep 11 11:10:2原创 2021-09-20 07:54:56 · 1426 阅读 · 3 评论 -
CPU CACHE中的VIPT与PIPT的工作原理
启动信息描述内核启动过程中有如下打印信息:CPU: PIPT / VIPT nonaliasing data cache, VIPT nonaliasing instruction cache这行打印信息代表了处理器L1 CACHE所支持的寻址方式。在kernel启动过程中,虽然这里第一次出现CACHE相关的打印信息,但是,此处并不是kernel第一次操作CACHE。例如:对于zImage而言,解压缩过程中会开启CACHE并配置CACHE 写属性。#ifdef CONFIG_CPU_DCACH原创 2021-10-09 22:01:33 · 1942 阅读 · 0 评论 -
kernel中通过read_mostly修饰变量来降低CACHE bounding
在kernel代码中存在大量的通过__read_mostly修饰的变量,例如: struct workqueue_struct *system_wq __read_mostly; EXPORT_SYMBOL(system_wq); struct workqueue_struct *system_highpri_wq __read_mostly; EXPORT_SYMBOL_GPL(system_highpri_wq);它有什么用?被__read_mostly修饰的变量存放于cache中,在链接原创 2021-09-21 12:33:16 · 291 阅读 · 0 评论 -
linux kernel启动过程中初始化mem_types,据此创建内核页表
linux booting过程中会打印内存属性信息,例如:OF: fdt: Machine model: V2P-CA9Memory policy: Data cache writealloc来自函数build_mem_type_table(void),调用流程如下:setup_arch | #ifdef CONFIG_MMU early_mm_init(mdesc); #endif | early_mm_init() | build_m原创 2021-09-28 14:17:51 · 364 阅读 · 1 评论 -
kernel自带的静态代码检查工具Sparse介绍
1.Sparse介绍Linus在2004年开发了kernel代码静态检查工具,可以检查出kernel中潜在的风险代码,Sparse通过 gcc 的扩展属性__attribute__ 以及自己定义的 __context__来对代码进行静态检查,重点检查kernel代码中的变量类型和各类锁。具体可以参考kernel文档Documentation/dev-tools/sparse.rst那么如何指定代码可以被Sparse检查的到呢?以__iomem为例,可以对需要检查的变量类型放到特定文件中,以__C原创 2021-12-14 20:11:52 · 1387 阅读 · 0 评论 -
假如只有串口和JTAG,如何高效且优雅的调试linux驱动程序
在只有串口和JTAG存在的嵌入式设备环境中,可以通过JTAG将镜像文件下载到指定位置,但是当文件较大时,下载镜像所消耗的时间会很长,当调试代码时每次都重新加载镜像文件,极大的降低了开发效率。基于这个背景,我们可以通过串口按需加载文件,对于调试驱动程序而言,可以极大的提高开发和调试效率。需要的工具包括lrzsz和一个支持x/y/z moderm的串口终端。1. 源码下载下载地址:https://ohse.de/uwe/software/lrzsz.html下载0.12.20版本2. 编译原创 2021-11-06 14:18:35 · 477 阅读 · 3 评论 -
linux kernel中的CPU CACHE策略初始化流程
linux booting过程中会打印CACHE的写机制,打印信息如下:OF: fdt: Machine model: V2P-CA9Memory policy: Data cache writealloc以上打印信息来自于函数build_mem_type_table(void)它的调用栈如下:setup_arch | #ifdef CONFIG_MMU early_mm_init(mdesc); #endif | early_mm_init()原创 2021-10-10 16:50:46 · 728 阅读 · 0 评论 -
linux创建init进程的3种实现方式原理分析
1. 概述Linux系统启动过程中通过init_task创建0号idle进程。然后通过kernel_thread创建1号init进程。创建该进程时通过系统调用,在内核空间执行用户空间的/sbin/init程序,通过该程序产生出shell,并依赖init衍生出其他进程。通过top命令查看当前系统环境下的进程列表,可以发现1号进程的为{linuxrc} init[root@iTOP-4412]# topMem: 26404K used, 948572K free, 0K shrd, 3199543672K原创 2021-11-26 15:59:58 · 1099 阅读 · 1 评论 -
Linux内核中__iomem的解析
内核代码中充斥着大量的__iomem修饰的void类型的指针,像下面这样:void __iomem *devm_ioremap_resource(struct device *dev, const struct resource *res){ resource_size_t size; void __iomem *dest_ptr; char *pretty_name; BUG_ON(!dev); if (!res || resource_type(res) != IORE原创 2021-12-14 22:39:24 · 4520 阅读 · 0 评论 -
查看Ubuntu操作系统的kernel config文件方法
ubuntu16@ubuntu16-virtual-machine:~$ ls /boot/config-`uname -r`/boot/config-4.15.0-117-genericubuntu16@ubuntu16-virtual-machine:~$直接编辑原创 2021-11-27 16:06:27 · 3966 阅读 · 0 评论 -
Linux系统启动 | 保留内存初始化原理及如何在项目中应用实战
1. 概述在linux启动过程中会打印出如下信息,这些信息为我们呈现出系统下的保留内存空间情况。Reserved memory: created DMA memory pool at 0x4c000000, size 8 MiBOF: reserved mem: initialized node vram@4c000000, compatible id shared-dma-pool本文只介绍基本的保留内存,不涉及CMA部分内容保留内存的初始化流程如下图所示:本文所说的保留内存的作用,概原创 2021-12-03 21:48:05 · 528 阅读 · 0 评论 -
linux kernel中module_platform_driver实现原理分析
介绍在linux kernel中通过module_platform_driver来实现模块化平台驱动。大量的设备驱动程序都基于该种方式来实现,使用频次非常的高,在linux kernel 5.4.124的代码中搜索module_platform_driver共有2356次引用。这个宏的使用方式大相径庭,有一套成熟的代码书写方式,将驱动程序入口符号作为宏的参数,基本格式如下:历史它的定义在include/linux/platform_device.h中,从文件的名字来看可知它存在的意义是基于原创 2021-10-23 15:52:43 · 829 阅读 · 0 评论 -
Ubuntu18.04.6 LTS搭建ROCK3399 Linux Docker开发环境(非常详细)
参考文档飞凌官方docker安装文档,本文是对其的补充。1. 安装必要的软件rk@ubuntu:~$ sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common Reading package lists... DoneBuilding dependency tree Reading state information... Doneca-certific.原创 2021-12-13 18:42:02 · 1370 阅读 · 0 评论 -
RK3399开箱体验及切换MIPI显示的方法
开发板默认是MIPI显示的,但是因为我在写这个文章之前,我把它切成了HDMI显示输出,为了还原真实开机启动的情形,有切换回MIPI复原默认的第一次开机情景。输出显示切换可以通过U-Boot命令行的方式实现。当U-Boot进入到倒计时阶段时,我们打断它,进入到配置模式。Hit key to stop autoboot('SPACE'): 0---------------------------------------------0:Exit to console1:Reboot2:Display原创 2021-12-17 22:37:59 · 820 阅读 · 0 评论 -
基于RK3399分析Linux系统下的CPU时钟管理 - 第2篇
SoC时钟系统提供的功能包括:使能控制、倍频、分频、复用等。因此,在软件代码中按照SoC时钟系统提供的功能来组织Clock provider的结构,方便用户使用。1. Clock provider数据结构CCF是common clock framework的缩写,意为通用时钟框架。在内核中通过宏定义CONFIG_COMMON_CLK打开CCF,打开相关宏开启CFG框架的通用功能,具体如下:CONFIG_COMMON_CLK=yCONFIG_CLKDEV_LOOKUP=yCONFIG_HAVE_CL原创 2021-12-28 21:31:26 · 1041 阅读 · 0 评论 -
Linux系统启动过程中的initcall实现原理和调试方法
介绍initcall的意义和使用方法、实现原理、执行流程以及调试方法。原创 2022-01-11 19:57:17 · 1644 阅读 · 0 评论 -
Kconfig中select与depends on原理
select与depends on是相反的逻辑关系。A depends on B那么只有在B选中才能选AA select B那么只要选中A就会选中B,所以select叫反向依赖。原创 2021-12-23 13:56:33 · 2380 阅读 · 1 评论 -
ARM平台的U-Boot移植详细步骤
介绍了RK3399的bootloader工作原理,移植U-Boot2022.01的详细流程原创 2022-01-17 08:20:43 · 2621 阅读 · 1 评论 -
基于Ubuntu的linux环境制作嵌入式SD/TF启动卡
制作嵌入式系统的SD/TF启动卡原创 2022-04-27 19:18:21 · 3550 阅读 · 2 评论 -
CPU中断的本质及分类,硬件中断、软件中断、异常的区别
CPU中断的本质及分类,介绍硬件中断、软件中断、异常的含义原创 2022-02-22 18:46:41 · 4256 阅读 · 1 评论 -
Linux驱动中阻塞IO进程的处理机制分析
内核版本:4.4.189当驱动程序无法立即满足请求,该如何响应?而调用进程通常又不会考虑驱动程序的状态,因此,在驱动程序中就需要做一些处理,而通常的做法是阻塞该进程的请求。阻塞I/O是指在执行设备操作时,若不能获得资源,则挂起当前进程直到满足可操作的条件后再进行操作。被挂起的进程进入到睡眠状态,从调度器的运行队列中被移走,直到等待的条件得到满足。而非阻塞I/O在不能进行设备操作时,并不挂起,它要么放弃,要么不停地轮询,直至可以进行操作为止。等待队列是处理阻塞I/O的经典机制。1. 驱动中阻塞I原创 2021-12-24 22:41:17 · 1047 阅读 · 0 评论 -
RK3399芯片上电后加载启动程序的详细流程
芯片上电解复位之后执行的第一段程序,在芯片中称之为Bootrom loader。这部分程序在芯片制造过程中固化到其内部的ROM空间,具备只读属性,在实际使用过程中无法修改这部分内容,这部分程序的知识产权也仅归属于芯片公司所有。其实,你也可以将Bootrom loader称之为固件。对于ARM架构的处理器而言,芯片上电解复位后的PC通常是指向0x00000000或0xffff0000地址,也就是说,它会去该地址处取第一条指令、译码、执行。CPU能支持的启动模式通过硬件拨码的方式告知CPU,CPU上电解复位后原创 2021-12-25 17:42:14 · 3127 阅读 · 0 评论 -
基于RK3399分析Linux系统下的CPU时钟管理 - 第1篇
0. 背景介绍绝大多数的电子器件都是由时钟驱动其工作的。而SoC芯片或电路板中的时钟以树状结构呈现,按时钟域进行划分,按照不同的时钟需求进行管理。出于功耗和数据传输时序控制等目的,在内核代码中对时钟进行统一注册、统一管理。kernel代码中很早就出现了时钟管理机制,甚至早于git版本管控之前。1. 时钟定义ARM处理器平台中基于dts描述时钟树,包括时钟结构、时钟属性等信息。由时钟框架驱动和设备驱动解析dts中时钟树信息,完成时钟系统的初始化、管理、使用。在设备树中定义了时钟的providers和c原创 2021-12-28 21:40:28 · 2249 阅读 · 0 评论 -
基于RK3399分析Linux系统下的CPU时钟管理 - 第3篇
详细讲解了RK3399的时钟系统结构,包括时钟系统初始化、PLL配置、时钟控制等实现原理原创 2021-12-29 19:37:57 · 2496 阅读 · 1 评论