《Verilog数字系统设计教程(第2版).pdf》
Verilog数字系统设计教程(第2版).pdf
https://github.com/shigh1005/pdf_book
《Linux设备驱动开发详解:基于最新的Linux 4.0内核.pdf》
《Linux设备驱动开发详解(基于最新4.0内核)》前言
Linux从未停歇脚步。Linus Torvalds,世界上最伟大的程序员之一,Linux内核的创始人,Git的缔造者,仍然在没日没夜的合并补丁,升级内核。做技术,从来没有终南捷径,拼的就是坐冷板凳的傻劲。
这是一个连阅读都被碎片化的时代,在这样一个时代,人们趋向于激进、浮躁。内心的不安宁使我们极难静下心来研究什么。我见过许许多多的Linux工程师,他们的简历书写着“精通”Linux内核,有多年的工作经验,而他们的“精通”却只是把某个寄存器从0改成1,从1改成0的不断重复;我见过许许多多的Linux工程师,他们终日埋头苦干,敲打着自己的机器和电路板,却从未冷静下来思考,并不断重构和升华自己的知识体系。
这是要把牢底坐穿的程序员。这样“忙忙碌碌”的程序员,从来都不是什么好程序员。
优秀的程序员,最优秀的品质是能够内心宁静地学习与思考问题,透析代码背后的架构、原理和设计思想。没有思想的代码是垃圾代码,没有思想的程序员,只是在完成低水平重复建设的体力活。很多程序员,连自己写的代码最后在机器里面怎么跑都从不过问,很多事情莫名其妙地发生了,很多bug莫名其妙地消失了……永远都是得过且过。
由此,衍生出《Linux设备驱动开发详解》新版的第一个出发点,那就是带给读者更多关于Linux开发背后思想的讲解,奠定根基。《Linux设备驱动开发详解(基于4.0内核)》呈现给读者的,更多的是一种思考,而不是知识点的简单罗列。
这次更新更进一步加强了对驱动编程所涉及Linux内核最底层机理的讲解,并对前2版的基础理论部分进行了大篇幅地重写,实例代码也被大面积重构。大幅度修改的内容包括中断、定时器、进程生命周期、uevent、并发、编译乱序、执行乱序、等待队列、I/O模型、内存管理等。这些知识点是如此重要,是真正证明程序员对Linux理解的部分,只有打好根基,才能游刃有余。
新版删除了《Linux设备驱动开发详解》第一版、第二版大量描述各种具体具体驱动类型的章节比如Sound、PCI、MTD、TTY等,而将更多焦点转移到了驱动编程背后的内核原理, 并试图从Linux内核上百个驱动子系统中寻找出内部的规律,以培养读者举一反三的能力。
Linux内核有上百个驱动子系统,这一点从内核的drivers子目录就可以看出来:
好吧,傻子才会一个目录一个目录地去看,一个目录一个目录地从头学起。我们势必要寻找各种驱动子系统的共性,摸索规律。本次更新,我们将更多看到各驱动子系统的类比,以及驱动子系统的层次化设计。
技术工作,从来都不是一劳永逸。这世界变化太快,当前技术革新的速度数倍于我们父辈祖辈祖祖辈经过的任何时代。证明你是真球迷还是伪球迷的时候到了。这是伪程序员的地狱,也是真程序员痛苦中的狂欢。
从浩如烟海的知识体系中、不断更新的软件版本中终生学习,不断攻克一个个挑战,获取新的养分,寻找新的灵感,这实在是黑暗码农生涯中不断闪现的璀璨光芒。
自本书第一版、第二版发布后,内核版本不断刷新,3.0、3.1、3.2…3.19、4.0、4.1,变化的是软件的架构,不变的是Linus的热情。
这无疑是本次升级的第二个出发点,更新Linux驱动编程的知识体系以符合最新的时代。所以,本次更新大量新增了关于Device Tree、ARM Linux移植、Linux电源管理、GPIO、clock、timer、pinmux、DMA等的内容。我们的操作平台,也转移到了QEMU模拟的4核Cortex-A9电路板,书中的实例,基本都转移到了市面流行的新芯片。
最近两三年,老是听到许多程序员抱怨,缺乏讲新内核的资料、缺乏从头到尾讲Device Tree的资料,但是我想说,这实在不是什么难点。难点仍然是本书第一个出发点要解决的问题,如果有好的基础,以优秀程序员极强的学习能力,应该很快就可以掌握这些新知识。机制没有变,变化的是只是策略。
所以学习能力,也是优秀程序员的又一品质。没有人生下来就是天才,良好学习能力的培训,本身也是通过不断学习来获取的。可以说,学的越多的人,学新东西一定越快,学习能力也变得越强。因为,知识的共通性实在太多。
读者阅读本书的思路,不应该是企图把它当成一本工具书、查API的书,而是一本梳理完整理论体系、开发思想、软件架构的书。唯如此,我们才能适应未来新的变化。
不知不觉中,离本书的第一次出版已经过去了七个年头。而自本次更新开始实施至今,也经过了一轮寒暑更替。岁月如歌,七载而下,我已非当年的意气青年。本书一版,二版,再版,这实非当初的预料。回首过去,我们惊奇地发现,这七年,正好是Linux由弱而盛,节节胜利的七年。也是许多如我一般的码农成家立业、结婚生子的七年。未来七年的Linux会是什么样子,我们无从预料。本书是否会有更进一步的新版,我们也无法预知,一如Linux没有路线图。社区和生态就是最好的Roadmap,万事随缘,而唯一不变的只是激情。
时代的滚滚车轮,推动着Linux内核的版本不断向前,也推动着每个人的人生。红尘滚滚,
我不去想是否能够成功,
既然选择了远方,
便只顾风雨兼程。
最后,本书能得以出版,要感谢带领我向前的人生导师和我的众多小伙伴,他们或者在我人生的关键时刻改变了我,或者带给了我黑暗程序生涯中无尽的快乐和动力。我的小伙伴,他们力挺我,鼓励我,也辱骂我,奚落我,这些,就是真挚的友情。
谨以此书,致以对杨平先生、何昭然、方毅伟、李华毅、宋志吾、杜向龙、叶祥振、刘昊、王榕、何晔、王立赛、曾过、刘永生、段炳华、章君义、王文琪、卢鹏、刘涛、徐西宁、吴赫、任桥伟、秦龙廷、胡良兵、张家旺、王雷、Bryan Wu、Eric Miao、Qipan Li、Guoying Zhang、陈健松、应荣军、Haoyu Zhong、刘洪涛、季久峰、邴杰、孙志忠、吴国举、Bob Liu、赵小吾、贺亚锋、刘仕杰、Hao Yin等老师和小伙伴的深深感激;谨以此书,致以对我的父母大人、老婆大人、兄长和姐姐、伟大丈母娘的深深感激,本书新版的写作时间超过一年,其过程是一种巨大的肉体和精神折磨,没有他们的默默支持和不断鞭策,是不可能完成的;谨以此书,致以对为本书做出巨大贡献的编辑、策划老师们,尤其是张国强老师深深的感激!
由于篇幅的关系,我没有办法一一列举所有我要感激的人入感谢名单。但是,我这些年从你们那里获得的,远远大于我付出的。所以,内心深处,唯有怀着对小伙伴深深的感恩,不断前行。岁月如歌,吾歌狂行。
宋宝华
2015年4月于上海浦东
1.4 Linux 设备驱动
1.4.1 设备的分类及特点
计算机系统的硬件主要由 CPU、存储器和外设组成。随着 IC 制作工艺的发展,目前, 芯片的集成度越来越高,往往在 CPU 内部就集成了存储器和外设适配器。譬如,相当多的 ARM、PowerPC、MIPS 等处理器都集成了 UART、I2C 控制器、SPI 控制器、USB 控制器、 SDRAM 控制器等,有的处理器还集成了 GPU(图形处理器)、视频编解码器等。
驱动针对的对象是存储器和外设(包括 CPU 内部集成的存储器和外设),而不是针对 CPU 内核。Linux 将存储器和外设分为 3 个基础大类。
● 字符设备。
● 块设备。
● 网络设备。
字符设备指那些必须以串行顺序依次进行访问的设备,如触摸屏、磁带驱动器、鼠标 等。块设备可以按任意顺序进行访问,以块为单位进行操作,如硬盘、eMMC 等。字符设备 和块设备的驱动设计有出很大的差异,但是对于用户而言,它们都要使用文件系统的操作接 口 open()、close()、read()、write() 等进行访问。
在 Linux 系统中,网络设备面向数据包的接收和发送而设计,它并不倾向于对应于文件 系统的节点。内核与网络设备的通信与内核和字符设备、网络设备的通信方式完全不同,前 者主要还是使用套接字接口。
SRAM、Flash、SDRAM、
磁盘的读写方式,UART、I2C、USB 等设备的接口以及轮询、中断、DMA 的原理,
PCI 总线的工作方式以及 CPU 的内存管理单元(MMU)
虚拟机环境:
http://pan.baidu.com/s/1c08gzi4(密码为 puki)
1.5.2 QEMU 实验平台
QEMU 模拟了 vexpress Cortex-A9 SMP 四核处理器开发板,板上集成了 Flash、SD、 I2C、LCD 等。ARM 公司的 Versatile Express 系列开发平台提供了超快的环境,用于为下一 代片上系统设计方案建立原型,比如 Cortex-A9 Quad Core。
在 http://www.arm.com/zh/products/tools/development-boards/versatile-express/index.php 上 可以发现更多关于 Versatile Express 系列开发平台的细节。
本书配套虚拟机映像中已经安装好了工具链,包含 arm-linux-gnueabihf-gcc 和 arm-linux- gnueabi-gcc 两个版本。
Linux 内核在 /home/baohua/develop/linux 目录中,在该目录下面,包含内核编译脚本:
第1章 Linux设备驱动概述及开发环境构建 11
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabi-
make LDDD3_vexpress_defconfig
make zImage -j8
make modules -j8
make dtbs
cp arch/arm/boot/zImage extra/
cp arch/arm/boot/dts/*ca9.dtb
cp .config extra/
由此可见,我们用的默认内核配置文件是 LDDD3_vexpress_defconfig。上述脚本也会自
动将编译好的 zImage 和 dtbs 复制到 extra 目录中。
extra 目录下的 vexpress.img 是一张虚拟的 SD 卡,将作为根文件系统的存放介质。它能
以 loop 的形式被挂载(mount),譬如在 /home/baohua/develop/linux 目录下运行。
sudo mount -o loop,offset=$((2048*512)) extra/vexpress.img extra/img
可以把 vexpress.img 的根文件系统分区挂载到 extra/img,这样我们可以在目标板的根文
件系统中放置我们喜欢的内容。
/home/baohua/develop/linux 目录下面有个编译模块的脚本 module.sh,它会自动编译内核
模块并安装到 vexpress.img 中,其内容如下:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- modules
extra/
12 Linux设备驱动开发详解:基于最新的Linux 4.0内核
sudo mount -o loop,offset=$((2048*512)) extra/vexpress.img extra/img
sudo make ARCH=arm modules_install INSTALL_MOD_PATH=extra/img
sudo umount extra/img
运行 extra 下面的 run-nolcd.sh 可以启动一个不含 LCD 的 ARM Linux。run-nolcd.sh 的内
容为 qemu-system-arm -nographic -sd vexpress.img -M vexpress-a9 -m 512M -kernel zImage -dtb
vexpress-v2p-ca9.dtb -smp 4 -append "init=/linuxrc root=/dev/mmcblk0p1 rw rootwait earlyprintk
console=ttyAMA0" 2>/dev/null,运行结果为:
baohua@baohua-VirtualBox:~/develop/linux/extra$ ./run-nolcd.sh
Uncompressing Linux... done, booting the kernel.
Booting Linux on physical CPU 0x0
Initializing cgroup subsys cpuset
Linux version 3.16.0+ (baohua@baohua-VirtualBox) (gcc version 4.7.3 (Ubuntu/
Linaro 4.7.3-12ubuntu1) ) #3 SMP Mon Dec 1 16:53:04 CST 2014
CPU: ARMv7 Processor [410fc090] revision 0 (ARMv7), cr=10c53c7d
CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
Machine model: V2P-CA9
bootconsole [earlycon0] enabled
Memory policy: Data cache writealloc
PERCPU: Embedded 7 pages/cpu @9fbcd000 s7232 r8192 d13248 u32768
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 130048
Kernel command line: init=/linuxrc root=/dev/mmcblk0p1 rw rootwait earlyprintk
console=ttyAMA0
PID hash table entries: 2048 (order: 1, 8192 bytes)
Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
Memory: 513088K/524288K available (4583K kernel code, 188K rwdata, 1292K rodata,
247K init, 149K bss, 11200K reserved)
Virtual kernel memory layout:
vector : 0xffff0000 - 0xffff1000
fixmap : 0xffc00000 - 0xffe00000
vmalloc : 0xa0800000 - 0xff000000
lowmem : 0x80000000 - 0xa0000000
modules : 0x7f000000 - 0x80000000
.text : 0x80008000 - 0x805c502c
.init : 0x805c6000 - 0x80603c40
.data : 0x80604000 - 0x80633100
( 4 kB)
(2048 kB)
(1512 MB)
( 512 MB)
( 16 MB)
(5877 kB)
( 248 kB)
( 189 kB)
( 150 kB)
.bss : 0x80633108 - 0x806588a8
SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
Hierarchical RCU implementation.
RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=4.
RCU: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
NR_IRQS:16 nr_irqs:16 16
L2C: platform modifies aux control register: 0x02020000 -> 0x02420000
L2C: device tree omits to specify unified cache
L2C: DT/platform modifies aux control register: 0x02020000 -> 0x02420000
L2C-310 enabling early BRESP for Cortex-A9
L2C-310 full line of zeros enabled for Cortex-A9
L2C-310 dynamic clock gating disabled, standby mode disabled
L2C-310 cache controller enabled, 8 ways, 128 kB
L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x46420001
smp_twd: clock not found -2
sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 178956969942ns
Console: colour dummy device 80x30
...
运行 extra 下面的 run-lcd.sh 可以启动一个含 LCD 的 ARM Linux,运行结果如图 1.11
所示。
图 1.11 含 LCD 的 ARM Linux
除了 QEMU 模拟的 ARM 电路板以外,本书配套的 Ubuntu 中还包含一些直接可以
在 Ubuntu 上 运 行 的 案 例, 譬 如 /home/baohua/develop/training/kernel 中 就 包 含 了 globalfifo、
globalmem 等,这些目录的源代码都包含了 Makefile,在其中直接 make,生成的 .ko 可以直
接在 Ubuntu 上运行。
1.5.3 源代码阅读和编辑
源代码是学习 Linux 的权威资料,在 Windows 上阅读 Linux 源代码的最佳工具是 Source Insight,在其中建立一个工程,并将 Linux 的所有源代码加入该工程,同步这个工程之后, 我们将能非常便捷地在代码之间进行关联阅读,如图 1.12 所示。
类似 http://lxr.free-electrons.com/、http://lxr.oss.org.cn/ 这样的网站提供了 Linux 内核源代 码的交叉索引,在其中输入 Linux 内核中的函数、数据结构或变量的名称就可以直接得到以 超链接形式给出的定义和引用它的所有位置。还有一些网站也提供了 Linux 内核中函数、变 量和数据结构的搜索功能,在 google 中搜索“linux identifier search”可得。
在 Linux 主机上阅读和编辑 Linux 源码的常用方式是 vim + cscope 或者 vim + ctags,vim 是一个文本编辑器,而 cscope 和 ctags 则可建立代码索引,建议读者尽快使用基于文本界面 全键盘操作的 vim 编辑器,如图 1.13 所示。
此时,我们只需要有一个感性认识,那就是,上述暂时陌生的元素都是 Linux 内核为字 符设备定义的,以实现驱动与内核接口而定义的。Linux 对各类设备的驱动都定义了类似的 数据结构和函数。
第2章
驱动设计的硬件基础
本章导读
本章讲述底层驱动工程师必备的硬件基础,给出了嵌入式系统硬件原理及分析方法的一 个完整而简洁的全景视图。
2.1 节描述了微控制器、微处理器、数字信号处理器以及应用于特定领域的处理器各自 的特点,分析了处理器的体系结构和指令集。
2.2 节对嵌入式系统中所使用的各类存储器与 CPU 的接口、应用领域及特点进行了归纳 整理。
2.3 节分析了常见的外设接口与总线的工作方式,包括串口、I2C、SPI、USB、以太网接口、 PCI 和 PCI-E、SD 和 SDIO 等。
嵌入式系统硬件电路中经常会使用 CPLD 和 FPGA,作为驱动工程师,我们不需要掌握 CPLD 和 FPGA 的开发方法,但是需要知道它们在电路中能完成什么工作,2.4 节讲解了这项 内容。
2.5 ~ 2.7 节给出了在实际项目开发过程中硬件分析的方法,包括如何进行原理图分析、 时序分析及如何快速地从芯片数据手册中获取有效信息。
2.8 节讲解了调试过程中常用仪器仪表的使用方法,涉及万用表、示波器和逻辑分析仪。 2.1 处理器
2.1.1 通用处理器
目前主流的通用处理器(GPP)多采用 SoC(片上系统)的芯片设计方法,集成了各种功 能模块,每一种功能都是由硬件描述语言设计程序,然后在 SoC 内由电路实现的。在 SoC 中,每一个模块不是一个已经设计成熟的 ASIC 器件,而是利用芯片的一部分资源去实现某 种传统的功能,将各种组件采用类似搭积木的方法组合在一起。
ARM 内核的设计技术被授权给数百家半导体厂商,做成不同的 SoC 芯片。ARM 的功耗 很低,在当今最活跃的无线局域网、3G、手机终端、手持设备、有线网络通信设备等中应用 非常广泛。至本书编写时,市面上绝大多数智能手机、平板电脑都使用 ARM SoC 作为主控

《Verilog数字系统设计教程(第2版).pdf》的更多相关文章
- 简单物联网:外网访问内网路由器下树莓派Flask服务器
最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...
- 利用ssh反向代理以及autossh实现从外网连接内网服务器
前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...
- 外网访问内网Docker容器
外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...
- 外网访问内网SpringBoot
外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...
- 外网访问内网Elasticsearch WEB
外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...
- 怎样从外网访问内网Rails
外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...
- 怎样从外网访问内网Memcached数据库
外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...
- 怎样从外网访问内网CouchDB数据库
外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...
- 怎样从外网访问内网DB2数据库
外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...
- 怎样从外网访问内网OpenLDAP数据库
外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...
随机推荐
- vmware workstations 虚拟机安装CentOS
1.下载vmware ,我的版本是从上学时保存网盘的,版本比较低,链接如下: 链接:https://pan.baidu.com/s/19QP0q8xmPWIPn-rziPTvKg 提取码:lvh9 2 ...
- [BZOJ1042]AOI2008]硬币购物
题目描述 Description 硬币购物一共有4种硬币.面值分别为\(c_1\) ,\(c_2\) ,\(c_3\) ,\(c_4\) .某人去商店买东西,去了\(tot\) 次.每次带\(d_i\ ...
- WPF 精修篇 自定义控件
原文:WPF 精修篇 自定义控件 自定义控件 因为没有办法对界面可视化编辑 所以用来很少 现在实现的是 自定义控件的 自定义属性 和自定义方法 用VS 创建自定义控件后 会自动创建 Themes 文件 ...
- 【转】SQL中GROUP BY语句与HAVING语句的使用
一.GROUP BY GROUP BY语句用来与聚合函数(aggregate functions such as COUNT, SUM, AVG, MIN, or MAX.)联合使用来得到一个或多个列 ...
- 用Python做个海量小姐姐素描图
素描作为一种近乎完美的表现手法有其独特的魅力,随着数字技术的发展,素描早已不再是专业绘画师的专利,今天这篇文章就来讲一讲如何使用python批量获取小姐姐素描画像.文章共分两部分: 第一部分介绍两种使 ...
- 如何使用PHP的生成器yield处理大量数据业务
官方解释yield yield生成器是php5.5之后出现的,官方文档这样解释:yield提供了一种更容易的方法来实现简单的迭代对象,相比较定义类实现 Iterator 接口的方式,性能开销和复杂性大 ...
- 如何使用re模块进行测试用例的参数化
import re import os from scripts.handle_mysql import HandleMysql from scripts.handle_config import H ...
- Zookeeper学习记录及Java客户端连接示例
1. Zookeeper 1.1 简介 ZooKeeper is a centralized service for maintaining configuration information, na ...
- RtlRaiseException(ntdll.dll)函数逆向
书中内容: 代码逆向: 1. CONTEXT是保存之前的函数(RaiseException)状态 2. 在逆向上一个函数时产生一个疑问:EXCEPTION_RECORD.ExceptionAddres ...
- Java电商项目-1.构建数据库,搭建项目环境
目录 到Github获取源码请点击此处 一. 数据库还原 二. Mybatis逆向生成工具的使用 三. 搭建项目环境 四. 在linux虚拟机上部署zookeeper, 搭建Dubbo服务. linu ...