Linux内核开发环境搭建
大学时学习嵌入式驱动程序设计,留下的东西。关于Linux内核开发环境在Windows上的搭建,希望对坛友们有帮助吧。
一、安装Visual Studio
负荷选择使用c++的Linux开发
二、创建项目
这里选择Linux空项目
三、配置内核源码目录
根据需要下载对应内核版本的文件到本地目录,然后vs配置头文件目录。这样就可以享受vs的代码智能提示了。虽然大学的时候,老师都是在Ubuntu虚拟机下用Gedit手敲内核函数,实在佩服当时的刘老师记忆真好。
四、例子源文件
新建一个xx.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用过的命令
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 -d myfaulty.ko
5.3如果是编写应用层程序测试内核模块,则可以创建控制台应用程序。当然最好是使用虚拟机里提供的头文件,可以仿照内核环境的方法,将其拷贝出来,在项目属性里使用。
5.4 Tips
Linux系统可以Vmware 搭建虚拟机。比如说安装Ubuntu,将当前项目目录的文件作为共享文件夹,分享给Linux虚拟机。这样可以快速进行Make,测试。
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