最全的Linux教程,Linux从入门到精通
======================
-
linux从入门到精通(第2版)
-
Linux系统移植
-
Linux驱动开发入门与实战
-
LINUX 系统移植 第2版
-
Linux开源网络全栈详解 从DPDK到OpenFlow
第一份《Linux从入门到精通》466页
====================
内容简介
====
本书是获得了很多读者好评的Linux经典畅销书**《Linux从入门到精通》的第2版**。本书第1版出版后曾经多次印刷,并被51CTO读书频道评为“最受读者喜爱的原创IT技术图书奖”。本书第﹖版以最新的Ubuntu 12.04为版本,循序渐进地向读者介绍了Linux 的基础应用、系统管理、网络应用、娱乐和办公、程序开发、服务器配置、系统安全等。本书附带1张光盘,内容为本书配套多媒体教学视频。另外,本书还为读者提供了大量的Linux学习资料和Ubuntu安装镜像文件,供读者免费下载。
本书适合广大Linux初中级用户、开源软件爱好者和大专院校的学生阅读,同时也非常适合准备从事Linux平台开发的各类人员。
需要《Linux入门到精通》、《linux系统移植》、《Linux驱动开发入门实战》、《Linux开源网络全栈》电子书籍及教程的工程师朋友们劳烦您转发+评论
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
struct device \*device\_create(struct class \*class, struct device \*parent,
dev\_t devt, void \*drvdata, const char \*fmt, ...)
{
va_list vargs;
struct device \*dev;
va\_start(vargs, fmt);
dev = device\_create\_vargs(class, parent, devt, drvdata, fmt, vargs);
va\_end(vargs);
return dev;
}
device_create用于创建设备。
class:该设备依附的类
parent:父设备
devt:设备号(此处的设备号为主次设备号)
drvdata:私有数据
fmt:设备名。
device_create能自动创建设备文件是依赖于udev这个应用程序。udev是一种工具,它能够根据系统中的硬件设备的状态动态更新设备文件,包括设备文件的创建,删除等。设备文件通常放在/dev目录下。使用udev后,在/dev目录下就只包含系统中真正存在的设备。
下面就来写一个驱动程序并使用这两个函数来创建设备。
程序:
#define CHRDEV\_MAJOR 240 // 主设备号
#define CHRDEV\_MAION 0 // 次设备号
#define CHRDEV\_COUNT 1 // 次设备号个数
#define CHRDEV\_NAME "testchrdev"
struct led\_cdev
{
struct cdev chrdevcdev;
int major;
dev\_t dev;
struct class \*led_dev_class;
};
static struct led\_cdev leddev;
ssize\_t chrdev\_read (struct file \*file, char __user \*usr, size\_t size, loff\_t \*loff)
{
printk("%s\r\n",\_\_func\_\_);
return 0;
}
int chrdev\_open (struct inode \*inode, struct file \*file)
{
printk("%s\r\n",\_\_func\_\_);
return 0;
}
int chrdev\_release (struct inode \*inode, struct file \*file)
{
printk("%s\r\n",\_\_func\_\_);
return 0;
}
struct file\_operations fops =
{
.open = chrdev_open,
.read = chrdev_read,
.release = chrdev_release,
};
static int __init chrdev\_init(void)
{
int ret = 0,error = 0;
struct device \*devices;
error = alloc\_chrdev\_region(&leddev.dev,CHRDEV_MAION,CHRDEV_COUNT,CHRDEV_NAME); // 注册设备号
printk("MAJOR = %d MINOR = %d\r\n",MAJOR(leddev.dev),MINOR(leddev.dev));
if(error < 0){
printk("alloc\_chrdev\_region error\r\n");
ret = -EBUSY;
goto fail;
}
leddev.major = MAJOR(leddev.dev);
cdev\_init(&leddev.chrdevcdev, &fops); // 绑定字符设备操作函数集
error = cdev\_add(&leddev.chrdevcdev,leddev.dev,CHRDEV_COUNT); // 添加字符设备
if(error < 0){
printk("cdev\_add error\r\n");
ret = -EBUSY;
goto fail1;
}
// 创建类,类名为testledclass
leddev.led_dev_class = class\_create(THIS_MODULE, "testledclass");
if (IS\_ERR(leddev.led_dev_class)){
printk("class\_create error\r\n");
ret = -EBUSY;
goto fail2;
}
// 创建设备
devices = device\_create(leddev.led_dev_class, NULL, MKDEV(leddev.major,0), NULL, "testled");
if(NULL == devices){
printk("device\_create error\r\n");
ret = -EBUSY;
goto fail3;
}
return 0;
fail3:
class\_destroy(leddev.led_dev_class);/\* 删除类 \*/
fail2:
cdev\_del(&leddev.chrdevcdev);/\* 删除cdev \*/
fail1:
unregister\_chrdev\_region(leddev.dev,CHRDEV_COUNT);
fail:
return ret;
}
static void __exit chrdev\_exit(void)
{
device\_destroy(leddev.led_dev_class,MKDEV(leddev.major,0));/\* 卸载设备 \*/
class\_destroy(leddev.led_dev_class);/\* 删除类 \*/
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.youkuaiyun.com/topics/618635766)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**