字符设备驱动开发基础

物理内存:计算机底层的实际地址

虚拟地址:现代计算机利用虚拟地址技术实现的一种地址

MMU:Memory Manage Unit、1 完成虚拟空间到物理空间的映射。2 内存保护设置存储器的访问权限,设置虚拟存储空间的缓冲特性。

内存映射

1
2
3
4
5
6
7
8
9
#define ioremap(cookie, size) __arm_ioremap((cookie), (size), MT_DEVICE)
void __iomem* __arm_ioremap(phys_addr_t phys_addr, size_t size, unsigned int mtype)
{
return arch_ioremap_caller(phys_addr, size, mtype, __builtin_return_address(0));
}

mtype: MT_DEVICE MT_DEVICE_NONSHARED MT_DEVICE_CACHED MT_DEVICE_WC

void iounmap(volatile void __iomem* addr);

I/O内存访问函数

映射的虚拟地址,其实本质就可直接通过指针访问,但是Linux内核不推荐这样做,而是推荐一组操作函数来对映射后的内存进行读写操作(猜测是为了可追溯、安全检查等)。

1
2
3
4
5
6
7
u8 readb(const volatile void __iomem* addr)
u16 readw(const volatile void __iomem* addr)
u32 readl(const volatile void __iomem* addr)

void writeb(u8 value, volatile void __iomem* addr)
void writew(u16 value, volatile void __iomem* addr)
void writel(u32 value, volatile void __iomem* addr)

Tip:vscode在查找一些系统头文件目录的时候会优先使用系统的头文件目录,所以需要在vscode设置中将系统头文件目录屏蔽

Makefile编译驱动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
KERNELDIR := /home/chengs/imx6ull/linux
CURRENT_PATH := $(shell pwd)
MODULE_NAME := chrdevbase led
obj-m := $(patsubst %, %.o, $(MODULE_NAME))
DIRVERS := $(patsubst %, %.ko, $(MODULE_NAME))

build: clean kernel_modules

kernel_modules:
$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules
cp $(DIRVERS) $(CURRENT_PATH)/../rootfs/lib/modules/4.1.15/
clean:
$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean