精华内容
下载资源
问答
  • linux 设备驱动开发详解
  • LINUX 设备驱动开发详解 华清远见 hen xiang xi
  • 宋宝华Linux设备驱动开发详解,国内最经典是Linux设备驱动开发教程,基于Linux2.6内核,非扫描的高清版PDF。
  • linux设备驱动开发详解

    千次阅读 2021-02-23 15:14:33
    书名:《Linux设备驱动开发详解》第二版 主机环境:Linux version 2.6.25-14.fc9.i686@Fedora arm-linux-gcc版本:version 4.4.1 开发板:mini2440-256M 版权信息:版权归作者M.Bing和博客园共同所有,可以随意转载,...

    书名:《Linux设备驱动开发详解》第二版

    主机环境:Linux version 2.6.25-14.fc9.i686@Fedora

    arm-linux-gcc版本:version 4.4.1

    开发板:mini2440-256M

    版权信息:版权归作者M.Bing和博客园共同所有,可以随意转载,但请保留此条信息!

    备注:由于作者水平有限,文章难免出错,欢迎大家指正,共同学习。

    一、字符设备简介   在Linux2.6内核中,使用cdev结构描述一个字符设备,cdev结构如下所示

    复制代码 struct cdev { struct kobject kobj; struct module owner; struct file_operations ops; /文件操作结构体/ struct list_head list; dev_t dev; /设备号 32位,其中12位主设备号,20次设备号/ unsigned int count; }; 复制代码   可以从dev_t获得主设备号和次设备号:

      MAJOR(dev_t dev)

      MINOR(dev_t dev)

      可以使用下面的宏通过主设备号和次设备号生成dev_t:

      MKDEV(int major, int minor)

      cdev结构内部还有一个重要的结构体:file_operations,其定义了字符设备驱动提供给虚拟文件系统的接口函数。

    在Linux2.6内核中使用以下函数操作cdev结构体:

    void cdev_init(struct cdev , struct file_operationd );/这个函数将cdev和file_operations联合在一起/ struct cdev *cdev_alloc(void); void cdev_put(struct cdev *,dev_t, unsigned); int cdev_add(struct cdev *, dev_t, unsigned); void cdev_del(struct cdev *); 各个函数的功能从其函数名就可以看出。

    二、file_operations结构体   在上面一节说了file_operations是一个重要的结构体,下面看看它的内部构成:

    复制代码 struct file_operations { struct module owner; loff_t(llseek) (struct file , loff_t, int); ssize_t(read) (struct file , char __user *, size_t, loff_t *); ssize_t(aio_read) (struct kiocb , char __user *, size_t, loff_t); ssize_t(write) (struct file , const char __user *, size_t, loff_t *); ssize_t(aio_write) (struct kiocb , const char __user *, size_t, loff_t); int (readdir) (struct file , void *, filldir_t); unsigned int (poll) (struct file , struct poll_table_struct *); int (ioctl) (struct inode , struct file *, unsigned int, unsigned long); int (mmap) (struct file , struct vm_area_struct *); int (open) (struct inode , struct file *); int (flush) (struct file ); int (release) (struct inode , struct file *); int (fsync) (struct file , struct dentry *, int datasync); int (aio_fsync) (struct kiocb , int datasync); int (fasync) (int, struct file , int); int (lock) (struct file , int, struct file_lock *); ssize_t(readv) (struct file , const struct iovec *, unsigned long, loff_t *); ssize_t(writev) (struct file , const struct iovec *, unsigned long, loff_t *); ssize_t(sendfile) (struct file , loff_t *, size_t, read_actor_t, void __user *); ssize_t(sendpage) (struct file , struct page *, int, size_t, loff_t *, int); unsigned long (get_unmapped_area) (struct file *, unsigned long, unsigned long, unsigned long, unsigned long); }; 复制代码

    每个函数都对应一个用户操作,但你不必实现每一个函数,一般你只需要实现以下几个函数:

    struct file_operations fops = { .read = device_read, .write = device_write, .open = device_open, .release = device_release }; 三、实现一个字符设备需要做哪些工作   1、填充file_operations中需要的函数,并实现这些函数

      2、实现加载模块时调用的函数XXX_init();下面是一个常用的例子:

    复制代码 dev_t IO_MAJOR = 0; //这里是动态分配设备号和动态创建设备结点需要用到的 struct cdev dev_c; struct class *my_class;

    static int __init IO_init(void) { int ret,err;

     ret = alloc_chrdev_region(&IO_MAJOR, 0, 1,DEVICE_NAME); //动态分配设备号
        if (ret) 
        { 
            printk("testmode register failure\n"); 
        unregister_chrdev_region(IO_MAJOR,1);
        return ret;
        } 
        else 
        { 
            printk("testmode register success\n"); 
        } 
    
     cdev_init(&dev_c, &s3c6410_IO_fops);
    
       err = cdev_add(&dev_c, IO_MAJOR, 1);
     if(err)
        {
            printk(KERN_NOTICE "error %d adding FC_dev\n",err);
             unregister_chrdev_region(IO_MAJOR, 1);
             return err;
           }
    
    
    
    my_class = class_create(THIS_MODULE, DEVICE_NAME);//动态创建设备结点
     if(IS_ERR(my_class))
     { 
         printk("ERR:cannot create a cdev_class\n");  
        unregister_chrdev_region(IO_MAJOR, 1);
        return -1;
        }
    
    
    device_create(my_class,NULL, IO_MAJOR, 0, DEVICE_NAME);
    printk(DEVICE_NAME "initialized.\n");
    return 0;

    } 复制代码 要注意的是,在上面的函数中,没有驱动模块加载失败时的处理,所以在实际的应用过程在每一步加载失败时,跳转到相应的出错处理,在出错处理中将前面以注册的函数依次卸载。

      图3-1为字符设备驱动的结构,字符设备驱动与字符设备以及字符设备驱动与用户空间访问该设备的程序之间的关系:

                                                                                          图3-1 字符设备内部关系

    四、示例代码

    复制代码 /*

    • =====================================================================================
    • Filename: testmode.c
    • Description:
    • Version: 1.0
    • Created: 2013-5-29
    • Revision: none
    • Compiler: gcc
    • Author: M.Bing
    • Company: Deviser of TinJing
    • =====================================================================================
    • /

    #include <linux/miscdevice.h> #include <linux/delay.h> #include <asm/irq.h> #include <mach/hardware.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/mm.h> #include <linux/fs.h> #include <linux/types.h> #include <linux/delay.h> #include <linux/moduleparam.h> #include <linux/slab.h> #include <linux/errno.h> #include <linux/ioctl.h> #include <linux/cdev.h> #include <linux/string.h> #include <linux/list.h> #include <linux/pci.h> #include <asm/uaccess.h> #include <asm/atomic.h> #include <asm/unistd.h>

    #include <plat/regs-gpio.h> #include <plat/s3c6410.h> #include <plat/gpio-cfg.h> #include <asm/gpio.h> #include <plat/gpio-bank-l.h> #include <plat/gpio-bank-n.h>

    #include <asm/uaccess.h> #include <asm/atomic.h> #include <asm/unistd.h>

    #define DEVICE_NAME "io_mode"

    #define TESTK08K15 0 //Test GPIOK8--GPIOK15 #define TESTL00L07 1 //Test GPIOL0--GPIOL7

    unsigned int UserCmd = 0;

    /Set GPK12 GPK13 GPK14 GPK15 INPUT/

    // static int IO_open(struct inode inode, struct file file) { int reg; /**Init GPIOK8--GPIOK15**/ reg = readl(S3C64XX_GPKCON1); reg &=(~0xffffffff);/Use GPK8 ~GPK15 8PIN/ /Set GPK12 GPK13 GPK14 GPK15 INPUT/ /Set GPK8 GPK9 GPK10 GPK11 OUTPUT/ reg |=(0x00001111); writel(reg,S3C64XX_GPKCON1);

    reg = readl(S3C64XX_GPKPUD);
    reg &= (~0xff0000);
    reg |= (0xaa0000); //GPK8   GPK9   GPK10 GPK11  pull
    writel(reg,S3C64XX_GPKPUD);

    /**Init GPIOL0--GPIOL7**/ reg = readl(S3C64XX_GPLCON); reg &= (~0xffffffff); reg |= (0x00001111); writel(reg,S3C64XX_GPLCON);//L0-L3 OUTPUT L4-L7 INPUT

    reg = readl(S3C64XX_GPLPUD);
    reg &=(~0x0000ffff);
    reg |=(0x000000aa);//L0-L3 PULL UP
    writel(reg,S3C64XX_GPLPUD);
    
    return 0;

    }

    static int IO_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) {

    if (arg > 4)
    {
        return -EINVAL;
    
    }
    UserCmd = cmd;
    switch(UserCmd)
        {
            case TESTK08K15:
                printk("\n-----------UserCmd = TESTK08K15------------\n");
                break;
            case TESTL00L07:
                printk("\n-----------UserCmd = TESTL00L07------------\n");
                break;
            default:
                printk("\n-----------Unkonw UserCmd = %d------------\n",cmd);
                break;
        }
    
    return 0;

    }

    static ssize_t IO_read( struct file *file, char __user *buff, size_t size, loff_t *loff) { unsigned int reg;

    if(UserCmd == TESTK08K15)
        {
            reg = readl(S3C64XX_GPKDAT);
            buff[0] = ((reg | 0xffff0fff) >> 12)&0x0f;//get K12 - K15 data
            //printk("IO_read buff[0] = %d\n",buff[0]);                     
    
        }
    if(UserCmd == TESTL00L07)
        {
            reg = readl(S3C64XX_GPLDAT);
            buff[0] = ((reg | 0xffffff0f) >> 4)&0x0f;//get L4 - L7 data
        }
    
    return 0;

    } static ssize_t IO_write( struct file *file, const char __user *buff, size_t size, loff_t *loff) { unsigned int reg; if(UserCmd == TESTK08K15) { //printk("IO_write buff[0] = %d\n",buff[0]); reg = readl(S3C64XX_GPKDAT); reg &= (0xf00); reg |=( buff[0] << 8)& 0xf00; writel(reg,S3C64XX_GPKDAT); } if(UserCmd == TESTL00L07) { reg = readl(S3C64XX_GPLDAT); reg &= (0x0f); reg |= (buff[0]) & 0x0f; writel(reg,S3C64XX_GPLDAT); } return 0; }

    static struct file_operations s3c6410_IO_fops = { .owner = THIS_MODULE, .open = IO_open, .ioctl = IO_ioctl, .read = IO_read, .write = IO_write

    };

    dev_t IO_MAJOR = 0; //这里是动态分配设备号和动态创建设备结点需要用到的 struct cdev dev_c; struct class *my_class;

    static int __init IO_init(void) { int ret,err;

     ret = alloc_chrdev_region(&IO_MAJOR, 0, 1,DEVICE_NAME); //动态分配设备号
        if (ret) 
        { 
            printk("testmode register failure\n"); 
        unregister_chrdev_region(IO_MAJOR,1);
        return ret;
        } 
        else 
        { 
            printk("testmode register success\n"); 
        } 
    
     cdev_init(&dev_c, &s3c6410_IO_fops);
    
       err = cdev_add(&dev_c, IO_MAJOR, 1);
     if(err)
        {
            printk(KERN_NOTICE "error %d adding FC_dev\n",err);
             unregister_chrdev_region(IO_MAJOR, 1);
             return err;
           }
    
    
    
    my_class = class_create(THIS_MODULE, DEVICE_NAME);//动态创建设备结点
     if(IS_ERR(my_class))
     { 
         printk("ERR:cannot create a cdev_class\n");  
        unregister_chrdev_region(IO_MAJOR, 1);
        return -1;
        }
    
    
    device_create(my_class,NULL, IO_MAJOR, 0, DEVICE_NAME);
    printk(DEVICE_NAME "initialized.\n");
    return 0;

    }

    static void __exit IO_exit(void) {

     device_destroy(my_class, IO_MAJOR);
      class_destroy(my_class);
     unregister_chrdev_region(IO_MAJOR,1);
      printk("testmode_exit \n");

    }

    module_init(IO_init); module_exit(IO_exit);

    MODULE_AUTHOR("M.Bing"); MODULE_DESCRIPTION("s3c6410 IO test."); MODULE_LICENSE("GPL"); 复制代码 以上就是良许教程网为各位朋友分享的Linux相关知识。

    展开全文
  • 本博实时更新《Linux设备驱动开发详解(第3版)》(即《Linux设备驱动开发详解:基于最新的Linux 4.0内核》)的最新进展。 目前已经完成稿件。 2015年8月9日,china-pub开始上线预售: ... 2015年8月20日,各路朋友报喜...

    本博实时更新《Linux设备驱动开发详解(第3版)》的最新进展。 目前已经完成稿件。

    2015年8月9日,china-pub开始上线预售:

    http://product.china-pub.com/4733972

    2015年8月20日,各路朋友报喜说已经拿到了书。

    本书已经rebase到开发中的Linux 4.0内核,案例多数基于多核CORTEX-A9平台

    本书微信公众号二维码, 如需联系请扫描下方二维码

    [F]是修正或升级;[N]是新增知识点;[D]是删除的内容

     

    第1章 《Linux设备驱动概述及开发环境构建》
    [D]删除关于LDD6410开发板的介绍
    [F]更新新的Ubuntu虚拟机
    [N]添加关于QEMU模拟vexpress板的描述

     

    第2章 《驱动设计的硬件基础》

    [N]增加关于SoC的介绍;
    [N]增加关于eFuse的内容;
    [D]删除ISA总线的内容了;
    [N]增加关于SPI总线的介绍;
    [N]增加USB 3.0的介绍;
    [F]修正USB同步传输方式英文名;
    [D]删除关于cPCI介绍;
    [N]增加关于PCI Express介绍;
    [N]增加关于Xilinx ZYNQ的介绍;
    [N]增加SD/SDIO/eMMC的章节;
    [D]删除“原理图分析的内容”一节;
    [N]增加通过逻辑分析仪看I2C总线的例子;

     

    第3章 《Linux内核及内核编程》

    [N]新增关于3.X内核版本和2015年2月23日 Linux 4.0-rc1
    [N]新增关于内核版本升级流程以及Linux社区开发模式讲解
    [N]新增关于Linux内核调度时间的图式讲解
    [N]新增关于Linux 3.0后ARM架构的变更的讲解
    [N]新增关于TASK_KILLABLE状态的简介
    [N]新增Linux内存管理图式讲解

    [F]修正Kconfig和Makefile中的一些表述
    [D]删除关于x86启动过程讲解
    [N]新增ARM Linux启动过程讲解
    [N]新增关于likely()和unlikely()讲解
    [N]新增toolchain的讲解,以及toolchain的几种浮点模式


    第4章 《Linux内核模块》
    [F]改正关于模块使用非GPL license的问题;
    [F]修正关于__exit修饰函数的内存管理

    第5章 《Linux文件系统与设备文件》
    [F]修正关于文件系统与块设备驱动关系图;
    [N]增加应用到驱动的file操作调用图;
    [N]增加通过netlink接受内核uevent的范例;
    [N]增加遍历sysfs的范例;

    [N]增加为kingston U盘编写udev规则的范例;
    [F]更新udev规则,以符合新版本;
    [N]增加udevadm的讲解;
    [N]高亮Android vold
     
    第6章 《字符设备驱动》
    [F]更新file_operations的定义,升级ioctl()原型;
    [N]增加关于Linux access_ok()的讲解以及Linux内核安全漏洞的说明;
    [F]修正globalmem的编码风格;
    [F]在globalmem支持2个以上实例的时候,从直接2个实例,升级为支持N个实例;

    第7章 《Linux设备驱动中的并发控制》
    [N]绘图深入讲解单核和多核下的各种竞态;
    [N]增加关于编译乱序,执行乱序,编译屏障和内存屏障的讲解;
    [N]增加关于ARM LDREX/STREX指令的讲解;
    [N]对spin_lock单核和多核的使用场景进行深入分析;

    [F]重新整理RCU的讲解方法和实例;
    [F]明确指明信号量已过时;
    [F]将globalmem中使用的信号量换为mutex。


    第8章 《Linux设备驱动中的阻塞与非阻塞I/O》
    [N]新增阻塞和非组塞的时序图
    [F]修正关于等待队列头部、等待队列元素的一些中文说法
    [N]添加等待队列的图形描述
    [F]修正globalfifo的编码风格
    [F]修正globalfifo可读可写的if判断为while判断
    [N]新增select的时序图
    [N]新增EPOLL的章节


    第9章 《Linux设备驱动中的异步通知与异步I/O》
    [F]修正关于glibc AIO支持
    [F]修正关于内核AIO支持
    [F]修正驱动AIO接口
    [D]删除关于驱动AIO支持的错误实例
    [N]高亮C10问题

    第10章 《中断与时钟》
    [N]增加关于ARM GIC的讲解
    [N]增加关于irq_set_affinity() API的讲解
    [N]增加关于devm_request_irq() API的讲解
    [N]增加关于request_any_context_irq() API的讲解

    [F]修正interrupt handler原型
    [F]修正work queue原型
    [N]新增关于Concurrency-managed workqueues讲解
    [N]增加关于ksoftirqd讲解
    [N]增加关于request_threaded_irq()讲解
    [D]删除s3c6410 rtc驱动中断实例
    [N]新增GPIO按键驱动中断实例
    [N]新增hrtimer讲解和实例
    [F]修正second设备编码风格

    第11章 《内存与I/O访问》
    [F]修正关于页表级数的描述,添加PUD
    [F]修正page table walk的案例,使用ARM Linux pin_page_for_write
    [N]新增关于ARM Linux内核空间虚拟地址分布
    [F]修正关于内核空间与用户空间界限
    [N]新增关于DMA、NORMAL和HIGHMEM ZONE的几种可能分布
    [N]新增关于buddy的介绍
    [F]修正关于用户空间malloc的讲解
    [N]增加mallopt()的案例
    [N]增加关于devm_ioremap、devm_request_region()和devm_request_mem_region()的讲解
    [N]增加关于readl()与readl_relaxed()的区别,writel()与writel_relaxed()的区别

    [F]更新vm_area_struct的定义
    [F]修正nopage() callback为fault() callback
    [N]增加io_remap_pfn_range()、vm_iomap_memory()讲解
    [F]强调iotable_init()静态映射目前已不太推荐
    [N]增加关于coherent_dma_mask的讲解
    [N]讲解dma_alloc_coherent()与DMA ZONE关系
    [N]提及了一致性DMA缓冲区与CMA的关系
    [N]增加关于dmaengine驱动和API的讲解

     

    第12章 《工程中的Linux设备驱动》
    [F]更名为《Linux设备驱动的软件架构思想》;
    [N]本章新增多幅图片讲解Linux设备驱动模型;
    [N]新增内容详细剖析为什么要进行设备与驱动的分离,platform的意义;
    [N]新增内容详细剖析为什么Linux设备驱动要分层,枚举多个分层实例;
    [N]新增内容详细剖析Linux驱动框架如何解耦,为什么主机侧驱动要和外设侧驱动分离;
    [N]DM9000实例新增关于在dts中填充平台信息的内容;
    [N]新增内容讲解驱动核心层的3大功能;
    [N]新增内容以面向对象类泛化对比Linux驱动;
    [N]SPI案例部分新增通过dts填充外设信息;

    [F]从tty, LCD章节移出架构部分到本章

     

    第13章 《Linux块设备驱动》
    [N]介绍关于block_device_operations的check_events成员函数
    [N]添加关于磁盘文件系统,I/O调度关系的图形
    [F]更新关于request_queue、request、bio、segment关系的图形
    [F]淘汰elv_next_request
    [F]淘汰blkdev_dequeue_request
    [N]添加关于blk_start_request描述
    [F]淘汰Anticipatory I/O scheduler
    [N]添加关于ZRAM块设备驱动实例
    [F]更新针对内核4.0-rc1的vmem_disk
    [N]添加关于vmem_disk处理I/O过程的图形
    [N]增加关于Linux MMC子系统的描述

     

    第14章 《Linux终端设备驱动》
    [D]整章全部删除,部分架构内容前移到第12章作为驱动分层实例

     

    第15章 《Linux I2C核心、总线与设备驱动》

    [F]修正i2c_adpater驱动的案例
    [N]增加关于在device tree中增加i2c设备的方法的描述

     

    第16章 《Linux网络设备驱动》

    [F]本章顺序从第16章前移到第14章
    [N]澄清sk_buff head、data、tail、end指针关系
    [F]更新sk_buff定义
    [F]澄清skb_put、skb_push、skb_reserve
    [N]增加netdev_priv的讲解,加入实例
    [N]增加关于get_stats()可以从硬件读统计信息的描述

    [F]修正关于net_device_stats结构体的定义位置
    [F]修正关于统计信息的更新方法

     

    第17章 《Linux音频设备驱动》

    [D] 本章直接删除

     

    第18章 《LCD设备驱动》

     

    [D] 本章直接删除,部分架构内容前移到第12章

     

    第19章 《Flash设备驱动》

    [D] 本章直接删除

     

    第20章 《USB主机与设备驱动》
    [F]前移到第16章;
    [F]更名为《USB主机、设备与Gadget驱动》;
    [N]增加关于xHCI的介绍;
    [F]修正usb gadget驱动为function驱动;
    [D]删除OHCI实例;
    [N]添加EHCI讲解和Chipidea EHCI实例;
    [F]修正iso传输实例;
    [F]修正usb devices信息到/sys/kernel/debug/usb/devices
    [N]介绍module_usb_driver;
    [N]介绍usb_function;
    [N]介绍usb_ep_autoconfig;
    [N]介绍usb_otg;

    [D]删除otg_transceiver;

     

    第21章 《PCI设备驱动》
    [D]整章删除

     

    第22章 《Linux设备驱动的调试》

    [F]变为第21章;

    [D]把实验室环境建设相关的节移到第3章;

    [F]修正关于gdb的set step-mode的含义讲解;

    [F]增加关于gdb的set命令的讲解;

    [F]增加gdb call命令的案例

    [D/N]删除手动编译工具链的代码,使用crosstool-ng;
    [N]更新toolchain的下载地址(codesourcery -> memtor),加入linaro下载地址;
    [N]增加pr_fmt的讲解;
    [N]增加关于ignore_loglevel bootargs的讲解;
    [N]增加EARLY_PRINTK和DEBUG_LL的讲解;

    [F]调整proc的范例,创建/proc/test_dir/test_rw;
    [N]修正关于3.10后内核proc实现框架和API的变更;
    [N]增加关于BUG_ON和WARN_ON的讲解
    [F]不再以BDI-2000为例,改为ARM DS-5;
    [N]增加关于ARM streamline性能分析器的介绍;
    [N]增加使用qemu调试linux内核的案例;
    [F]调整Oops的例子,使用globalmem,平台改为ARM;
    [F]更新LTT为LTTng。

     

    第23章 《Linux设备驱动的移植》
    [D]整章删除

     

    全新的章节

     

    第17章  《I2C、SPI、USB架构类比》

     

    本章导读

    本章类比I2C、SPI、USB的结构,从而更进一步帮助读者理解本书第12章的内容,也进一步实证Linux驱动万变不离其宗的道理。

     

    第18章  《Linux设备树(Device Tree)》

     

    本章导读

    本章将介绍Linux设备树(Device Tree)的起源、结构和因为设备树而引起的驱动和BSP变更。

    18.1节阐明了ARM Linux为什么要采用设备树。

    18.2节详细剖析了设备树的结构、结点和属性,设备树的编译方法以及如何用设备树来描述板上的设备、设备的地址、设备的中断号、时钟等信息。

    18.3节讲解了采用设备树后,驱动和BSP的代码需要怎么改,哪些地方变了。

    18.4节补充了一些设备树相关的API定义以及用法。

    本章是相对《Linux设备驱动开发详解(第2版)》全新的一章内容,也是步入内核3.x时代后,嵌入式Linux工程师必备的知识体系。

     

     

     

    第19章  《Linux的电源管理》

     

    本章导读

    Linux在消费电子领域的应用已经铺天盖地,而对于消费电子产品而言,省电是一个重要的议题。

    本章将介绍Linux设备树(Device Tree)的起源、结构和因为设备树而引起的驱动和BSP变更。

    19.1节阐述了Linux电源管理的总体架构。

    19.2~19.8节分别论述了CPUFreq、CPUIdle、CPU热插拔以及底层的基础设施Regulator、OPP以及电源管理的调试工具PowerTop。

    19.9节讲解了系统Suspend to RAM的过程以及设备驱动如何提供对Suspend to RAM的支持。

    19.10节讲解了设备驱动的Runtimesuspend。

    本章是相对《Linux设备驱动开发详解(第2版)》全新的一章内容,也是Linux设备驱动工程师必备的知识体系。

     

     

     

    第20章 《Linux芯片级移植与底层驱动》

     

    本章导读

    本章主要讲解,在一个新的ARM SoC上,如何移植Linux。当然,本章的内容也适合MIPS、PowerPC等其他的体系架构。

    第20.1节先总体上介绍了Linux 3.x之后的内核在底层BSP上进行了哪些优化。

    第20.2节讲解了如何提供操作系统的运行节拍。

    第20.3节讲解了中断控制器驱动,以及它是如何为驱动提供标准接口的。

    第20.4节讲解多核SMP芯片的启动。

    第20.6~20.9节分别讲解了作为Linux运行底层基础设施的GPIO、pinctrl、clock和dmaengine驱动。

    本章相对《Linux设备驱动开发详解(第2版)》几乎是全新的一章内容,有助于工程师理解驱动调用的底层API的来源,以及直接有助于进行Linux的平台移植。

     

    展开全文
  • Linux设备驱动开发详解(第2 版) 作者华清远见 第1 章 Linux设备驱动概述及开发环境构建 本章目标 本章将介绍 Linux 设备驱动开发的基本概念并对本书所基于的平台和开发环境进行讲解 1.1 节阐明了设备驱动的概念和...
  • Linux内核驱动开发详解,基于kernel4.0,对驱动工程师很有帮助
  • 嵌入式Linux设备驱动开发详解 嵌入式Linux设备驱动开发详解 嵌入式Linux设备驱动开发详解
  • 预览合集,请购买正版书籍:全部有书签导引,便于查阅 Linux 设备驱动程序...Linux 设备驱动开发详解 第2版 宋宝华 文字_.pdf Linux 设备驱动开发详解 4.0核 ARM.pdf Linux 设备驱动程序内核机制 深入 陈学松著_.pdf
  • Linux设备驱动开发详解:基于最新的Linux 4.0内核》

    《Linux设备驱动开发详解:基于最新的Linux 4.0内核》


    china-pub   天猫     dangdang   京东   


    China-pub 8月新书销售榜



    推荐序一

      技术日新月异,产业斗转星移,滚滚红尘,消逝的事物太多,新事物的诞生也更迅猛。众多新生事物如灿烂烟花,转瞬即逝。当我们仰望星空时,在浩如烟海的专业名词中寻找,赫然发现,Linux的生命力之旺盛顽强,斗志之昂扬雄壮,令人称奇。它正以摧枯拉朽之势迅速占领包括服务器、云计算、消费电子、工业控制、仪器仪表、导航娱乐等在内的众多应用领域,并逐步占据许多WINCE、VxWorks的传统嵌入式市场。

      Linux所及之处,所向披靡。这与Linux的社区式开发模式,迅速的迭代不无关系。Linux每2~3月更新一次版本,吸纳新的体系架构、芯片支持、驱动、内核优化和新特性,这使得Linux总是能够在第一时间内迎合用户的需求,快速地适应瞬息万变的市场。由Linux以及围绕着Linux进行产品研发的众多企业和爱好者构成了一个庞大的Linux生态圈。而本书,无疑给这个庞大的生态圈注入了养料。

      然而,养料的注入应该是持续不断的。至今,Linux内核的底层BSP、驱动框架和内核实现发生了许多变更,本书涵盖了这些新的变化,这将给予开发者更多新的帮助。内核的代码不断重构并最优化,而本书也无疑是一次重大的重构。

      生命不息,重构不止。

      周立功

      推荐序二

      在翻译了《Understanding the Linux Kernel》和《Linux Kernel Development》这两本书后,每当有读者询问如何学习Linux内核时,我都不敢贸然给出建议。如此庞大的内核,各个子系统之间的关系错综复杂,代码不断更新和迭代,到底该从何入手?你的出发点是哪里?你想去的彼岸又是哪里?相应的学习方法都不同。

      一旦踏入Linux内核领域,要精通Linux内核的精髓,几乎没有捷径可走。尽管通往山顶的路有无数条,但每条路上都布满荆棘,或许时间和毅力才是斩荆披棘的利器。

      从最初到现在,Linux内核的版本更新达上千个,代码规模不断增长,平均每个版本的新增代码有4万行左右。在源代码的10个主要子目录(arch、init、include、kernel、mm、IPC、fs、lib、net、drivers)中,驱动程序的代码量呈线性增长趋势。

      从软件工程角度来看内核代码的变化规律,Linux的体系结构相对稳定,子系统数变化不大,平均每个模块的复杂度呈下降趋势,但系统整体规模和复杂性分别呈超线性和接近线性增长趋势。drivers和arch等模块的快速变化是引起系统复杂性增加的主因。那么,在代码量最多的驱动程序中,有什么规律可循?最根本的又是什么?

      本书更多的是关于Linux内核代码背后机理的讲解,呈现给读者的是一种思考方法,让读者能够在思考中举一反三。尽管驱动程序只是内核的一个子系统,但Linux内核是一种整体结构,牵一发而动全局,对Linux内核其他相关知识的掌握是开发驱动的基础。本书的内容包括中断、定时器、进程生命周期、uevent、并发、编译乱序、执行乱序、等待队列、I/O模型、内存管理等,实例代码也被大幅重构。

      明代著名的思想家王明阳有句名言“知而不行,是为不知;行而不知,可以致知”。因此在研读本书时,你一定要亲身实践,在实践之后要提升思考,如此,你才可以越过代码本身而看到内核的深层机理。

      陈莉君

      西安邮电大学


    媒体评论

      十多年前,我在海外一家路由器公司从事底层软件开发时,一本《Linux Device Driver》(LDD)使我受益匪浅。近年来,我在从事基于ARM的嵌入式操作系统教学时发现,很多Linux设备驱动中的新技术,比如Device Tree、sysfs等,在LDD3中均没有涉及。而市面上的翻译书晦涩难懂,有的还不如英文原书好理解。宋宝华是我尊敬的技术人员,十年如一日,在Linux内核及设备驱动领域潜心耕耘,堪称大师。本书无论从汉语的遣词造句,案例的深入浅出,还是对前沿技术的掌握,对难点技术丝丝入扣的分析,都体现出了强烈的“工匠精神”,堪称经典,值得推荐。
      ——Xilinx前大中华区大学计划经理、慕客信CEO  谢凯年


      设备驱动程序是连接计算机软件和硬件的纽带和桥梁,开发者在嵌入式操作系统的开发移植过程中,有将近70%~80%的精力都用在了驱动程序的开发与调试方面。这就对设备驱动程序开发人员提出了极高的要求。开发者不仅要同时具备软件和硬件的知识和经验,而且还要不断地学习、更新自己,以便跟上嵌入式系统日新月异的发展。研究前人的总结和动手实践是不断提高自己的有效途径。虽然市面上已经有多种设备驱动的书籍,但本书在总结Linux设备驱动程序方面仍然非常具有特色。它用理论联系实际,尤其是提供了大量的实例,对读者深入地理解并掌握各种驱动程序的编写大有裨益。
      ——飞思卡尔半导体(中国)有限公司数字网络软件技术方案部总监  杨欣欣博士


      一位优秀的设备驱动开发工程师需要具备多年嵌入式软件和硬件开发经验的积累,本书针对Linux设备驱动开发相关的设计思想、框架、内核,深入浅出,结合代码,从理论到实践进行重点讲解。毫无疑问,本书可谓一把通向设备驱动大师殿堂之门的金钥匙,它将激发你的味蕾,带你“品尝”嵌入式设备驱动开发这道“美味佳肴”,掩卷沉思,意味深长。
      ——ARM中国在线社区经理   宋斌


      作者长期从事嵌入式Linux开发和教学工作,擅长Linux驱动开发,并跟踪开源软件和嵌入式处理器技术的最新发展,撰写本书,书中内容新鲜实用。作者针对ARM和移动便携式设备的兴起,在书中添加了ARM Linux 设备树和Linux电源管理系统架构及驱动的内容,书中关于Linux设备驱动的软件架构思想的章节也很有特色。
      ——中国软件行业协会嵌入式系统分会副理事长 何小庆


    封面:


    展开全文
  • 嵌入式linux设备驱动开发详解嵌入式linux设备驱动开发详解
  • LINUX 设备驱动开发详解 + 源码 非常有用
  • 深入理解linux内核英文原版+linux设备驱动开发详解深入理解linux内核英文原版+linux设备驱动开发详解深入理解linux内核英文原版+linux设备驱动开发详解
  • Linux设备驱动开发详解-基于最新的Linux4.0内核(第三版),包括很多Linux系统驱动的程序代码,应该大多数直接可以调试成功。
  • 字符设备、块设备、TTY设备、I2C设备、LCD设备、音频设备、USB设备、网络设备、PCI设备等Linux设备驱动的架构和框架中各个复杂数据架构和函数的关系,并讲解了大量Linux驱动开发的大量实例...

    内容简介

    本书是一本介绍Linux设备驱动开发理论、框架与实例的书,本书以Linux 2.6版本内核为蓝本,详细介绍自旋锁、信号量、完成量、中断顶/底半部、定时器、内存和I/O映射以及异步通知、阻塞I/O、非阻塞I/O等Linux设备驱动理论;字符设备、块设备、TTY设备、I2C设备、LCD设备、音频设备、USB设备、网络设备、PCI设备等Linux设备驱动的架构和框架中各个复杂数据架构和函数的关系,并讲解了大量Linux驱动开发的大量实例,使读者能够独立开发各类Linux设备驱动。
      本书内容全面,实例丰富,操作性强,语言通俗易懂,适合广大Linux开发人员、嵌入式工程师参考使用。

     

    图书比价网

    展开全文
  • Linux 设备驱动开发详解(第2版)高清版,linux设备驱动开发,底层开发。
  • Linux从未停歇脚步。Linus Torvalds,世界上最伟大的程序员之一,Linux内核的创始人,Git的缔造者,仍然在没日没夜的合并补丁,升级内核。做技术,从来没有终南捷径,拼的就是坐冷板凳的傻劲。 这是一个连阅读都被...
  • Linux设备驱动开发详解:基于最新的Linux 4.0内核.pdf 宋宝华 Linux布道者,知名嵌入式系统专家,《Essential Linux Device Drivers》译者。作为最早从事Linux内核与设备驱动研究的专家之一,他在众多国内外知名...
  • 本书将字符设备,块设备,TTY设备,I2C设备,LCD设备,Flash设备,网络设备,音频设备,USB设备,PCI设备等复杂设备驱动的框架作为核心内容,讲解了大量Linux驱动开发的大量实例.并且书中还对Linux设备驱动开发环境建设,驱动的...
  • 嵌入式linux设备驱动开发详解SD.rar 内有丰富驱动实例,可以学习参考一下
  • linux 设备驱动开发详解 高清 非扫描 pdf
  • 嵌入式Linux设备驱动开发详解光盘;实例代码: ----本书部分实例的源代码;lib.tar.bz2: ----相关库 图片 ----书中所有插图
  • 嵌入式Linux设备驱动开发详解 PDF文件
  • KernelAndDriver:Linux设备驱动开发详解源码,可直接make编译

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 23,702
精华内容 9,480
关键字:

linux设备驱动开发详解

linux 订阅