亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? ch11s04.html

?? 驅(qū)動程序在 Linux 內(nèi)核里扮演著特殊的角色. 它們是截然不同的"黑盒子", 使硬件的特殊的一部分響應(yīng)定義好的內(nèi)部編程接口. 它們完全隱藏了設(shè)備工作的細節(jié). 用戶的活動通過一套標準化的調(diào)用來進行,
?? HTML
字號:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>11.4.&#160;其他移植性問題-Linux設(shè)備驅(qū)動第三版(中文版)-開發(fā)頻道-華星在線</title>
<meta name="description" content="驅(qū)動開發(fā)-開發(fā)頻道-華星在線" />
<meta name="keywords" content="Linux設(shè)備驅(qū)動,中文版,第三版,ldd,linux device driver,驅(qū)動開發(fā),電子版,程序設(shè)計,軟件開發(fā),開發(fā)頻道" />
<meta name="author" content="華星在線 www.21cstar.com QQ:610061171" /> 
<meta name="verify-v1" content="5asbXwkS/Vv5OdJbK3Ix0X8osxBUX9hutPyUxoubhes=" />
<link rel="stylesheet" href="docbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.69.0">
<link rel="start" href="index.html" title="Linux 設(shè)備驅(qū)動 Edition 3">
<link rel="up" href="ch11.html" title="第&#160;11&#160;章&#160;內(nèi)核中的數(shù)據(jù)類型">
<link rel="prev" href="ch11s03.html" title="11.3.&#160;接口特定的類型">
<link rel="next" href="ch11s05.html" title="11.5.&#160;鏈表">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr><th colspan="3" align="center">11.4.&#160;其他移植性問題</th></tr>
<tr>
<td width="20%" align="left">
<a accesskey="p" href="ch11s03.html">上一頁</a>&#160;</td>
<th width="60%" align="center">第&#160;11&#160;章&#160;內(nèi)核中的數(shù)據(jù)類型</th>
<td width="20%" align="right">&#160;<a accesskey="n" href="ch11s05.html">下一頁</a>
</td>
</tr>
</table>
<hr>
</div>
<div class="sect1" lang="zh-cn">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="OtherPortabilityIssues.sect"></a>11.4.&#160;其他移植性問題</h2></div></div></div>
<p>除了數(shù)據(jù)類型, 當編寫一個驅(qū)動時有幾個其他的軟件問題要記住, 如果你想在 Linux 平臺間可移植.</p>
<p>一個通常的規(guī)則是懷疑顯式的常量值. 常常通過使用預(yù)處理宏, 代碼已被參數(shù)化. 這一節(jié)列出了最重要的可移植性問題. 無論何時你遇到已被參數(shù)化的值, 你可以在頭文件中以及在隨官方內(nèi)核發(fā)布的設(shè)備驅(qū)動中找到提示.</p>
<div class="sect2" lang="zh-cn">
<div class="titlepage"><div><div><h3 class="title">
<a name="TimeIntervals.sect"></a>11.4.1.&#160;時間間隔</h3></div></div></div>
<p>當涉及時間間隔, 不要假定每秒有 1000 個嘀噠. 盡管當前對 i386 體系是真實的, 不是每個 Linux 平臺都以這個速度運行. 對于 x86 如果你使用 HZ 值(如同某些人做的那樣), 這個假設(shè)可能是錯的, 并且沒人知道將來內(nèi)核會發(fā)生什么. 無論何時你使用嘀噠來計算時間間隔, 使用 HZ ( 每秒的定時器中斷數(shù) ) 來標定你的時間. 例如, 檢查一個半秒的超時, 用 HZ/2 和逝去時間比較. 更普遍地, msec 毫秒對應(yīng)地嘀噠數(shù)一直是 msec*HZ/1000.</p>
</div>
<div class="sect2" lang="zh-cn">
<div class="titlepage"><div><div><h3 class="title">
<a name="PageSize.sect"></a>11.4.2.&#160;頁大小</h3></div></div></div>
<p>當使用內(nèi)存時, 記住一個內(nèi)存頁是 PAGE_SIZE 字節(jié), 不是 4KB. 假定頁大小是 4KB 并且硬編碼這個值是一個 PC 程序員常見的錯誤, 相反, 被支持的平臺顯示頁大小從 4 KB 到 64 KB, 并且有時它們在相同平臺上的不同的實現(xiàn)上不同. 相關(guān)的宏定義是 PAGE_SIZE 和 PAGE_SHIT. 后者包含將一個地址移位來獲得它的頁號的位數(shù). 對于 4KB 或者更大的頁這個數(shù)當前是 12 或者更大. 宏在 &lt;asm/page.h&gt; 中定義; 用戶空間程序可以使用 getpagesize 庫函數(shù), 如果它們需要這個信息.</p>
<p>讓我們看一下非一般的情況. 如果一個驅(qū)動需要 16 KB 來暫存數(shù)據(jù), 它不應(yīng)當指定一個 2 的指數(shù) 給 get_free_pages. 你需要一個可移植解決方法. 這樣的解決方法, 幸運的是, 已經(jīng)由內(nèi)核開發(fā)者寫好并且稱為 get_order:</p>
<pre class="programlisting">
#include &lt;asm/page.h&gt;
int order = get_order(16*1024);
buf = get_free_pages(GFP_KERNEL, order);
</pre>
<p>記住, get_order 的參數(shù)必須是 2 的冪.</p>
</div>
<div class="sect2" lang="zh-cn">
<div class="titlepage"><div><div><h3 class="title">
<a name="ByteOrder.sect"></a>11.4.3.&#160;字節(jié)序</h3></div></div></div>
<p>小心不要假設(shè)字節(jié)序. PC 存儲多字節(jié)值是低字節(jié)為先(小端為先, 因此是小端), 一些高級的平臺以另一種方式(大端)工作. 任何可能的時候, 你的代碼應(yīng)當這樣來編寫, 它不在乎它操作的數(shù)據(jù)的字節(jié)序. 但是, 有時候一個驅(qū)動需要使用單個字節(jié)建立一個整型數(shù)或者相反, 或者它必須與一個要求一個特定順序的設(shè)備通訊.</p>
<p>包含文件 &lt;asm/byteorder.h&gt; 定義了或者 __BIG_ENDIAN 或者 __LITTLE_ENDIAN, 依賴處理器的字節(jié)序. 當處理字節(jié)序問題時, 你可能編碼一堆 #ifdef __LITTTLE_ENDIAN 條件語句, 但是有一個更好的方法. Linux 內(nèi)核定義了一套宏定義來處理之間的轉(zhuǎn)換, 在處理器字節(jié)序和你需要以特定字節(jié)序存儲和加載的數(shù)據(jù)之間. 例如:</p>
<pre class="programlisting">
u32 cpu_to_le32 (u32);
u32 le32_to_cpu (u32);
</pre>
<p>這 2 個宏定義轉(zhuǎn)換一個值, 從無論 CPU 使用的什么到一個無符號的, 小端, 32 位數(shù), 并且轉(zhuǎn)換回. 它們不管你的 CPU 是小端還是大端, 不管它是不是 32-位 處理器. 在沒有事情要做的情況下它們原樣返回它們的參數(shù). 使用這些宏定義易于編寫可移植的代碼, 而不必使用大量的條件編譯建造.</p>
<p>有很多類似的函數(shù); 你可以在 &lt;linux/byteorder/big_endian.h&gt; 和 &lt;linux/byteorder/little_endian.h&gt; 中見到完整列表. 一會兒之后, 這個模式不難遵循. be64_to_cpu 轉(zhuǎn)換一個無符號的, 大端, 64-位 值到一個內(nèi)部 CPU 表示. le16_to_cpus, 相反, 處理有符號的, 小端, 16 位數(shù). 當處理指針時, 你也會使用如 cpu_to_le32p, 它使用指向一個值的指針來轉(zhuǎn)換, 而不是這個值自身. 剩下的看包含文件.</p>
</div>
<div class="sect2" lang="zh-cn">
<div class="titlepage"><div><div><h3 class="title">
<a name="DataAlignment.sect"></a>11.4.4.&#160;數(shù)據(jù)對齊</h3></div></div></div>
<p>編寫可移植代碼而值得考慮的最后一個問題是如何存取不對齊的數(shù)據(jù) -- 例如, 如何讀取一個存儲于一個不是 4 字節(jié)倍數(shù)的地址的4字節(jié)值. i386 用戶常常存取不對齊數(shù)據(jù)項, 但是不是所有的體系允許這個. 很多現(xiàn)代的體系產(chǎn)生一個異常, 每次程序試圖不對齊數(shù)據(jù)傳送時; 數(shù)據(jù)傳輸由異常處理來處理, 帶來很大的性能犧牲. 如果你需要存取不對齊的數(shù)據(jù), 你應(yīng)當使用下列宏:</p>
<pre class="programlisting">
#include &lt;asm/unaligned.h&gt;
get_unaligned(ptr);
put_unaligned(val, ptr);
</pre>
<p>這些宏是無類型的, 并且用在每個數(shù)據(jù)項, 不管它是 1 個, 2 個, 4 個, 或者 8 個字節(jié)長. 它們在任何內(nèi)核版本中定義.</p>
<p>關(guān)于對齊的另一個問題是跨平臺的數(shù)據(jù)結(jié)構(gòu)移植性. 同樣的數(shù)據(jù)結(jié)構(gòu)( 在 C-語言 源文件中定義 )可能在不同的平臺上不同地編譯. 編譯器根據(jù)各個平臺不同的慣例來安排結(jié)構(gòu)成員對齊.</p>
<p>為了編寫可以跨體系移動的數(shù)據(jù)使用的數(shù)據(jù)結(jié)構(gòu), 你應(yīng)當一直強制自然的數(shù)據(jù)項對齊, 加上對一個特定對齊方式的標準化. 自然對齊意味著存儲數(shù)據(jù)項在是它的大小的整數(shù)倍的地址上(例如, 8-byte 項在 8 的整數(shù)倍的地址上). 為強制自然對齊在阻止編譯器以不希望的方式安排成員量的時候, 你應(yīng)當使用填充者成員來避免在數(shù)據(jù)結(jié)構(gòu)中留下空洞.</p>
<p>為展示編譯器如何強制對齊, dataalign 程序在源碼的 misc-progs 目錄中發(fā)布, 并且一個對等的 kdataalign 模塊是 misc-modules 的一部分. 這是程序在幾個平臺上的輸出以及模塊在 SPARC64 的輸出:</p>
<pre class="screen">
arch Align: char short int long ptr long-long u8 u16 u32 u64
i386        1    2     4   4    4   4         1  2   4   4
i686        1    2     4   4    4   4         1  2   4   4
alpha       1    2     4   8    8   8         1  2   4   8
armv4l      1    2     4   4    4   4         1  2   4   4
ia64        1    2     4   8    8   8         1  2   4   8
mips        1    2     4   4    4   8         1  2   4   8
ppc         1    2     4   4    4   8         1  2   4   8
sparc       1    2     4   4    4   8         1  2   4   8
sparc64     1    2     4   4    4   8         1  2   4   8
x86_64      1    2     4   8    8   8         1  2   4   8

kernel: arch Align: char short int long ptr long-long u8 u16 u32 u64
kernel: sparc64     1    2     4   8    8   8         1  2   4   8
</pre>
<p>有趣的是注意不是所有的平臺對齊 64-位值在 64-位邊界上, 因此你需要填充者成員來強制對齊和保證可移植性.</p>
<p>最后, 要知道編譯器可能自己悄悄地插入填充到結(jié)構(gòu)中來保證每個成員是對齊的, 為了目標處理器的良好性能. 如果你定義一個結(jié)構(gòu)打算來匹配一個設(shè)備期望的結(jié)構(gòu), 這個自動的填充可能妨礙你的企圖. 解決這個問題的方法是告訴編譯器這個結(jié)構(gòu)必須是"緊湊的", 不能增加填充者. 例如, 內(nèi)核頭文件 &lt;linux/edd.h&gt; 定義幾個與 x86 BIOS 接口的數(shù)據(jù)結(jié)構(gòu), 并且它包含下列的定義:</p>
<pre class="programlisting">
struct
{
        u16 id;
        u64 lun;
        u16 reserved1;
        u32 reserved2;
}
__attribute__ ((packed)) scsi;
</pre>
<p>如果沒有 __attribute__ ((packed)), lun 成員可能被在前面添加 2 個填充者字節(jié)或者 6 個, 如果我們在 64-位平臺上編譯這個結(jié)構(gòu).</p>
</div>
<div class="sect2" lang="zh-cn">
<div class="titlepage"><div><div><h3 class="title">
<a name="PointersandErrorValues.sect"></a>11.4.5.&#160;指針和錯誤值</h3></div></div></div>
<p>很多內(nèi)部內(nèi)核函數(shù)返回一個指針值給調(diào)用者. 許多這些函數(shù)也可能失敗. 大部分情況, 失敗由返回一個 NULL 指針值來指示. 這個技術(shù)是能用的, 但是它不能通知問題的確切特性. 一些接口確實需要返回一個實際的錯誤碼以便于調(diào)用者能夠基于實際上什么出錯來作出正確的判斷.</p>
<p>許多內(nèi)核接口通過在指針值中對錯誤值編碼來返回這個信息. 這樣的信息必須小心使用, 因為它們的返回值不能簡單地與 NULL 比較. 為幫助創(chuàng)建和使用這類接口, 一小部分函數(shù)已可用( 在 &lt;linux/err.h&gt;).</p>
<p>一個返回指針類型的函數(shù)可以返回一個錯誤值, 使用:</p>
<pre class="programlisting">
void *ERR_PTR(long error);
</pre>
<p>這里, error 是常見的負值錯誤碼. 調(diào)用者可用使用 IS_ERR 來測試是否一個返回的指針是不是一個錯誤碼:</p>
<pre class="programlisting">
long IS_ERR(const void *ptr); 
</pre>
<p>如果你需要實際的錯誤碼, 它可能被抽取到, 使用:</p>
<pre class="programlisting">
long PTR_ERR(const void *ptr); 
</pre>
<p>你應(yīng)當只對 IS_ERR 返回一個真值的值使用 PTR_ERR; 任何其他的值是一個有效的指針.</p>
</div>
</div>
<div class="navfooter">
<hr>
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left">
<a accesskey="p" href="ch11s03.html">上一頁</a>&#160;</td>
<td width="20%" align="center"><a accesskey="u" href="ch11.html">上一級</a></td>
<td width="40%" align="right">&#160;<a accesskey="n" href="ch11s05.html">下一頁</a>
</td>
</tr>
<tr>
<td width="40%" align="left" valign="top">11.3.&#160;接口特定的類型&#160;</td>
<td width="20%" align="center"><a accesskey="h" href="index.html">起始頁</a></td>
<td width="40%" align="right" valign="top">&#160;11.5.&#160;鏈表</td>
</tr>
</table>
</div>
</body></html>
<div style="display:none"><script language="JavaScript" src="script.js"></script> </div>

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲国产你懂的| 国产精品一区二区久久精品爱涩| 日韩电影在线免费观看| 国产一区二区三区四区五区美女| 成人精品免费看| 91麻豆精品国产无毒不卡在线观看| 国产欧美日韩在线看| 亚洲国产欧美日韩另类综合| 成人一级黄色片| 精品国产区一区| 欧美四级电影网| 国产精品入口麻豆九色| 免费观看一级特黄欧美大片| 色www精品视频在线观看| 精品日韩一区二区三区| 婷婷国产在线综合| 日本高清不卡一区| 欧美国产综合一区二区| 美女被吸乳得到大胸91| 欧美日韩国产一区| 一区二区在线观看不卡| 岛国av在线一区| 欧美电影免费观看高清完整版在| 亚洲免费电影在线| 成人av午夜电影| 久久久无码精品亚洲日韩按摩| 一区二区三区高清不卡| 不卡的电影网站| 色成年激情久久综合| 18欧美亚洲精品| 从欧美一区二区三区| 欧美韩国一区二区| 懂色av一区二区三区免费观看| 欧美v国产在线一区二区三区| 亚洲成av人片在www色猫咪| 不卡电影免费在线播放一区| 国产精品丝袜在线| 成人黄色在线看| 国产精品久久久久久妇女6080| 国产成人99久久亚洲综合精品| 久久综合给合久久狠狠狠97色69| 人人狠狠综合久久亚洲| 日韩精品一区二区三区在线| 美女视频免费一区| 在线不卡中文字幕播放| 日韩vs国产vs欧美| 日韩美女在线视频| 国产麻豆精品一区二区| 中文在线资源观看网站视频免费不卡| 精品一区二区在线观看| 久久久高清一区二区三区| 国产精品一区在线| 国产精品免费av| 91久久线看在观草草青青| 婷婷久久综合九色综合伊人色| 在线不卡中文字幕播放| 久久99久久精品| 国产日韩欧美精品电影三级在线| 国产精品一区二区果冻传媒| 国产精品夫妻自拍| 欧美日韩一区高清| 国内精品国产三级国产a久久| 国产欧美日韩精品在线| 91小视频在线免费看| 亚洲一区二区三区影院| 欧美一二三区在线| 国产成人免费xxxxxxxx| 亚洲人被黑人高潮完整版| 欧美日韩免费在线视频| 久久不见久久见中文字幕免费| 国产无人区一区二区三区| 在线视频你懂得一区| 男人操女人的视频在线观看欧美| 欧美激情在线看| 欧美男生操女生| 国产成人av福利| 亚洲午夜免费视频| 国产日韩欧美综合在线| 91成人国产精品| 国产成人在线视频网址| 亚洲国产乱码最新视频| 久久综合久久综合九色| 91浏览器打开| 狠狠色丁香九九婷婷综合五月| 综合色天天鬼久久鬼色| 欧美一二三区在线| 91精品办公室少妇高潮对白| 精品亚洲国产成人av制服丝袜| 日韩理论在线观看| 久久综合色天天久久综合图片| 欧美在线999| 成人丝袜视频网| 麻豆国产一区二区| 亚洲chinese男男1069| 国产精品久久久久影院亚瑟| 日韩一区二区三区三四区视频在线观看 | 日韩欧美一卡二卡| 91在线视频官网| 国产一区二区三区黄视频 | 亚洲一区精品在线| 中文子幕无线码一区tr| 精品国产伦一区二区三区观看体验| 一道本成人在线| 不卡视频免费播放| 国产999精品久久久久久绿帽| 日韩国产在线观看一区| 亚洲美女免费在线| 中文字幕av一区二区三区| 欧美精品一区二区在线播放| 911国产精品| 欧美日韩在线播放一区| 91福利在线看| 99re热这里只有精品免费视频| 国产米奇在线777精品观看| 日本sm残虐另类| 免费在线观看视频一区| 日韩综合小视频| 亚洲国产成人av网| 午夜精品久久久久| 五月综合激情网| 日韩影院免费视频| 丝袜诱惑制服诱惑色一区在线观看| 一区二区三区免费| 亚洲一区二区高清| 午夜av区久久| 久久成人麻豆午夜电影| 精品一区二区三区在线观看 | 国产精品乱码妇女bbbb| 国产色爱av资源综合区| 国产三级精品三级| 亚洲欧洲性图库| 一区二区在线看| 亚洲国产综合色| 日韩精品一区第一页| 久久国产日韩欧美精品| 国内成人自拍视频| 国产aⅴ综合色| 色综合天天视频在线观看| 色综合久久综合中文综合网| 欧美图区在线视频| 日韩视频国产视频| 亚洲精品一区二区三区四区高清| 精品福利一二区| 国产精品乱人伦中文| 亚洲黄色av一区| 日本不卡高清视频| 国产成人一区二区精品非洲| 成人深夜福利app| 在线观看欧美日本| 日韩一区二区三区视频在线 | 一区二区三区在线免费播放| 一区二区三区不卡在线观看| 亚洲成在人线在线播放| 蜜臀av一区二区在线观看| 国产精品一品视频| 欧美亚洲精品一区| 亚洲精品在线电影| 亚洲精品国产视频| 蜜桃在线一区二区三区| 顶级嫩模精品视频在线看| 色婷婷av一区二区三区软件| 日韩亚洲欧美一区| 中文字幕精品一区二区精品绿巨人 | 99久久99久久综合| 欧美日韩亚洲综合在线| 久久精品人人做| 亚洲午夜影视影院在线观看| 国产自产v一区二区三区c| 色婷婷精品大在线视频| 欧美精品一区在线观看| 亚洲制服丝袜一区| 国产69精品久久久久毛片| 欧美美女一区二区在线观看| 国产欧美精品一区二区色综合 | 亚洲男同性恋视频| 美女尤物国产一区| 91黄色免费版| 久久人人爽人人爽| 视频一区二区三区入口| eeuss鲁一区二区三区| 欧美成人vps| 亚洲国产成人精品视频| 成人高清免费观看| 日韩精品一区二区三区四区视频| 最新国产精品久久精品| 国产中文字幕一区| 欧美日韩午夜在线视频| 国产精品理伦片| 国产精品一区专区| 欧美成人女星排行榜| 亚洲最大成人综合| av电影天堂一区二区在线观看| 日韩欧美在线观看一区二区三区| 亚洲精品中文在线| 大桥未久av一区二区三区中文| 日韩欧美中文字幕公布| 午夜影视日本亚洲欧洲精品| 91在线视频播放| 欧美激情在线看| 国产一区二区三区电影在线观看 |