V4l2loopback实现笔记(二):字符设备交互
本文继续记录复现 v4l2loopback 功能的学习过程。在上一篇文章中,我们介绍了如何编写一个基础的内核模块,涵盖了模块的元数据、初始化与清理函数等核心概念。本文将进一步探讨内核模块与用户空间的交互,重点介绍字符设备的注册与使用。这是理解 v4l2loopback 工作原理的关键一步,因为 v4l2loopback 作为一个虚拟视频设备,必须通过字符设备接口与用户空间进行数据交换。
本文继续记录复现 v4l2loopback 功能的学习过程。在上一篇文章中,我们介绍了如何编写一个基础的内核模块,涵盖了模块的元数据、初始化与清理函数等核心概念。本文将进一步探讨内核模块与用户空间的交互,重点介绍字符设备的注册与使用。这是理解 v4l2loopback 工作原理的关键一步,因为 v4l2loopback 作为一个虚拟视频设备,必须通过字符设备接口与用户空间进行数据交换。
本文旨在记录复现 v4l2loopback 功能的学习过程。为了深入理解 v4l2loopback(虚拟视频设备)的工作原理,本文决定从零开始复现其核心功能作为整个项目的起点,首先通过编写一个名为 hello_v4l2 的基础内核模块,来探索 Linux 内核开发的核心概念。本文内容主要涵盖了内核模块开发中最基础但也最重要的几个技术点:生命周期管理、参数传递、日志输出以及内存管理。
在操作系统中,进程间通信(Inter-Process Communication, IPC)是指不同进程之间交换数据和信息的机制。以下是几种常见的进程间通信方式:管道(Pipes)、命名管道(Named Pipes)、消息队列(Message Queues)、共享内存(Shared Memory)、信号量(Semaphores)、套接字(Sockets)等。
指针变量圈定的内存大小与编译器或者说地址总线有关。在32系统中,指针变量大小为4byte;在64位系统中,指针变量大小为8byte。将指针和指针变量的概念进行区分,指针代表这个指针变量的值,即内存地址;指针变量指的是一个变量,用于存放内存地址。
STL Containers
├── 顺序容器(Sequence)
│ ├── vector
│ ├── deque
│ ├── list / forward_list
│ └── array
│
├── 关联容器(有序,基于红黑树)
│ ├── set / multiset
│ └── map / multimap
│
├── 无序关联容器(哈希表)
│ ├── unordered_set / unordered_multiset
│ └── unordered_map / unordered_multimap
│
└── 容器适配器(接口受限)
├── stack
├── queue
└── priority_queuevector —— 动态数组(最常用)特点
内存分布分为静态区和动态区,静态区在编译时已经决定好了内存分配大小,动态区是运行时分配。

#include <stdio.h>
#include <stdlib.h>
int global_inited = 10;
int global_uninited;
int main()
{
int local_var = 20;
char *str = "Hello";
static int static_var = 30;
static char static_str1 = 'b';
static char static_str2;
int *heap_var = (int *)malloc(sizeof(int));
printf("Address of main: %p\n", main);
printf("Address of str: %p\n", str);
printf("Address of global_inited: %p\n", &global_inited);
printf("Address of static_var: %p\n", &static_var);
printf("Address of static_str1: %p\n", &static_str1);
printf("Address of global_uninited: %p\n", &global_uninited);
printf("Address of static_str2: %p\n", &static_str2);
printf("Address of heap_var: %p\n", heap_var);
printf("Address of local_var: %p\n", &local_var);
free(heap_var);
return 0;
}输出: