BeneficialWeb 发表于 2021-11-19 21:32

Linux内核开发环境搭建

本帖最后由 BeneficialWeb 于 2021-11-19 22:01 编辑

# Linux内核开发环境搭建

大学时学习嵌入式驱动程序设计,留下的东西。关于Linux内核开发环境在Windows上的搭建,希望对坛友们有帮助吧。

## 一、安装Visual Studio

负荷选择使用c++的Linux开发



## 二、创建项目

这里选择Linux空项目



## 三、配置内核源码目录

根据需要下载对应内核版本的文件到本地目录,然后vs配置头文件目录。这样就可以享受vs的代码智能提示了。虽然大学的时候,老师都是在Ubuntu虚拟机下用Gedit手敲内核函数,实在佩服当时的刘老师记忆真好。



## 四、例子源文件

新建一个xx.c文件 置入以下代码,以字符设备驱动为例。

```c
// 这里对于visual studio来说比较重要
#ifndef __KERNEL__
#define __KERNEL__
#endif // !__KERNEL__

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/uaccess.h>
#include <linux/sched.h>
#include <linux/ioctl.h>
#include <linux/wait.h>
#include <linux/kfifo.h>
#include <linux/proc_fs.h>

// 模块作者
MODULE_AUTHOR("VirtualCC");
MODULE_LICENSE("GPL"); // 指定模块采用的协议
MODULE_DESCRIPTION("Char Device Driver");
MODULE_VERSION("V1.1");

#define CDEV_DEVICE_NAME      "Cdev"
#define CDEV_NODE_NAME                "myCdev"
#define CDEV_CLASS_NAME                "myCdevClass"

#define CDEV_IOC_MAGIC      'z'
#define CDEV_QUEUE_RESET _IO(CDEV_IOC_MAGIC,0)
#define CDEV_QUEUE_CHANGE_IN _IOW(CDEV_IOC_MAGIC,1,int)
#define CDEV_QUEUE_CHANGE_OUT _IOW(CDEV_IOC_MAGIC,2,int)
#define CDEV_QUEUE_CHANGE_SIZE _IOW(CDEV_IOC_MAGIC,3,int)
#define CDEV_IOC_MAXNR 3

struct class *myCdevClass;
static int major = 0;
static int queueSize = 1 << 10;      // 1 kb
module_param(queueSize, int, S_IRUGO);

int cdevOpen(struct inode* inode, struct file *filp);
int cdevIoctl(struct inode* inode, struct file * filp, unsigned int cmd, unsigned long arg);
int cdevRead(struct file* filp, char __user* buf, size_t count, loff_t* f_pos);
int cdevWrite(struct file* filp, const char __user* buff, size_t count, loff_t *f_pos);
int cdevRelease(struct inode* inode, struct file *filp);
loff_t cdevLlseek(struct file *filp, loff_t offset, int whence);
int queryInfoProc(char* page, char ** start, off_t offset, int count, int* eof, void *data);
static int __init cdevInit(void);
static void __exit cdevExit(void);

// 由于2.6.32没有定义,于是扩展kfifo函数
int kfifo_is_empty(struct kfifo *fifo);
int kfifo_is_full(struct kfifo *fifo);

// 指定模块初始化函数
module_init(cdevInit);
// 指定模块退出函数
module_exit(cdevExit);

struct file_operations myCdevFops = {
      .owner = THIS_MODULE,
      .open = cdevOpen,
      .release = cdevRelease,
      .read = cdevRead,
      .write = cdevWrite,
      .ioctl = cdevIoctl,
      .llseek = cdevLlseek,
};

struct myCdev {
      unsigned char* buffer;      // 用于临时缓冲
      struct kfifo* myQueue;
      wait_queue_head_t writeQueue;
      wait_queue_head_t readQueue;
      struct semaphore sem;
      spinlock_t lock;
      struct cdev cdev;
}myCdev;
```

## 五、其他

### 5.1曾用过的Linux内核源码下载地址:

https://mirrors.edge.kernel.org/pub/linux/kernel/

### 5.2用过的命令

```sh
cat /proc/kallsyms |grep "my_module"
dmesg |tail
insmod      将模块连接到正在运行的内核
rmmod      移除连接
readelf -s my_module.ko
cat /proc/devices
mknod /dev/my_module c 251 0
ls /dev/my_module -l
strace ./test.out
cat /dev/my_module more
gcc -DMY -o a a.c
cat /proc/cpuinfo
objdump -dmyfaulty.ko
```

### 5.3如果是编写应用层程序测试内核模块,则可以创建控制台应用程序。当然最好是使用虚拟机里提供的头文件,可以仿照内核环境的方法,将其拷贝出来,在项目属性里使用。



### 5.4 Tips

Linux系统可以Vmware 搭建虚拟机。比如说安装Ubuntu,将当前项目目录的文件作为共享文件夹,分享给Linux虚拟机。这样可以快速进行Make,测试。

Makefile模板

```makefile
obj-m = myCdev.o

all:
      make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
clean:
      rm *.ko *.symvers *.order *.mod.c *.o
```

参考例子

https://github.com/BeneficialCode/myCdev/tree/master

Dboykey 发表于 2021-11-19 21:44

环境部署?好!入门基础!

nelsonkl 发表于 2021-11-19 21:49

想大神致敬{:1_893:}{:1_893:}

YycAway 发表于 2021-11-19 21:54

感谢分享,基础且重要的步骤

NineteenC 发表于 2021-11-19 22:17

感谢分享

鹤舞九月天 发表于 2021-11-20 06:27

可以,不过个人感觉过程简单了点

v29292977 发表于 2021-11-20 07:35

已收藏,后面如果设计到这些,正好学习下

Jaybo 发表于 2021-11-20 09:04

谢谢大佬分享

tlf 发表于 2021-11-20 09:15

bigcan 发表于 2021-11-20 10:25

好文章,值得收藏
页: [1] 2
查看完整版本: Linux内核开发环境搭建