内存管理
页概念在现代计算机系统中,处理器的寻址通常通过 虚拟地址(Virtual Address) 进行,而虚拟地址到物理地址的转换过程涉及“页”(Page)的概念。对于支持内存管理单元(MMU)的处理器(如ARMv7),寻址过程会按照页来划分和管理内存,但具体机制需要结合硬件架构和操作系统来理解。以下是详细说明:
一、处理器寻址的基本概念
虚拟地址与物理地址
虚拟地址:应用程序看到的内存地址(由操作系统分配),范围由处理器位数决定(如32位处理器虚拟地址空间为0~4GB)。
物理地址:实际内存(RAM)的硬件地址,由处理器地址总线宽度决定(如32位处理器物理地址空间通常也是4GB)。
MMU的作用:负责将虚拟地址转换为物理地址,这个过程称为 地址转换(Address Translation)。
分页(Paging)机制
操作系统将虚拟地址空间和物理地址空间划分为固定大小的块,称为 页(Page)。
虚拟地址对应的页称为 虚拟页(Virtual Page),物理地址对应的页称为 物理页(Physical Page)。
页的大小由处理器架构决定(如ARMv7支持4 ...
input子系统
input子系统定义input子系统是linux内核针对某一类型的设备而创建的,比如键盘、鼠标、触摸屏、手柄等。input子系统分为以下几部分:input驱动层,input核心层,input事件层。
上图中,最左边的就是具体的设备,这个不用管。中间部分就是我们要关注的input驱动层,input核心层,input事件层。驱动层:输入设备的具体驱动程序,比如按键驱动程序,向内核层报告输入内容。核心层:承上启下,为驱动层提供输入设备注册和操作接口。通知事件层对输入事件进行处理。事件层:主要和用户空间进行交互。
drivers/input/input.c
123register_chrdev_region(MKDEV(INPUT_MAJOR, 0), INPUT_MAX_CHAR_DEVICES, "input");
这个文件中注册了一个类,设备号是13
输入设备注册在使用 input 子系统的时候我们只需要注册一个 input 设备即可,input_dev 结构体表示 input设备,此结构体定义在 include/lin ...
并发与竞争
1、应用层的锁和内核中的锁区别1-1、特性1-1-1、 内核锁(Kernel Locks)
作用:内核锁用于保护内核数据结构,防止多个内核线程或进程同时访问和修改这些数据结构,从而避免数据不一致或竞争条件。
类型:
自旋锁(Spinlock):当一个线程试图获取已经被占用的自旋锁时,它会不断循环(自旋)直到锁可用。适用于持有时间短的场景。
互斥锁(Mutex):当一个线程试图获取已经被占用的互斥锁时,它会被阻塞,直到锁可用。适用于持有时间较长的场景。
读写锁(Read-Write Lock):允许多个读操作同时进行,但写操作是独占的。适用于读多写少的场景。
使用场景:内核锁主要用于内核空间,保护内核数据结构,确保内核的稳定性和一致性。
1-1-2、 应用层锁(Application-Level Locks)
作用:应用层锁用于保护应用程序中的共享数据,防止多个线程或进程同时访问和修改这些数据,从而避免数据不一致或竞争条件。
类型:
互斥锁(Mutex):类似于内核中的互斥锁,用于保护共享资源,确保同一时间只有一个线程可以访问。
读写锁(Read-Write Lock):允许多个读 ...
linux中断
linux中断1、硬件中断1-1、Linux内核中断API以下是Linux内核中断处理相关的API
1-1-1、中断处理函数注册和注销12int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev);void free_irq(unsigned int irq, void *dev);
request_irq
参数:
unsigned int irq: 中断号。
irq_handler_t handler: 中断处理函数指针。
unsigned long flags: 中断标志(如IRQF_SHARED表示共享中断线)。
const char *name: 中断处理程序的名称,用于调试。
void *dev: 设备标识符,通常为设备结构体。
返回值:
0: 成功注册。
非零值: 注册失败。
free_irq
参数:
unsigned int irq: 中断号。
void *dev: 设备标识符,必须与注册时一致。
...
无题
设备树中,半导体厂商一般已经将芯片的型号、频率、IO、中断、时钟、DMA、内存等参数进行了封装,用户只需要在设备树中引用即可。举例:配置gpio,gpio一般在设备树中以节点方式描述,节点名以gpio开头,节点名后面接gpio的编号,如gpio0、gpio1、gpio2等。如imx6ull的gpio1节点:
123456789101112gpio1: gpio@0209c000 { compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio"; reg = <0x0209c000 0x4000>; interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; gpio-controller; #gpio-cells = <2>; interrupt-controller; #interrupt-cells cc ...
linux内核定时器
定时器1、内核config配置配置内核定时器步骤
12->kernel Features ->timer frequency (<choice> [=y])
在里面可以选择系统的节拍数,默认是1000Hz,也就是1ms节拍,如果选择2000Hz,就是0.5ms节拍,如果选择10000Hz,就是0.1ms节拍。配置完成后,在源码中的.config文件中,会自动生成如下配置:
1CONFIG_HZ=1000
这个就是节拍率。
这个配置生效在:include/asm-generic/param.h中
1234567891011#ifndef __ASM_GENERIC_PARAM_H#define __ASM_GENERIC_PARAM_H#include <uapi/asm-generic/param.h># undef HZ# define HZ CONFIG_HZ /* Internal kernel timer frequency */# define USER_HZ 100 /* some user inte ...
内核4.8后与4.8之前的gpio差异
在 Linux 内核中,有专门用于控制 GPIO(General - Purpose Input/Output,通用输入输出)输出的函数。
4.8 之前的内核在较旧的 Linux 内核版本中,使用的是传统的 GPIO 接口。相关函数主要定义在 <linux/gpio.h> 头文件中。
1、请求GPIO在使用 GPIO 之前,需要先请求该 GPIO 资源,以确保不会与其他驱动冲突。
123#include <linux/gpio.h>int gpio_request(unsigned gpio, const char *label);
2、设置GPIO方向输出1int gpio_direction_output(unsigned gpio, int value);
gpio:要设置的 GPIO 编号。
value:初始输出电平,0 表示低电平,1 表示高电平。返回值:成功时返回 0,失败时返回负数错误码。
3、设置 GPIO 输出电平1void gpio_set_value(unsigned gpio, int value);
gpio: ...
字符内核驱动框架
需要重点掌握的的函数:物理内存映射到虚拟空间后,在内核使用ioremap进行映射,在用户空间使用mmap进行映射。
ioremap函数与readl,readb,readw,readq,writel,writeb,writew,函数配合使用
1、字符型设备框架–旧相关函数:
12345678910111213retvalue = register_chrdev(CHRDEVBASE_MAJOR, CHRDEVBASE_NAME, &chrdevbase_fops);unregister_chrdev(CHRDEVBASE_MAJOR, CHRDEVBASE_NAME);copy_to_user(.....);copy_from_user(.....);module_init(chrdevbase_init);module_exit(chrdevbase_exit);/* * LICENSE和作者信息 */MODULE_LICENSE("GPL");MODULE_AUTHOR("ygc");
1-1、旧字符框架123456789101112 ...
kernel移植(linux4.115移植)
1、选择编译器安装必备库
1sudo apt-get install libncurses5-dev libncursesw5-dev
内核版本,uboot版本,编译器版本,都会影响到程序能否正常运行。
123456#/bin/bashpath="/home/ygc/Desktop/linux-gcc/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin"make ARCH=arm CROSS_COMPILE=$path/arm-linux-gnueabihf- distcleanmake ARCH=arm CROSS_COMPILE=$path/arm-linux-gnueabihf- imx_v7_defconfigmake ARCH=arm CROSS_COMPILE=$path/arm-linux-gnueabihf- menuconfigmake ARCH=arm CROSS_COMPILE=$path/arm-linux-gnueabihf- all -j16
确认编译器没有问题。
2、添加板子的 ...