自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 SPI 串行外围设备接口

当主设备发送数据时,将数据从内存中拷入串行移位寄存器,随后通过 MOSI 引脚向从设备发送数据。从设备则会将串行移位寄存器中的数据进行移位,将原有数据通过 MISO 引脚输出,从而接收主设备发送的数据,并拷入内存中。不同的 SPI 中存在不同的电子器件,在配置和使用上都会存在差异。因此,SPI 的数据传输为一发一收。为了避免收到不需要的数据,SPI 设备制定了相关的命令,来在正确的时序点接收数据。SPI 工作模式称为主从模式,因此设备相互连接后,主模式成为 SPI 主控制器,从模式则成为 SPI 设备。

2023-10-28 20:27:14 152

原创 sylixos SDIO 设备

总线适配器一般会被链入系统提供的全局总线链表(_G_plineBusAdapterHeader),同时总线适配器提供这类总线设备的链表头(SDADAPTER_plineDevHeader),以及为这类总线设备提供通用的接口(SDADAPTER_psdfunc)。SDM 作为 SD 协议栈核心层,参考 SD 物理设备抽象了 __SDM_HOST 主控器结构和驱动(_G_sdmhostdrvfuncs),API_SdmLibInit 完成 __SDM_HOST 驱动接口的定义。

2023-07-24 10:07:38 204

原创 rk3588 大小核启动

多核启动则是 Linux 通过 cpu_ops 简介调用 psci 的操作接口,从而执行从核的启动与关闭等操作,这些操作均和 SMC 指令有所关联。猜测 5 核接收 SMC 指令后,固件进行了响应,但是 5 核出现问题,无法启动,导致主核出现死循环现象,现象由 bsp 代码结构造成。5 核启动后没有任何输出,怀疑 5 核启动时,供电是否正常,打印电压状态寄存器排查。结果表明,多核启动时供电正常,故排除因供电问题导致的多核启动失败。分析代码,对 psci 接口进行更新,启动 4 核,系统成功启动。

2023-05-24 11:47:12 1647

原创 cpufreq--处理器功耗控制

policy 暂无注册接口,Linux 中在编译过程中会开辟空间存放已有的 policy,但是 policy 不一定会被使用,因此在驱动注册过程中会进行选择处理。提供文件操作为 show 和 store,通过这两种接口访问 governor 和 policy,从而控制功耗。管理方案的实现则由具体的驱动来完成。用户可以通过功耗管理接口(以文件形式提供)来选择管理方案,并设置相关参数。cpufreq 框架提供 cpu 功耗管理接口,以及功耗管理方案。组织层和策略层将以驱动的形式注册,并提供用户接口文件。

2023-03-17 14:35:48 901

原创 基于 oss 框架的音频驱动

oss_audio_open_devfile 接口根据设备编号在全局数组 audio_devfiles 中获取 adev_t 结构,audio_devfiles 为全局数组,创建 audio dev 过程中会被应用。驱动主要对上述中 mixer,audio dev 的操作进行实现,对应的操作结构为 _mixer_driver_t 和 audiodrv_t。因此,oss 框架中,核心结构体为 _adev_t 结构,用于对设备进行描述,后期的初始,读,写等操作都是通过 _adev_t 结构来完成。

2023-02-10 17:52:23 1031 5

原创 kmem_cache(slab机制)

