自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(81)
  • 收藏
  • 关注

原创 linux 恒等映射 idmap 的作用

在head.S 中,__create_page_table时,将 __idmap_text_start 到 __idmap_text_end 的范围创建和恒等映射(物理地址与虚拟地址相同,详见。所以说,恒等映射保证了打开mmu 之后,cpu 仍然可以继续使用物理地址(因为物理地址会被mmu 作为虚拟地址翻译成相同的值)执行代码。通过搜索“idmap.text”,可以看到只有下表中的这些符合被放在了idmap.text 段中。

2024-04-16 08:52:14 141

原创 linux arm64 __create_page_tables 的结果验证

内核代码一开始,在完成了el2_setup, set_cpu_boot_mode_flag之后,就开始__create_page_tables本文主要概述__create_page_tables 的作用和过程。代码没必要一行一行分析,都是基础的汇编代码。并且内核本身有很全面的注释。本文目的是把这个过程拆解成很多个小段,从而更容易理解。

2024-04-08 08:30:39 776

原创 vscode GDB 调试linux内核 head.S

此前参考如下文章已经完成了在ubuntu 虚拟机用vscode 调试linux 内核。但是美中不足的是,断点最早只能加在__primary_switched() 函数。无法停在更早的断点上,比如ENTRY(stext) 位置。参考《奔跑吧linux 内核(第2版)》卷2,3.1.5节如下位置,可以在gdb -tui 中从 ENTRY(stext) 开始单步调试,但是远不如vs code 方便。于是在vs code 官方文档中寻找方法。

2023-08-29 09:13:35 558

原创 idmap_pg_dir 大小及作用

43ARM64_HW_PGTABLE_LEVELS 的含义是:在不使用段映射的情况下,需要多少个页表级别来寻址宽度为 ‘va_bits’ 的地址。因为我们用每个页表级别的 (PAGE_SHIFT - 3) 位来解析最高的 (va_bits - PAGE_SHIFT) 位。所以就需要(48-12) / (12-9) = 4 个级别,也就是PGD,PUD, PMD, PT (L0-L3)四级。即ARM64_HW_PGTABLE_LEVELS(48) = 41。

2023-08-10 08:40:15 226

原创 init_pg_dir 的大小及作用

在vmlinux.lds.S 中,有01EARLY_PGDSEARLY_PUDSEARLY_PMDS从System.map 中可以看到。

2023-08-08 08:18:21 241

原创 ARM64_HW_PGTABLE_LEVEL_SHIFT 宏的作用

所以,ARM64_HW_PGTABLE_LEVEL_SHIFT(4 - CONFIG_PGTABLE_LEVELS) 得到的其实是PGD, L0页表索引在64bit 虚拟地址所处的偏移量,即39。在 4K page 的情况下,因为pow(4, 12) = 4K,所以需要用bit11-0来表示某地址在该page中的偏移。比如四级页表,每级页表所占的bit 个数就是36/4 = 9,也就是下图所示的情况。设页表等级数 为n,那每级索引所占的bit个数就是36/n。

2023-07-18 08:50:48 191

原创 《软件开发本质论》读书笔记

产品推动人为团队提供目的,包括大方向和细节上的目的。并使得团队深入理解为什么要做这个事情。

2023-04-22 10:26:29 482

原创 adrp 命令为何能获取符号的地址

adrp 在编译时,会记录label 地址与当前指令地址的offset。在运行时,pc + offset 就能得到label 的地址。又因为arm64 指令长度的限制,所以adrp 这条指令得到的地址仅仅精确到了label 所在的页的基地址,需要配合ADD 加上label 的lo12 位才能得到准确地址。

2023-01-14 22:02:08 909

原创 __pa_symbol 及str_l 解析

其作用是在内核物理内存的线性映射还没建立的时候,用来根据虚拟地址计算物理地址

2022-11-10 08:54:07 677

原创 ubuntu apt-get update 失败 server certificate verification failed

apt update 失败,提示server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none

2022-10-29 08:00:50 1134

原创 mipi 协议科普(C/DPHY)

从mipi spec 中截取了一些常用的概念,mipi 入门时可以参考这个ppt ,算是划了下重点

2022-09-23 08:04:16 783

原创 static_branch_likely 原理及用法(完全剖析)

看irq-gic-v3.c时,发现中断回调中有static_branch_likely 这么一个函数。看起来是为了减少cpu 分支预测失败带来的巨大代价而做的优化。具体原理还没细看。内核源码中这里有个文档介绍 kernel/Documentation/static-keys.txt。...

2022-04-17 21:27:22 1468 1

原创 ctags 生成简明易用 linux 源码 tags

问题所在一般使用ctags 就是用ctags -R生成tags。不过这样看源码时会有两个问题:假如同一个函数在不同的处理器架构中都有实现,那么跳转时,会出现很多你不关心的架构的函数原型。比如你关注arm64,但是会出现power pc,mips 等等架构在跳转时,会出现很多struct member的标签。但是这通常不是你想要的。最典型的你可以在linux 源码中 :ta device,你期望的是跳到struct device 的定义处。结果出现了几百行结果,大部分都是device 作为其他stru

2022-04-14 08:05:39 1156

原创 浅谈 arch_local_irq_save 及arm64 debug exceptions

追__raw_spin_lock_irqsave 代码时,发现了arch_local_irq_save 这个函数,顺便看了下这个函数static inline unsigned long arch_local_irq_save(void){ unsigned long flags; asm volatile( "mrs %0, daif // arch_local_irq_save\n" "msr daifset, #2" : "=r" (flags) : : "memory"

2022-03-16 09:55:46 737

原创 linux arm64 中断处理流程完整分析 (二)—— 中断处理流程c代码部分 以gic_v3 为例

本文以gic 为例,探索中断中断控制器的注册过程,以及相关中断处理流程。GIC V3 结构详细可以参考这个页面。这里只做简单介绍。/*drivers/irqchip/irq-gic-v3.c*/IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init);gic_of_init(struct device_node *node, struct device_node *parent) "从dts中获取distributor,以及redistributor

2022-03-08 08:53:01 2843

原创 linux arm64 中断处理流程完整分析 (一)—— 中断向量表、中断处理流程汇编部分

中断流程老生常谈,但我一直以来也只是知道中断过来之后,会保护现场,跳到中断向量表,执行中断,恢复现场,然后返回。至于更多细节,就不得而知了。这篇文章旨在把更完整的linux 中断处理流程梳理一遍。主要带着以下几个问题:中断向量表是在代码哪里配置的响应中断时,必然有一些读写gic 寄存器的操作,这些操作在什么位置/proc/interrupts 这个proc 文件是如何实现的linux 进入中断前,会屏蔽其他所有中断,这个是如何实现的系统调用的系统中断0x80,是如何从用户态调用到内核态file_

2022-03-03 09:11:02 3731

原创 页表映射及页表描述符

以4KB页表粒度,4级页表为例,分析虚拟地址到物理地址的转换过程:虚拟地址的bit63 用来选择TTBR0 还是TTBR1。这两个寄存器中保存了内核态和用户态的L0页表基地址。(这也是为什么内核地址高位总是0xFFFF…)在L0 基地址处,保存了512个页表项(512=pow(2,9), 因此L0 索引占用了9bit,下同),每一个页表项占用64bit。根据虚拟地址中的 L0 索引找到 L0 页表中的一个页表项(如红框所示)。该页表项的bit47-bit_m 保存了下一级页表的物理基地址。此处bit_

2022-01-13 08:28:54 707

原创 ARM cache 结构与访问方式

组相连的cache 结构PIPT 与VIVT 的访问方式

2021-12-07 08:50:41 1519 1

原创 内核性能优化点

高速缓存伪共享当多个cpu 访问同一个高速缓存行中的不同数据时,两个cpu 会不断争夺对该高速缓存行的控制权,不断将对方的高速缓存行invalid,导致不断写内存,进而导致性能下降。解决方法就是让多线程操作的数据处在不同的高速缓存行。如struct data { long x; long y; long z;} __attribute__(__aligned__((64)))...

2021-11-08 08:56:23 87

原创 《程序员的自我修养——链接、装载与库》读书笔记—— 7.6 动态链接的步骤和实现

简述动态链接可以分为以下几个步骤:动态链接器的自举装载共享对象重定位和初始化

2021-10-18 08:54:50 194

原创 《程序员的自我修养——链接、装载与库》读书笔记—— 7.5 动态链接相关结构

7.5.x 这几小节看的有点懵,只能多看几遍,慢慢理解。定几个小目标:搞清楚.dynamic, .dynsym, .rel.dyn, .rel.plt 这几个段都保存了哪些信息?这些段能在什么阶段起到什么作用?

2021-10-15 08:35:10 360

原创 vim 常用插件包及快捷键

目录插件和vim脚本安装常用快捷键导航窗口符号跳转其他常用快捷键常见问题vim 中使用某些命令或者快捷键时,有报错本文简单介绍我目前使用的vim 插件的使用方法和快捷键。插件和vim脚本安装从一个大佬那里fork来的一份vimrc的配置,自己做了点改动。下载链接:https://github.com/zqxl/vimrc安装步骤:1、将其中的vimrc 复制为ubuntu 的~/.vimrc,如下2、将整个目录(.git所在目录的所有的文件及文件夹)复制到~/.vim/ 目录下,如下3、

2021-10-10 11:15:39 368

原创 hexdump 命令

大概整明白了-e 里边这个format 到底怎么写。模仿man 里边的命令demo改了一个能用hexdump -e ‘"0x%08_ax: " 4/4 "%08x " “\n”’ plt|less搞清楚的含义:%08_ax :08是输出按8个字符的长度输出,高位补0;_a是输出offset;x是按16进制;4/4:第一个4是每行四次输出;第二个4是每次输出4个byte0x00000000: 464c457f 00010101 00000000 000000000x00000010: 000300

2021-09-29 08:33:36 1072

原创 Android 编译框架下使用gcov 统计.so代码覆盖率

我的需求是在Android编译框架下,可执行程序需要在设备机中执行,而非宿主机。因此走了些弯路,这里记录一下。编译在相应的Andriod.mk 中添加如下CFLAGNATIVE_COVERAGE := trueLOCAL_STATIC_LIBRARIES += libgcovLOCAL_CFLAGS += -ftest-coverage -fprofile-arcsLOCAL_LDFLAGS += -ftest-coverage -fprofile-arcs结果解析运行后的.gcda 文件

2021-09-28 08:22:30 1158

原创 《程序员的自我修养——链接、装载与库》读书笔记—— 7.4 延迟绑定

为什么需要延迟绑定根据前文所述,动态链接的可执行程序在使用.so 中的符号时,依赖.got 中保存的地址,这个地址是链接器在程序运行时才去填充(或者说绑定)的。如果有大量的符号需要动态链接,这些符号查找地址重定位的工作必定会消耗可观的时间。并且,可能很多动态库中的函数在程序执行完时都不会被调用到,那么对这些函数的查找和重定位的工作就白白浪费了。什么是PLT 延迟绑定PLT(procesure linkage table) 延迟绑定的基本思路就是,在程序第一次被使用的时候,才去进行绑定(符号查找,填充.

2021-09-26 08:17:17 256

原创 《程序员的自我修养——链接、装载与库》读书笔记—— 7.1-7.3 动态链接、地址无关码

为什么要动态链接静态链接时,公共库函数会被链接到程序内部,同时运行多个程序时,公共库函数在内存中(磁盘中也一样)就存在多个副本,极大浪费空间。而动态链接库只在内存中有一个副本,所有使用这个动态库的程序都使用这一份副本。(此时你也想到了,对于动态链接库中的可修改数据,比如全局变量,静态局部变量等,每个程序都必须有自己的副本才可以,否则将导致冲突)程序的开发和发布。使用静态链接时,一旦静态库发生改动(比如修了一个小bug),整个程序都必须被重新下载。使用动态链接时则只需要重新下载更新这个动态链接库就可以了

2021-09-20 08:26:37 135

原创 《程序员的自我修养——链接、装载与库》读书笔记—— 6.4.5 进程栈初始化

一直以来有个疑惑,在编写一个类似下面的简单的应用程序时,main 函数的两个参数argc, argv谁传给它的?int main(int argc, char *argv[]){ ....}这一小节解答了我的这个疑问。操作系统在启动进程前,会把进程的运行参数argc, argv提前保存到进程的虚拟空间的栈中。同时被报错的栈中的还有系统环境变量。假如我们运行命令prog的同时传入参数123,也就是“./prog 123”,此时的进程栈如下图:栈顶寄存器esp 指向的地址0XBF801FBC

2021-09-12 11:24:11 118

原创 《程序员的自我修养——链接、装载与库》读书笔记—— 6.4.1 ELF 文件链接视图和执行视图

查看可执行程序的段表,可以看到一共有33个段。如下图。在ELF被映射时,是以页长度为单位的。如果按照段来映射,那么33个段每个段都要映射到页长的整数倍大小的空间里,这将造成极大的内存空间浪费。其实,操作系统在映射ELF时,关心的只是段的权限(可读、可写和可执行)。因此,可以将相同权限的段合并在一起来进行映射,从而避免大量因对齐导致的内存空间浪费。合并之后的段被称为“Segment”。如下命令可以查看ELF 的Segment。从下图红框位置,还可以看到每个“Segment” 都合并了哪些段(section

2021-09-12 09:12:59 350

原创 《程序员的自我修养——链接、装载与库》读书笔记 6.2 装载方式

程序必须从磁盘装载到内存中才可以被执行。最简单的方法就是把程序装载到加载地址即可,但是内存往往不够用。这里介绍了两种典型的装载方式:覆盖装入和页映射。书中的介绍已经很简洁明了,这里就不再概括了。请直接参照书中原文。...

2021-08-22 16:17:08 108

原创 objdump和 readelf 的区别

在查看section 时,发现两者的section 下标是不一样的,对于同一个.o,两者的结果如下。可以看到,readelf -S 下标为0的是一个类型为NULL 段,但是objdump -h 的结果不存在这个段。因此,同一个段,在两个结果中的下标是不一样的。比如我碰到的疑问就是,通过readelf -s查看符号表,发现符号所在的段下标和objdump -h出来的段对应不起来。。。所以才有了这篇blog,记录一下zqxl@ubuntu:~/work/practice/_3.4_SimpleSection

2021-08-19 08:31:13 235

原创 linux 内核启动串口log 等级配置

问题看kernel 代码的时候,总会重新烧内核,有时候乱改改挂了,但是发现串口启动log没有打出来,没法定位。于是乎想研究一下内核启动时的串口log 是如何控制的?什么情况下会都打出来,以及什么时候没有打印线索经高人指点,说看一下内核启动参数bootargs。于是在内核启动后,dmesg看了下,果然发现了个疑点,启动参数里有个quiet 选项。所以以此为线索看下内核是如何解析这个参数的。就从大名鼎鼎的start_kernel 开始找吧。/* 首先init/main.c中可以找到这么一个定义,看起

2021-07-17 22:18:02 1182

原创 imx6ull uboot 从tftp 加载内核

问题背景imx6ull 的mfgtool 烧录工具慢得要死,自己最近在看内核代码,经常烧内核,还经常烧完启动不了,如果每次都用mfg tool烧录,效率太低。有大佬提示可以通过tftp 启动,就找了个教程实践了一下。主要参考了这个页面,解决了自己遇到的几个小问题。在这里整理记录一下整个过程。tftp 服务器配置(ubuntu)步骤如下:1、xinetd 安装sudo apt-get install xinetd2、 配置xinetdsudo vi /etc/xinetd.conf/etc

2021-07-17 16:49:06 774 1

原创 dtb解析过程及platform_device 创建过程

目录内核解析dtb 文件,并构建树状devide_node 的过程platform_device 创建过程内核解析dtb 文件,并构建树状devide_node 的过程dtb被编译好传给内核之后,内核是如何解析的?解析的结果是什么?有必要追一下代码。/* 在 drivers/of/base.c 中,创建了一个全局的指针*/struct device_node *of_root;EXPORT_SYMBOL(of_root);/*drivers/of/fdt.c 看起来下边这个函数给of_root

2021-07-06 08:31:07 1728 1

原创 以spi_bus_type 为例梳理kobject. ktype, kset用法

spi_bus_type//bus_type 的定义如下struct bus_type spi_bus_type = { .name = "spi", .dev_groups = spi_dev_groups, .match = spi_match_device, .uevent = spi_uevent,};spi_dev_groups//这里是一个attribute group,应该对应在bus 目录下的一个个的文件static const struct attribute_

2021-07-01 08:55:47 371

原创 内核代码研读计划

主线任务1. 内核是如何从设备树将dev 解析并注册进内核,挂接到相应的bus上的支线任务1.

2021-06-08 08:41:22 72

原创 野火imx6ull开发板使用笔记

内核编译与烧录参照如下部分:

2021-05-14 08:53:28 463

原创 linux spi 驱动框架

spi.cpostcore_initcall(spi_init);static int __init spi_init(void) bus_register(&spi_bus_type); class_register(&spi_master_class); spidev.cmodule_init(spidev_init);static int __init spidev_init(void) register_chrdev(SPIDE

2021-02-24 08:50:39 99

转载 ubuntu 环境变量

一:设置环境变量的三种方法1.1 临时设置export PATH=/home/yan/share/usr/local/arm/3.4.1/bin:$PATH11.2 当前用户的全局设置打开~/.bashrc,添加行:export PATH=/home/yan/share/usr/local/arm/3.4.1/bin:$PATH1使生效:source .bashrc11.3 所有用户的全局设置$ vim /etc/profile1在里面加入:export PATH=/home/

2020-12-31 08:25:40 1634

原创 开源寄存器查看小工具 类unicode++

工作需要经常需要查看寄存器,在10进制,16进制直接转换,有一个很好用的小软件叫unicode++,界面如下:然而,不知道为什么,有时候死活输入不了。所以就自己用python 写了一个,GitHub如下:https://github.com/zqxl/bitsshow现在的初始版本功能比较简单:后续会慢慢完善。...

2020-10-12 23:49:52 1446 1

原创 书签(保存文章用)

默認打開pr_debug和dev_dbghttps://www.cnblogs.com/pengdonglin137/p/5808373.html

2020-05-30 11:22:29 362 2

mipi 协议科普,含cphy, dphy, csi2

mipi 协议科普,含cphy, dphy, csi2

2022-09-22

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除