《Verilog数字系统设计教程(第2版).pdf》
Verilog數(shù)字系統(tǒng)設(shè)計教程(第2版).pdf
https://github.com/shigh1005/pdf_book
《Linux設(shè)備驅(qū)動開發(fā)詳解:基于最新的Linux 4.0內(nèi)核.pdf》
《Linux設(shè)備驅(qū)動開發(fā)詳解(基于最新4.0內(nèi)核)》前言
LinuxDev
2015-04-28
閱讀數(shù):1056
Linux從未停歇腳步。Linus Torvalds,世界上最偉大的程序員之一,Linux內(nèi)核的創(chuàng)始人,Git的締造者,仍然在沒日沒夜的合并補丁,升級內(nèi)核。做技術(shù),從來沒有終南捷徑,拼的就是坐冷板凳的傻勁。
這是一個連閱讀都被碎片化的時代,在這樣一個時代,人們趨向于激進、浮躁。內(nèi)心的不安寧使我們極難靜下心來研究什么。我見過許許多多的Linux工程師,他們的簡歷書寫著“精通”Linux內(nèi)核,有多年的工作經(jīng)驗,而他們的“精通”卻只是把某個寄存器從0改成1,從1改成0的不斷重復(fù);我見過許許多多的Linux工程師,他們終日埋頭苦干,敲打著自己的機器和電路板,卻從未冷靜下來思考,并不斷重構(gòu)和升華自己的知識體系。
這是要把牢底坐穿的程序員。這樣“忙忙碌碌”的程序員,從來都不是什么好程序員。
優(yōu)秀的程序員,最優(yōu)秀的品質(zhì)是能夠內(nèi)心寧靜地學(xué)習(xí)與思考問題,透析代碼背后的架構(gòu)、原理和設(shè)計思想。沒有思想的代碼是垃圾代碼,沒有思想的程序員,只是在完成低水平重復(fù)建設(shè)的體力活。很多程序員,連自己寫的代碼最后在機器里面怎么跑都從不過問,很多事情莫名其妙地發(fā)生了,很多bug莫名其妙地消失了……永遠都是得過且過。
由此,衍生出《Linux設(shè)備驅(qū)動開發(fā)詳解》新版的第一個出發(fā)點,那就是帶給讀者更多關(guān)于Linux開發(fā)背后思想的講解,奠定根基。《Linux設(shè)備驅(qū)動開發(fā)詳解(基于4.0內(nèi)核)》呈現(xiàn)給讀者的,更多的是一種思考,而不是知識點的簡單羅列。
這次更新更進一步加強了對驅(qū)動編程所涉及Linux內(nèi)核最底層機理的講解,并對前2版的基礎(chǔ)理論部分進行了大篇幅地重寫,實例代碼也被大面積重構(gòu)。大幅度修改的內(nèi)容包括中斷、定時器、進程生命周期、uevent、并發(fā)、編譯亂序、執(zhí)行亂序、等待隊列、I/O模型、內(nèi)存管理等。這些知識點是如此重要,是真正證明程序員對Linux理解的部分,只有打好根基,才能游刃有余。
新版刪除了《Linux設(shè)備驅(qū)動開發(fā)詳解》第一版、第二版大量描述各種具體具體驅(qū)動類型的章節(jié)比如Sound、PCI、MTD、TTY等,而將更多焦點轉(zhuǎn)移到了驅(qū)動編程背后的內(nèi)核原理,并試圖從Linux內(nèi)核上百個驅(qū)動子系統(tǒng)中尋找出內(nèi)部的規(guī)律,以培養(yǎng)讀者舉一反三的能力。
Linux內(nèi)核有上百個驅(qū)動子系統(tǒng),這一點從內(nèi)核的drivers子目錄就可以看出來:
好吧,傻子才會一個目錄一個目錄地去看,一個目錄一個目錄地從頭學(xué)起。我們勢必要尋找各種驅(qū)動子系統(tǒng)的共性,摸索規(guī)律。本次更新,我們將更多看到各驅(qū)動子系統(tǒng)的類比,以及驅(qū)動子系統(tǒng)的層次化設(shè)計。
技術(shù)工作,從來都不是一勞永逸。這世界變化太快,當(dāng)前技術(shù)革新的速度數(shù)倍于我們父輩祖輩祖祖輩經(jīng)過的任何時代。證明你是真球迷還是偽球迷的時候到了。這是偽程序員的地獄,也是真程序員痛苦中的狂歡。
從浩如煙海的知識體系中、不斷更新的軟件版本中終生學(xué)習(xí),不斷攻克一個個挑戰(zhàn),獲取新的養(yǎng)分,尋找新的靈感,這實在是黑暗碼農(nóng)生涯中不斷閃現(xiàn)的璀璨光芒。
自本書第一版、第二版發(fā)布后,內(nèi)核版本不斷刷新,3.0、3.1、3.2…3.19、4.0、4.1,變化的是軟件的架構(gòu),不變的是Linus的熱情。
這無疑是本次升級的第二個出發(fā)點,更新Linux驅(qū)動編程的知識體系以符合最新的時代。所以,本次更新大量新增了關(guān)于Device Tree、ARM Linux移植、Linux電源管理、GPIO、clock、timer、pinmux、DMA等的內(nèi)容。我們的操作平臺,也轉(zhuǎn)移到了QEMU模擬的4核Cortex-A9電路板,書中的實例,基本都轉(zhuǎn)移到了市面流行的新芯片。
最近兩三年,老是聽到許多程序員抱怨,缺乏講新內(nèi)核的資料、缺乏從頭到尾講Device Tree的資料,但是我想說,這實在不是什么難點。難點仍然是本書第一個出發(fā)點要解決的問題,如果有好的基礎(chǔ),以優(yōu)秀程序員極強的學(xué)習(xí)能力,應(yīng)該很快就可以掌握這些新知識。機制沒有變,變化的是只是策略。
所以學(xué)習(xí)能力,也是優(yōu)秀程序員的又一品質(zhì)。沒有人生下來就是天才,良好學(xué)習(xí)能力的培訓(xùn),本身也是通過不斷學(xué)習(xí)來獲取的。可以說,學(xué)的越多的人,學(xué)新東西一定越快,學(xué)習(xí)能力也變得越強。因為,知識的共通性實在太多。
讀者閱讀本書的思路,不應(yīng)該是企圖把它當(dāng)成一本工具書、查API的書,而是一本梳理完整理論體系、開發(fā)思想、軟件架構(gòu)的書。唯如此,我們才能適應(yīng)未來新的變化。
不知不覺中,離本書的第一次出版已經(jīng)過去了七個年頭。而自本次更新開始實施至今,也經(jīng)過了一輪寒暑更替。歲月如歌,七載而下,我已非當(dāng)年的意氣青年。本書一版,二版,再版,這實非當(dāng)初的預(yù)料。回首過去,我們驚奇地發(fā)現(xiàn),這七年,正好是Linux由弱而盛,節(jié)節(jié)勝利的七年。也是許多如我一般的碼農(nóng)成家立業(yè)、結(jié)婚生子的七年。未來七年的Linux會是什么樣子,我們無從預(yù)料。本書是否會有更進一步的新版,我們也無法預(yù)知,一如Linux沒有路線圖。社區(qū)和生態(tài)就是最好的Roadmap,萬事隨緣,而唯一不變的只是激情。
時代的滾滾車輪,推動著Linux內(nèi)核的版本不斷向前,也推動著每個人的人生。紅塵滾滾,
我不去想是否能夠成功,
既然選擇了遠方,
便只顧風(fēng)雨兼程。
最后,本書能得以出版,要感謝帶領(lǐng)我向前的人生導(dǎo)師和我的眾多小伙伴,他們或者在我人生的關(guān)鍵時刻改變了我,或者帶給了我黑暗程序生涯中無盡的快樂和動力。我的小伙伴,他們力挺我,鼓勵我,也辱罵我,奚落我,這些,就是真摯的友情。
謹以此書,致以對楊平先生、何昭然、方毅偉、李華毅、宋志吾、杜向龍、葉祥振、劉昊、王榕、何曄、王立賽、曾過、劉永生、段炳華、章君義、王文琪、盧鵬、劉濤、徐西寧、吳赫、任橋偉、秦龍廷、胡良兵、張家旺、王雷、Bryan Wu、Eric Miao、Qipan Li、Guoying Zhang、陳健松、應(yīng)榮軍、Haoyu Zhong、劉洪濤、季久峰、邴杰、孫志忠、吳國舉、Bob Liu、趙小吾、賀亞鋒、劉仕杰、Hao Yin等老師和小伙伴的深深感激;謹以此書,致以對我的父母大人、老婆大人、兄長和姐姐、偉大丈母娘的深深感激,本書新版的寫作時間超過一年,其過程是一種巨大的肉體和精神折磨,沒有他們的默默支持和不斷鞭策,是不可能完成的;謹以此書,致以對為本書做出巨大貢獻的編輯、策劃老師們,尤其是張國強老師深深的感激!
由于篇幅的關(guān)系,我沒有辦法一一列舉所有我要感激的人入感謝名單。但是,我這些年從你們那里獲得的,遠遠大于我付出的。所以,內(nèi)心深處,唯有懷著對小伙伴深深的感恩,不斷前行。歲月如歌,吾歌狂行。
宋寶華
2015年4月于上海浦東
1.4 Linux 設(shè)備驅(qū)動
1.4.1 設(shè)備的分類及特點
計算機系統(tǒng)的硬件主要由 CPU、存儲器和外設(shè)組成。隨著 IC 制作工藝的發(fā)展,目前, 芯片的集成度越來越高,往往在 CPU 內(nèi)部就集成了存儲器和外設(shè)適配器。譬如,相當(dāng)多的 ARM、PowerPC、MIPS 等處理器都集成了 UART、I2C 控制器、SPI 控制器、USB 控制器、 SDRAM 控制器等,有的處理器還集成了 GPU(圖形處理器)、視頻編解碼器等。
驅(qū)動針對的對象是存儲器和外設(shè)(包括 CPU 內(nèi)部集成的存儲器和外設(shè)),而不是針對 CPU 內(nèi)核。Linux 將存儲器和外設(shè)分為 3 個基礎(chǔ)大類。
● 字符設(shè)備。
● 塊設(shè)備。
● 網(wǎng)絡(luò)設(shè)備。
字符設(shè)備指那些必須以串行順序依次進行訪問的設(shè)備,如觸摸屏、磁帶驅(qū)動器、鼠標(biāo) 等。塊設(shè)備可以按任意順序進行訪問,以塊為單位進行操作,如硬盤、eMMC 等。字符設(shè)備 和塊設(shè)備的驅(qū)動設(shè)計有出很大的差異,但是對于用戶而言,它們都要使用文件系統(tǒng)的操作接 口 open()、close()、read()、write() 等進行訪問。
在 Linux 系統(tǒng)中,網(wǎng)絡(luò)設(shè)備面向數(shù)據(jù)包的接收和發(fā)送而設(shè)計,它并不傾向于對應(yīng)于文件 系統(tǒng)的節(jié)點。內(nèi)核與網(wǎng)絡(luò)設(shè)備的通信與內(nèi)核和字符設(shè)備、網(wǎng)絡(luò)設(shè)備的通信方式完全不同,前 者主要還是使用套接字接口。
SRAM、Flash、SDRAM、
磁盤的讀寫方式,UART、I2C、USB 等設(shè)備的接口以及輪詢、中斷、DMA 的原理,
PCI 總線的工作方式以及 CPU 的內(nèi)存管理單元(MMU)
虛擬機環(huán)境:
http://pan.baidu.com/s/1c08gzi4(密碼為 puki)
1.5.2 QEMU 實驗平臺
QEMU 模擬了 vexpress Cortex-A9 SMP 四核處理器開發(fā)板,板上集成了 Flash、SD、 I2C、LCD 等。ARM 公司的 Versatile Express 系列開發(fā)平臺提供了超快的環(huán)境,用于為下一 代片上系統(tǒng)設(shè)計方案建立原型,比如 Cortex-A9 Quad Core。
在 http://www.arm.com/zh/products/tools/development-boards/versatile-express/index.php 上 可以發(fā)現(xiàn)更多關(guān)于 Versatile Express 系列開發(fā)平臺的細節(jié)。
本書配套虛擬機映像中已經(jīng)安裝好了工具鏈,包含 arm-linux-gnueabihf-gcc 和 arm-linux- gnueabi-gcc 兩個版本。
Linux 內(nèi)核在 /home/baohua/develop/linux 目錄中,在該目錄下面,包含內(nèi)核編譯腳本:
第1章 Linux設(shè)備驅(qū)動概述及開發(fā)環(huán)境構(gòu)建 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/
由此可見,我們用的默認內(nèi)核配置文件是 LDDD3_vexpress_defconfig。上述腳本也會自
動將編譯好的 zImage 和 dtbs 復(fù)制到 extra 目錄中。
extra 目錄下的 vexpress.img 是一張?zhí)摂M的 SD 卡,將作為根文件系統(tǒng)的存放介質(zhì)。它能
以 loop 的形式被掛載(mount),譬如在 /home/baohua/develop/linux 目錄下運行。
sudo mount -o loop,offset=$((2048*512)) extra/vexpress.img extra/img
可以把 vexpress.img 的根文件系統(tǒng)分區(qū)掛載到 extra/img,這樣我們可以在目標(biāo)板的根文
件系統(tǒng)中放置我們喜歡的內(nèi)容。
/home/baohua/develop/linux 目錄下面有個編譯模塊的腳本 module.sh,它會自動編譯內(nèi)核
模塊并安裝到 vexpress.img 中,其內(nèi)容如下:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- modules
extra/
12 Linux設(shè)備驅(qū)動開發(fā)詳解:基于最新的Linux 4.0內(nèi)核
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 的內(nèi)
容為 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,運行結(jié)果為:
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,運行結(jié)果如圖 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 源代碼閱讀和編輯
源代碼是學(xué)習(xí) Linux 的權(quán)威資料,在 Windows 上閱讀 Linux 源代碼的最佳工具是 Source Insight,在其中建立一個工程,并將 Linux 的所有源代碼加入該工程,同步這個工程之后, 我們將能非常便捷地在代碼之間進行關(guān)聯(lián)閱讀,如圖 1.12 所示。
類似 http://lxr.free-electrons.com/、http://lxr.oss.org.cn/ 這樣的網(wǎng)站提供了 Linux 內(nèi)核源代 碼的交叉索引,在其中輸入 Linux 內(nèi)核中的函數(shù)、數(shù)據(jù)結(jié)構(gòu)或變量的名稱就可以直接得到以 超鏈接形式給出的定義和引用它的所有位置。還有一些網(wǎng)站也提供了 Linux 內(nèi)核中函數(shù)、變 量和數(shù)據(jù)結(jié)構(gòu)的搜索功能,在 google 中搜索“linux identifier search”可得。
在 Linux 主機上閱讀和編輯 Linux 源碼的常用方式是 vim + cscope 或者 vim + ctags,vim 是一個文本編輯器,而 cscope 和 ctags 則可建立代碼索引,建議讀者盡快使用基于文本界面 全鍵盤操作的 vim 編輯器,如圖 1.13 所示。
此時,我們只需要有一個感性認識,那就是,上述暫時陌生的元素都是 Linux 內(nèi)核為字 符設(shè)備定義的,以實現(xiàn)驅(qū)動與內(nèi)核接口而定義的。Linux 對各類設(shè)備的驅(qū)動都定義了類似的 數(shù)據(jù)結(jié)構(gòu)和函數(shù)。
第2章
驅(qū)動設(shè)計的硬件基礎(chǔ)
本章導(dǎo)讀
本章講述底層驅(qū)動工程師必備的硬件基礎(chǔ),給出了嵌入式系統(tǒng)硬件原理及分析方法的一 個完整而簡潔的全景視圖。
2.1 節(jié)描述了微控制器、微處理器、數(shù)字信號處理器以及應(yīng)用于特定領(lǐng)域的處理器各自 的特點,分析了處理器的體系結(jié)構(gòu)和指令集。
2.2 節(jié)對嵌入式系統(tǒng)中所使用的各類存儲器與 CPU 的接口、應(yīng)用領(lǐng)域及特點進行了歸納 整理。
2.3 節(jié)分析了常見的外設(shè)接口與總線的工作方式,包括串口、I2C、SPI、USB、以太網(wǎng)接口、 PCI 和 PCI-E、SD 和 SDIO 等。
嵌入式系統(tǒng)硬件電路中經(jīng)常會使用 CPLD 和 FPGA,作為驅(qū)動工程師,我們不需要掌握 CPLD 和 FPGA 的開發(fā)方法,但是需要知道它們在電路中能完成什么工作,2.4 節(jié)講解了這項 內(nèi)容。
2.5 ~ 2.7 節(jié)給出了在實際項目開發(fā)過程中硬件分析的方法,包括如何進行原理圖分析、 時序分析及如何快速地從芯片數(shù)據(jù)手冊中獲取有效信息。
2.8 節(jié)講解了調(diào)試過程中常用儀器儀表的使用方法,涉及萬用表、示波器和邏輯分析儀。 2.1 處理器
2.1.1 通用處理器
目前主流的通用處理器(GPP)多采用 SoC(片上系統(tǒng))的芯片設(shè)計方法,集成了各種功 能模塊,每一種功能都是由硬件描述語言設(shè)計程序,然后在 SoC 內(nèi)由電路實現(xiàn)的。在 SoC 中,每一個模塊不是一個已經(jīng)設(shè)計成熟的 ASIC 器件,而是利用芯片的一部分資源去實現(xiàn)某 種傳統(tǒng)的功能,將各種組件采用類似搭積木的方法組合在一起。
ARM 內(nèi)核的設(shè)計技術(shù)被授權(quán)給數(shù)百家半導(dǎo)體廠商,做成不同的 SoC 芯片。ARM 的功耗 很低,在當(dāng)今最活躍的無線局域網(wǎng)、3G、手機終端、手持設(shè)備、有線網(wǎng)絡(luò)通信設(shè)備等中應(yīng)用 非常廣泛。至本書編寫時,市面上絕大多數(shù)智能手機、平板電腦都使用 ARM SoC 作為主控
總結(jié)
以上是生活随笔為你收集整理的《Verilog数字系统设计教程(第2版).pdf》的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nginx将9000端口转发映射至 80
- 下一篇: Linux环境下如何生成core文件