同时,kmem_cache 中的 c_lastp 以及 c_firstp 指针将以 c_offset 属性地址为基准,使其成 kmem_cache 中所有 slabs 的双向链表头。当申请 地址空间时,内核首先匹配较为接近的 kmem_cache,随后在 kmem_cache 中已有的 slab 中获取相应的地址空间(即。上述结构中 kmem_cache 结构中嵌套了 kmem_slab 结构,用作 kmem_cache 中 slab 结构的链表头。嵌套的位置为 kmem_cache->c_offset。

2022-09-08 18:11:56 1048

原创 free_area 空闲区域

申请地址空间时,内核将根据 free_area 和 mem_map 数组来决定,内核提供了宏 RMQUEUE_TYPE 作为内存分配的最终执行者。关于上述中的 free_are_init 接口则是在 paging_init 接口中被调用,不同的架构实现的页初始化不同,以 i386 为例。通过 free_area_init 接口来初始空闲区域。为了理解 Linux 内存管理,选取低版本向上学习,此次分析的为 2.2.26 版本。综上,便是 free_area 的入口调用分析。

2022-09-05 17:13:06 429

原创 内存管理_memblock

void __init page_address_init(void){ int i; for (i = 0; i < ARRAY_SIZE(page_address_htable); i++) { INIT_LIST_HEAD(&page_address_htable[i].lh); spin_lock_init(&page_address_htable[i].lock) }}static struct page_address_slot { struct

2022-08-23 15:00:04 206

原创 ftrace

//以kpatch中的ftrace使用为例,进行分析static struct ftrace_ops kpatch_ftrace_ops __read_mostly = { .func = kpatch_ftrace_handler, .flags = FTRACE_OPS_FL_SAVE_REGS | FTRACE_OPS_FL_IPMODIFY,};ftrace_set_filter_ip(&kpatch_ftrace_ops, ip, 0, 0);re

2020-11-26 14:22:42 262

原创 ftrace_init

//ftrace在kernel启动初始过程中会被初始化,即在init/main.c:start_kernel()函数中。//以mips结构为例,分析ftrace的初始化过程:void __init ftrace_init(void){ extern unsigned long __start_mcount_loc[]; extern unsigned long __stop_mcount_loc[]; //这两个变量由内核编译的过程中进行赋值 unsigned long count, f

2020-11-26 10:47:44 313 1

原创 sock文件系统

//sock文件系统定义如下:static struct file_system_type sock_fs_type = { .name = "sockfs", .init_fs_context = sockfs_init_fs_context, .kill_sb = kill_anon_super,};//sock文件系统在内核初始过程中通过init_calls方式来执行core_initcall(sock_init);//sock文件系统入口——sock_init()接口,原型如下:

2020-10-19 21:04:02 550

原创 网络子系统

网络子系统在内核中可划分为两部分,分别是网络协议栈和网络设备。将从网络编程的接口入手,了解网络子系统,主要以TCP socket编程为例来进行分析。socket系统调用原型:int socket(int family, int type, int protocol);SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol){ return __sys_socket(family, type, protocol);}

2020-10-19 21:01:47 859

原创 qemu-QemuOpt

qemu参数解析:struct QemuOpt { char *name; char *str; const QemuOptDesc *desc; union { bool boolean; uint64_t uint; } value; QemuOpts *opts; QTAILQ_ENTRY(QemuOpt) next;};struct QemuOpts { char *id; QemuOptList *list; Location loc; QTAILQ_H

2020-09-21 17:18:05 236 1

原创 qemu-sysbus

qemu系统总线——sysbus在实际的物理机器上,CPU与外接连接的总线被称之为Host Bus。即系统总线,SysBus。在qemu中,对sysbus总线进行了模拟,实现在hw/core/sysbus.c文件中。type_init(sysbus_register_types);static void sysbus_register_types(void){ type_register_static(&system_bus_info); type_register_static(

2020-09-11 10:01:16 558

原创 qemu-qdev

qemu中创建设备的接口为qdev_new函数。DeviceState *qdev_new(const char *name){ if (!object_class_by_name(name)) { module_load_qom_one(name); } return DEVICE(object_new(name));}当创建设备时,qemu首先根据名字找到其所对应的对象类,随后再根据名字创建所需的设备对象。在qemu中,采用了面对对象的设计模式,因此,存在ObjectClass与O

2020-09-11 09:55:06 947 1

原创 中断域

IRQ Domain用于将硬件的中断号,转换成Linux系统中的中断号(virtual irq, virq)。例如:硬件中断号 映射关系 Linux中断号 (irq_domain)INT ID#20 ----------------> irq=4每个中断控制器都对应一个IRQ Domain;中断控制器驱动通过irq_domain_add_*()接口来创建IRQ Domain;IRQ Domain支持三种映射方式:linear map(线性映射),tree map(树映射

2020-07-16 17:27:37 842

原创 CPU Temp hardware monitor

在内核中,为了对硬件设备进行监视,内核提供了hwmon(hardware monitor)方法,来方便对硬件设备的监视。以社区5.6版本为例,分析与龙芯相关的cpu_hwmon.c文件,该文件以module_init()的形式注入内核,从而在内核初始化阶段通过do_initcalls被调用,从而得到执行。该文件的入口函数为:static int __init loongson_hwmon_init(void){ int ret; pr_info("Loongson Hwmon Enter...\n

2020-07-06 18:02:54 1000

原创 总线注册(platform,PCI)

在内核中可能存在不同种类的总线,为了对总线进行管理,内核将其抽象为设备来进行管理。这里,分别以platform总线和pci总线为例来进行说明。platform总线是一种虚拟总线,当某一设备与处理器直接连接时,可以利用该虚拟总线来模拟出设备通过总线连接到处理器这一结构。内核中,关于platform总线的注册位于drivers/base/platform.c文件中。int __init platform_bus_init(void){ int error; early_platform_clean

2020-07-06 16:30:05 831

原创 device_tree分析

在内核中,经常会听到“设备树”这一概念,根据名字,大致可以理解为内核将计算机系统中的设备按照树型结构进行了组织。首先,了解一下内核将会使用的设备树二进制文件DTB。DTB(Devicetree Blob)是DTS的二进制文件格式,Kernel使用DTC工具将DTS源文件编译成DTB,bootloader再将DTB文件传递给Kernel解析。DTB的文件结构|-----------------------|| struct fdt_header ||--------------------

2020-06-30 11:01:51 2480

原创 setup_early_printk()函数分析

关于该函数,主要用来注册用于早期显示的终端。内核中声明了一个全局变量early_console,并将另一全局变量early_console_prom赋值给它,同时,注册early_console_prom所抽象的终端。原型如下:struct console *early_console;static void early_console_write(struct console *con, const char *s, unsigned n){ while (n-- && *s)

2020-06-15 19:41:28 256

原创 printk()函数分析

在内核模块中,常用的输出函数为printk(),为了理解该函数的工作原理以及执行流程,接下来对该函数进行分析。printk()函数原型如下://以“printk("num is: %d!\n", num)”语句为例,开始分析。//在分析之前,先来了解两个宏定义,分别是:#define va_start(v, l) __builtin_va_start(v, l) //参数v将指向(addr + sizeof(l)),addr为参数的首地址#define va_end(v) __builtin_va

2020-06-15 14:43:11 2909

原创 PCI总线设备遍历

在梳理内核驱动程序时,发现一个问题,当注入内核驱动程序时,内核会根据驱动结构体(比如:struct pci_driver)中的总线属性(pci_driver->bus)来找到与驱动程序在同一总线上相对应的驱动设备。因此,本文主要对pci设备在内核中的注入时间,以及注入过程来进行分析。查阅资料,得知关于不同CPU架构下的PCI设备的注入是以arch/cpu_type/pci/目录下的文件为入口来开始执行的。通过对其中的文件进行分析,最后执行的关键入口函数为pci_bus_add_devices()函数

2020-05-21 10:18:13 1883

原创 Linux_rtl8169

以Realtek_8168网卡为例,来说明Linux内核中网卡设备驱动的注册与运行。因为r8168与r8169使用的相同的驱动程序,因此在内核版本中,会发现r8169_main.c文件。在5.6版本的内核中,内核定义了struct pci_driver rtl8169_pci_driver对象来描述网卡驱动,并调用module_pci_driver()函数来注册该驱动模块。如下:static ...

2020-05-16 17:03:10 636

原创 总线(PCI / HT)

什么是总线?总线(BUS)是计算机各种功能部件之间传送信息的公共通信干线,它是由导线组成的传输线束,按照计算机所传输的信息种类,计算机的总线可以划分为数据总线、地址总线和控制总线,分别用来传输数据、数据地址和控制信号。总线是一种内部结构,它是cpu、内存、输入、输出设备传递信息的公用通道,主机的各个部件通过总线相连接,外部设备通过相应的接口电路再与总线相连接,从而形成了计算机硬件系统。在计算机系统中,各个部件之间传送信息的公共通路叫总线,微型计算机是以总线结构来连接各个功能部件的。在计算机系统中按其所连

2020-05-16 11:29:11 2423

原创 硬件中断信号处理

我们知道关于中断被分成了两种,一种是软中断(比如:系统调用,系统报错等);另一种是硬件中断。这里我们来了解一下内核是如何识别并处理这些中断的。以5.6版本的内核为例,在内核启动阶段的代码中可以看到这么一个函数init_IRQ(),顾名思义,该函数主要的任务是初始化中断。因为每个CPU的架构不同,所以其硬件中断存在一定的差异性,因此该函数由各个CPU的架构自己来实现。这里以mips架构为例,其实现...

2020-05-15 17:56:00 1019

原创 存储器管理(三)

虚拟存储器的基本概念 在实际运行过程中,没有必要将进程一次性全部装入内存,因为装入进程后,会长期占用在内存,而进程的运行一班是局部性的。 1. 局部性原理。进程在执行时,将呈现出局部性规律,即在很短的时间内,进程的执行仅限于某个部分。相应的,它所访问的存储空间仅限于某个区域。进程执行时,除少部分的转移和过程调用外,大多数程序顺序执行;过程调用将使进程的执行轨迹从一部分区域转到另一部分区域,进程...

2018-04-18 18:21:59 152

原创 存储器管理(二)

分页存储管理方式 采用“紧凑”技术解决按区分配中存在的碎片问题,其实质是让存储器适应程序对连续性的要求。逻辑地址空间是从0~XKB一个连续的范围,要求主存中也有一个连续的分区用以加载。荡朱村现有的空闲区都小于程序的地址空间时,只有采用“紧凑”技术把碎片连接成一个人的空闲区才能满足作业的要求,但同时在CPU上的消耗代价会更大。所以,该方法只适用于在分配去的数目不太多,而且分配不太频繁的情况。 为...

2018-04-17 19:45:55 457

原创 存储器管理

存储器是计算机系统的重要组成部分,是一种宝贵且紧俏的资源,如何对它进行管理,会影响到存储器的利用率以及系统性能。存储器管理讨论的主要对象是对内存的管理方法以及有效利用。 存储器管理研究的主要内容分为3个方面: 1. 取,研究将哪段程序从辅存调入主存,一般有请调和预调之分。请调是按照需要来确定调入主存的程序段;预调是根据某种策略,预测并调入即将使用的某段程序到主存。 2. 放,研究将“取”来的...

2018-04-13 19:27:15 375

原创 通过PROC文件收集进程信息

cgroup 是对进程进行划分,将使用资源状况近乎相同的进程规划到同一个 cgroup 当中。进程的相关信息保存在 /proc/pid 目录中,而其中的文件较多,具体通过哪个文件来获取数据。随后跟踪了 top 命令的执行过程,即strace top,看到该过程主要打开了两个文件,一个是 stat,另一个是 statm。如图:stat 文件包含的信息广泛,而 statm 主要包含存储的使用情况,所以决

2017-12-29 14:07:58 408

转载 cgroup 简介

cgroup 的功能在于将一台计算机上的资源(CPU,memory,network)进行分片,来防止进程间不利的资源抢占。 术语cgroup:关联一组 task 和一组 subsystem 的配置参数。 一个 task 对应一个进程,cgroup 是资源分片的最小单位。 subsystem:资源管理器,一个 subsystem 对应一项资源的管理,如 cpu, cpuset,memroy 等。

2017-12-19 22:21:04 2496

原创 linux 内核—进程的地址空间(1)

系统中所运行的程序,被叫做进程。每个进程在执行的过程中都会有自己独立的地址空间,而系统是如何确定哪块地址空间是该进程的?所以创建了有关进程的地址空间的数据结构体,通过这些结构体来创建、查找、删除与进程对应的地址空间。什么是地址空间?由进程的所有线性地址构成的空间叫做地址空间。但是地址空间又是由n(n>=0)个线性区构成的,也就是说,地址空间中的线性地址并不是连续的。而线性区的线性地址却是连续的。所以

2017-07-09 15:13:40 285

原创 Linux内核——进程管理(二)

进程上下文 可执行程序代码是进程的重要组成部分。这些代码从一个可执行文件载入到进程的地址空间执行。一般程序在用户空间执行。当一个程序执行系统调用或者触发了某个异常,它就陷入了内核空间。此时,我们称内核“代表进程执行”并处于进程上下文中。在此上下文中current宏是有效的。除非在此间隙有更高优先级的进程需要执行并由调度器做出了相应的调整,否则在内核退出的时候,程序恢复在用户空间会继续执行。 系统

2017-07-02 11:54:55 249

原创 进程管理(一)

进程 进程就是处于执行期的程序(目标码存放在某种存储介质上)。但进程并不仅仅局限于可执行程序代码(Unix称其为代码段,text section)。通常进程还要包含其他资源,像打开的文件,挂起的信号,内核内部数据,处理器状态,一个或多个具有内存映射的内存地址空间及一个或多个执行线程(thread of execution),当然还包括用来存放全局变量的数据段等。实际上,进程就是正在执行的程序的实时结

2017-06-30 22:53:25 260

原创 C++学习笔记(三)

友元函数和友元类 类具有封装性,类中私有成员一般只能通过该类中的成员函数才可以访问,而程序中该类外的其他函数是无法访问其私有成员的。程序中要访问类的私有成员必须通过对象调用该类的公有成员函数来实现,但这样会比较多地占用系统的时间和空间。为了提高运行效率,引进了有缘函数这个概念,它可以作为普通的函数来直接访问类的所有成员,包括私有成员。同样,友元类概念的引入使得一个类作为另一个类的友元,那么这个类的

2017-06-29 16:05:58 250

原创 C++学习笔记(二)

构造函数和析构函数 构造函数和析构函数是类的两个特殊成员函数。构造函数与复制构造函数 一个对象的数据成员反映了对象的属性,它们的值描述了对象所处的状态。但在类的定义中,无法用表达式初始化这些数据成员,因而在说明一个对象时,其初始状态是不稳定的。在创建对象时,应对该对象进行初始化。C++语言在创建一个对象时,通过系统自动调用构造函数对所创建的对象进行初始化。对象(数据成员)的初值通过自动调用构造函

2017-06-27 18:10:45 388

原创 C ++ 学习笔记(一)

C++面向对象程序设计基础 面向对象程序设计的3个重要特性是封装性、继承性和多态性。将所描述的客观事物的不同类型数据和对它们的操作封装成为一个集合体——类和对象,通过类的封装性,可以实现数据隐藏,便于程序的维护和修改。继承特性的引入,为代码的重复利用提供了更有效的手段,派生类继承了基类的所有特性,并改造基类的成员和添加新的成员。C++语言支持编译时的多态和运行时的多态,运行时的多态通过虚函数来实现

2017-06-27 13:22:01 508

原创 文件I/O指针

1.1、辅存的物理排列 辅存一般是两面都能存储信息的硬盘的堆叠,这些光盘成为盘片,每个面成为盘面。盘片叠放在一个由电动机驱动旋转的主轴。 盘片的每个表面进一步划分成同心圆环成为磁道。柱面的值就是盘片每一面的磁道数。反过来,这些轨道进一步划分成扇区。扇区是实际存储数据体系结构的最小单元。 利用磁头从这些介质的表面实现数据读取。借助连接机械臂的移动磁头读取不同扇区。 每个扇区通常能存储512个字

2017-06-23 17:44:06 349

原创 面向连接的通信(LINUX)

首先介绍几个缩写,UICI(Universal Ineternet Communication Interface)叫做通用因特网通信接口,它其实是面向连接通信的一个简化的API( Application Programming Interface)应用程序接口。 UICI接口是通过流套接字和TCP实现的。 下来介绍常用的一种通信模型,客户机-服务器。 它们通信的方式是:

2017-01-16 13:17:53 505

原创 从硬件了解寻址

学习Linux内核,内存管理是必学的,但是和自己以前设计译码电路的寻址完全不同,所以对抽象后地址映射不能很好地理解,虽然很多书都有介绍,但是领悟的还是有缺陷。所以这次以Intel微处理器为例子去了解硬件是怎么寻址的,然后在转到Linux系统怎么抽象的。80x86常见的工作模式有,实模式和保护模式。先来看实模式,它的操作空间<=1MB。所以这个时候段寄存器里面存放的是16位的段地址。然后段地址会

2017-01-15 22:02:58 742

原创 文件操作

管理文件系统主要操作的具体表现为: 在写操作的过程中,通过“超级快->逻辑块位图->数据块”这条路线可以查找到硬盘上的空闲数据块;通过“超级快->i节点位图->i节点表中的i节点->数据块”这条路线可以访问到文件中指定的数据块。 文件系统给通常的组织规则是: 根目录文件i节点->根目录文件->根目录文件中A的目录项->A目录文件的i节点->A目录文件->A目录文件中的B目录项->B目录文件的i

2017-01-15 09:32:30 223

空空如也

空空如也

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

TA关注的人

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