A. linux里面编译安装显卡驱动失败求高手帮助
源码包的位置不正确,你可以在./config 的时候指定内核源码包位置。一般linux将内核源码装在了/usr/src/linux下,如果你所用的内核版本与源码包的版本不一致,则你要更新源码包,并重新生成生成version.h文件:
makeinclude/linux/version.h
makeinclude/asm
ls-l/lib/moles/3.x.x.x
其中3.x.x.x是你的源码包内核版本号。
然后,你再编译一次驱动,应该就能编译成功了。
B. Linux进程查看的who命令
该命令主要用于查看当前在线上的用户情况。这个命令非常有用。如果用户想和其他用户建立即时通讯,比如使用talk命令,那么首先要确定的就是该用户确实在线上,不然talk进程就无法建立起来。又如,系统管理员希望监视每个登录的用户此时此刻的所作所为,也要使用who命令。
who命令的常用语法格式如下:
who[imqsuwHT] [--count] [--idle] [--heading] [--help] [--message] [--mesg] [--version] [--writable] [file] [am i]
所有的选项都是可选的,也就是说可以单独使用who命令。
不使用任何选项时,who命令将显示以下三项内容:
login name:登录用户名;
terminal line:使用终端设备;
login time:登录到系统的时间。
如果给出的是两个非选项参数,那么who命令将只显示运行who程序的用户名、登录终端和登录时间。通常这两个参数是“am i”,即该命令格式为:“whoam i”。
下面对who命令的常用参数进行说明。
-m 和“whoam i”的作用一样,显示运行该程序的用户名。
-q,--count 只显示用户的登录帐号和登录用户的数量,该选项优先级高于其他任何选项。
-s 忽略。主要是用于和其他版本的who命令兼容。
-i,-u,--idle 在登录时间后面显示该用户最后一次对系统进行操作至今的时间,也就是常说的“发呆”时间。
-H,--heading 显示一行列标题。常用的标题如表4-2所示。
表4-2who命令输出常用标题
标 题
说 明
USER
用户登录帐号
LINE
用户登录使用终端
LOGIN-TIME
用户登录时间
IDLE
用户空闲时间,即未进行操作的时间
PID
用户登录shell的进程ID
FROM
用户网络地址
-w,-T--mesg,--message,--writable 和-s选项一样,在登录帐号后面显示一个字符来表示用户的信息状态:
+:允许写信息;
-:不允许写信息;
?:不能找到终端设备。
--help 在标准输出上显示帮助信息。
--version 在标准输出上显示版本信息。
下面介绍who命令的一些基本用法。
如果需要查看在系统上究竟有哪些用户,可以直接使用who命令。
[例17] 查看登录到系统的用户情况
$who
root tty1 Mar 17 13:49
foxytty2 Mar 17 13:49
root tty3 Mar 17 13:49
bbs ttyp0 Mar 17 13:49 (river.net)
可以看到,现在系统一共有四个用户。第一列是登录用户的帐号;第二列是登录所使用的终端;第三列是登录时间;第四列是用户从什么地方登录的网络地址,这里是域名。
一般来说,这样就可以了解登录用户的大致情况了。但有时上面的显示不是那么直观,因为没有标题说明,不容易看懂,这时就需要使用-H选项了。
[例18] 查看登录用户的详细情况,键入:
$who-uH
显示如下:
USER LINE LOGIN-TIME IDLE FROM
root tty1 Mar 17 13:49 .
foxytty2 Mar 17 13:49 00:01
root tty3 Mar 17 13:49 00:01
bbs ttyp0 Mar 17 13:49 00:01 (river.net)
这样一目了然。其中-u选项指定显示用户空闲时间,所以可以看到多了一项IDLE。第一个root用户的IDLE项是一个“.”,这就说明该用户在前1秒仍然是活动的,而其他用户后面都有一个时间,称为空闲时间。
最后来看看使用“whoam i”格式命令的结果:
233.river.net!root tty1 Mar 17 13:49
可见只显示出了运行该who命令的用户情况,当然这时候不存在空闲时间。
who命令应用起来非常简单,可以比较准确地掌握用户的情况,所以使用非常广泛。
C. Linux鍛戒护-鏂囦欢绠$悊鍛戒护
linux绯荤粺鍥犲叾浼樼鐨勭ǔ瀹氭у拰瀹夊叏鎬э紝琚瓒婃潵瓒婂氱殑浼佷笟鏈嶅姟鍣ㄥ簲鐢ㄣ傞殢涔嬭屾潵鐨勮秺鏉ヨ秺澶氱殑浜哄︿範浣跨敤linux锛岃屽仛涓簂inux绯荤粺鐨勫熀纭linux鍛戒护鏇存槸蹇呭︽棤鐤戠殑锛屽皬缂栦粖澶╄窡澶у跺垎浜涓绡囧皬缂栫簿蹇冪紪杈戠殑鏂囩珷鈥渓inux鍛戒护-鏂囦欢绠$悊鍛戒护鈥濓紝甯屾湜鑳藉府鍒板ぇ閮ㄥ垎鐨刲inux鍒濆﹁呫
cat 鍔熻兘锛氭湁浠庣佺洏鍒涘缓鏂囦欢鐨勫姛鑳斤紙浣嗕笉鍏峰囩紪杈戝姛鑳斤級锛屼絾涓昏佸姛鑳借繕鏄2涓鎴栬呬互涓婃枃浠剁殑鍚堝苟銆 甯搁厤鍚堜娇鐢ㄥ弬鏁帮細 -n 鎴--number 鐢1 寮濮嬪规墍鏈夎緭鍑虹殑琛屾暟缂栧彿銆 -b 鎴--number-nonblank 鍜-n 鐩镐技锛屽彧涓嶈繃瀵逛簬绌虹櫧琛屼笉缂栧彿銆 浣跨敤鏂规硶锛 Cat 鈥搉 diannaob1diannaob2,鎶奷iannaob1閲岀殑鍐呭瑰姞涓婅屽彿浠ュ悗骞跺叆diannaob2銆 Cat 鈥揵 diannaob1 diannaob2diannaob3,瀵筪iannaob1鍜宒iannaob2閲岀殑鍐呭瑰姞涓婅屽彿锛堢┖鐧借屼笉鍔狅級骞跺叆diannaob3銆
chattr 鍔熻兘锛氱粰鎸囧畾鏂囦欢娣诲姞锛屽幓鎺夛紝璧嬩簣灞炴с 甯搁厤鍚堜娇鐢ㄥ弬鏁帮細 -R 閫掑綊澶勭悊锛屽皢鎸囧畾鐩褰曚笅鐨勬墍鏈夋枃浠跺強瀛愮洰褰曚竴骞跺勭悊銆 -v鐗堟湰缂栧彿 璁剧疆鏂囦欢鎴栫洰褰曠増鏈銆 -V 鏄剧ず鎸囦护鎵ц岃繃绋嬨 +灞炴 寮鍚鏂囦欢鎴栫洰褰曠殑璇ラ」灞炴с -灞炴 鍏抽棴鏂囦欢鎴栫洰褰曠殑璇ラ」灞炴с =灞炴 鎸囧畾鏂囦欢鎴栫洰褰曠殑璇ラ」灞炴с a锛氳╂枃浠舵垨鐩褰曚粎渚涢檮鍔犵敤閫斻 b锛氫笉鏇存柊鏂囦欢鎴栫洰褰曠殑鏈鍚庡瓨鍙栨椂闂淬 c锛氬皢鏂囦欢鎴栫洰褰曞帇缂╁悗瀛樻斁銆 d锛氬皢鏂囦欢鎴栫洰褰曟帓闄ゅ湪鍊惧掓搷浣滀箣澶栥 i锛氫笉寰椾换鎰忔洿鍔ㄦ枃浠舵垨鐩褰曘 s锛氫繚瀵嗘у垹闄ゆ枃浠舵垨鐩褰曘 S锛氬嵆鏃舵洿鏂版枃浠舵垨鐩褰曘 u锛氶勯槻浠ュ栧垹闄ゃ 浣跨敤鏂规硶锛 姣斿俤iannaob1杩欎釜鏂囦欢涓轰簡鏂瑰紡琚鍏朵粬linux鐢ㄦ埛鍒犻櫎锛屽彲浠ョ粰鍏舵坊鍔犻勯槻浠ュ栧垹闄ゅ睘鎬с Chattr +u diannaob1
chgrp 鍔熻兘锛氭洿鏀圭洰褰曟垨鑰呮枃浠舵墍灞炵殑缇ょ粍銆 浣跨敤鏂规硶锛 姣斿傛妸diannaob1鏂囦欢绉诲姩鍒癲iannaob缁勯噷锛欳hgrp diannaob diannaob1
cmp 鍔熻兘锛氱敤鏉ユ瘮杈冩枃浠朵箣闂寸殑涓嶅悓锛屽傛灉鐩稿悓涓嶈繑鍥炰换浣曚俊鎭锛屼笉鍚岀殑鍦版柟鍒楀嚭瀛楃﹀拰鍒楁暟缂栧彿銆 甯搁厤鍚堜娇鐢ㄥ弬鏁帮細 -c鎴--print-chars 銆闄や簡鏍囨槑宸寮傚勭殑鍗佽繘鍒跺瓧鐮佷箣澶栵紝涓骞舵樉绀鸿ュ瓧绗︽墍瀵瑰簲瀛楃︺ -i瀛楃︽暟鐩鎴--ignore-initial=瀛楃︽暟鐩 銆鎸囧畾涓涓鏁扮洰銆 -l鎴--verbose 銆鏍囩ず鍑烘墍鏈変笉涓鏍风殑鍦版柟銆 -s鎴--quiet鎴--silent 銆涓嶆樉绀洪敊璇淇℃伅銆 -v鎴--version 銆鏄剧ず鐗堟湰淇℃伅銆 --help 銆鍦ㄧ嚎甯鍔┿ 浣跨敤鏂规硶锛 姣斿傛瘮杈冩枃浠禿iannaob1鍜宒iannaob2鏈変粈涔堝悓 Cmp diannaob1 diannaob2閰嶅悎浣跨敤鐨勫弬鏁板姞鍦╟mp鍜屾枃浠朵箣闂淬
file 鍔熻兘锛氳鲸璇嗘枃浠剁被鍨嬨 甯搁厤鍚堜娇鐢ㄥ弬鏁帮細 -b 銆鍒楀嚭杈ㄨ瘑缁撴灉鏃讹紝涓嶆樉绀烘枃浠跺悕绉般 -c 銆璇︾粏鏄剧ず鎸囦护鎵ц岃繃绋嬶紝渚夸簬鎺掗敊鎴栧垎鏋愮▼搴忔墽琛岀殑鎯呭舰銆 -f鍚嶇О鏂囦欢 銆鎸囧畾鍚嶇О鏂囦欢锛屽叾鍐呭规湁涓涓鎴栧氫釜鏂囦欢鍚嶇О鍛㈡劅锛岃ゝile渚濆簭杈ㄨ瘑杩欎簺鏂囦欢锛屾牸寮忎负姣忓垪涓涓鏂囦欢鍚嶇О銆 -L 銆鐩存帴鏄剧ず绗﹀彿杩炴帴鎵鎸囧悜鐨勬枃浠剁殑绫诲埆銆 -m榄旀硶鏁板瓧鏂囦欢 銆鎸囧畾榄旀硶鏁板瓧鏂囦欢銆 -v 銆鏄剧ず鐗堟湰淇℃伅銆 -z 銆灏濊瘯鍘昏В璇诲帇缂╂枃浠剁殑鍐呭广 浣跨敤鏂规硶锛 姣斿傝佽鲸鍒玠iannaob1鐨勬枃浠剁被鍨 File diannaob1 鏂囦欢浣嶇疆
find 鍔熻兘锛氭牴鎹鍚勭嶉渶姹傦紙鍚嶇О銆佺被鍒銆佹椂闂淬佸ぇ灏忋佹潈闄愮瓑锛夊湪鎸囧畾鐨勭洰褰曞唴瀵绘壘绗﹀悎瑕佹眰鐨勬枃浠躲 甯搁厤鍚堜娇鐢ㄥ弬鏁帮細 -mount, -xdev : 鍙妫鏌ュ拰鎸囧畾鐩褰曞湪鍚屼竴涓妗f堢郴缁熶笅鐨勬。妗堬紝閬垮厤鍒楀嚭鍏跺畠妗f堢郴缁熶腑鐨勬。妗 -amin n : 鍦ㄨ繃鍘籲 鍒嗛挓鍐呰璇诲彇杩 -anewer file : 姣旀。妗坒ile 鏇存櫄琚璇诲彇杩囩殑妗f -atime n : 鍦ㄨ繃鍘籲 澶╄繃璇诲彇杩囩殑妗f -cmin n : 鍦ㄨ繃鍘籲 鍒嗛挓鍐呰淇鏀硅繃 -cnewer file :姣旀。妗坒ile 鏇存柊鐨勬。妗 -ctime n : 鍦ㄨ繃鍘籲 澶╄繃淇鏀硅繃鐨勬。妗 -empty : 绌虹殑妗f-gid n or -group name : gid 鏄痭 鎴栨槸group 鍚嶇О鏄痭ame -ipath p, -path p : 璺寰勫悕绉扮﹀悎p 鐨勬。妗堬紝ipath 浼氬拷鐣ュぇ灏忓啓 -name name, -iname name : 妗f堝悕绉扮﹀悎name 鐨勬。妗堛俰name 浼氬拷鐣ュぇ灏忓啓 -size n : 妗f堝ぇ灏忔槸n 鍗曚綅锛宐 浠h〃512 浣嶅厓缁勭殑鍖哄潡锛宑 琛ㄧず瀛楀厓鏁帮紝k 琛ㄧずkilo bytes锛寃 鏄浜屼釜浣嶅厓缁勩-type c : 妗f堢被鍨嬫槸c 鐨勬。妗堛 d: 鐩褰 c: 瀛楀瀷瑁呯疆妗f b: 鍖哄潡瑁呯疆妗f p: 鍏峰悕璐鍒 f: 涓鑸妗f l: 绗﹀彿杩炵粨 浣跨敤鏂规硶锛 灏嗙洰鍓嶇洰褰曞強鍏跺瓙鐩褰曚笅鎵鏈夊欢浼告。鍚嶆槸c 鐨勬。妗堝垪鍑烘潵銆 find . -name "*.c" 灏嗙洰鍓嶇洰褰曞叾鍏朵笅瀛愮洰褰曚腑鎵鏈変竴鑸妗f堝垪鍑 find . -ftype f 灏嗙洰鍓嶇洰褰曞強鍏跺瓙鐩褰曚笅鎵鏈夋渶杩20 鍒嗛挓鍐呮洿鏂拌繃鐨勬。妗堝垪鍑篺ind . -ctime -20
git 鍔熻兘锛氭枃瀛楁ā寮忎笅鐨勬枃浠剁$悊鍛橈紝杩涘叆涔嬪悗锛屽彲浠ヨ繘琛屽悇绉嶆枃浠剁殑鎿嶄綔銆 甯搁厤鍚堜娇鐢ㄥ弬鏁帮細F1 锛氭墽琛宨nfo鎸囦护锛屾煡璇㈡寚浠ょ浉鍏充俊鎭锛屼細瑕佹眰鎮ㄨ緭鍏ユ叉煡璇㈢殑鍚嶇О銆 F2 锛氭墽琛宑at鎸囦护锛屽垪鍑烘枃浠跺唴瀹广 F3 锛氭墽琛実itview鎸囦护锛岃傜湅鏂囦欢鍐呭广 F4 锛氭墽琛寁i鎸囦护锛岀紪杈戞枃浠跺唴瀹广 F5 锛氭墽琛宑p鎸囦护锛屽嶅埗鏂囦欢鎴栫洰褰曪紝浼氳佹眰鎮ㄨ緭鍏ョ洰鏍囨枃浠舵垨鐩褰曘 F6 锛氭墽琛宮v鎸囦护锛岀Щ鍔ㄦ枃浠舵垨鐩褰曪紝鎴栨槸鏇存敼鍏跺悕绉帮紝浼氳佹眰鎮ㄨ緭鍏ョ洰鏍囨枃浠舵垨鐩褰曘 F7 锛氭墽琛宮kdir鎸囦护锛屽缓绔嬬洰褰曘 F8 锛氭墽琛宺m鎸囦护锛屽垹闄ゆ枃浠舵垨鐩褰曘 F9 锛氭墽琛宮ake鎸囦护锛屾壒澶勭悊鎵ц屾寚浠ゆ垨缂栬瘧绋嬪簭鏃讹紝浼氳佹眰鎮ㄨ緭鍏ョ浉鍏冲懡浠ゃ F10 锛氱诲紑git鏂囦欢绠$悊鍛樸
cut 鍔熻兘锛氱敤浜庝粠鏂囦欢鎴栬呮爣鍑嗚緭鍏ヤ腑璇诲彇鍐呭瑰苟鎴鍙栨瘡涓琛岀殑鐗瑰畾閮ㄥ垎骞堕佸埌鏍囧噯杈撳嚭銆 閰嶅悎浣跨敤鍙傛暟锛 -b 瀛楄妭锛坆ytes锛 -c 瀛楃︼紙characters锛 -f 鍩燂紙fields锛 浣跨敤鏂规硶锛 濡傛棩鏈燂細dc oct 10 21:15:54 PDT 2012 Date |cut 鈥揵 1-4 杈撳嚭dc o锛岃〃绀哄彇鍓4涓瀛楄妭锛屽叾涓绌烘牸涔熺畻涓涓瀛楄妭銆 Date |cut 鈥揷 1-4 杈撳嚭dc o锛岀湅浼艰窡-b娌℃湁鍖哄埆锛屼絾鏄濡傛灉鏃ユ湡鎹㈡垚姹夊瓧灏辨湁鍖哄埆浜嗭紝鍥犱负涓涓姹夊瓧绠3涓瀛楄妭銆 澶氫釜瀹氫綅涔嬮棿鐢ㄩ楀彿闅斿紑锛 Date |cut 鈥揵 1-4,6 杈撳嚭鍓4涓瀛楄妭鍜岀6涓瀛楄妭锛歞c ot 鍒嗗壊鍩燂細 濡傦細 service1:pts/0:Oct 9 20:27: (211.95.114.235) service2:pts/1:Oct 9 21:06: (218.80.203.242) service3:pts/2:Oct 9 14:35: (218.80.203.242) service4:pts/3:Oct 9 21:07: (218.80.213.242) service5:pts/4:Oct 9 21:07: (218.80.213.242) service6:pts/5:Oct 9 21:45: (58.31.205.19) cut 鈥揹: -f1 f.txt 鎶奻.txt杩欎釜鏂囦欢鎸夛細鍒嗗壊鎴愬煙锛屽彇鍩1 杈撳嚭锛 service1 service2 service3 service4 service5 service6 linux瀛︿範锛氬噯淇″煿璁涓蹇冿紙training.zhunxin.net锛 2.in 鍔熻兘锛氬垱寤鸿繛鎺ワ紙绫讳技浜巜indow涓嬪垱寤鸿秴閾炬帴锛 浣跨敤鏂规硶锛 鎶婂皢鐩褰/usr/menggc/mub l涓嬬殑鏂囦欢m2.c閾炬帴鍒扮洰J/usr/1iu涓嬬殑鏂囦欢a2.c In /usr/menggc/mub l/m2.c J/usr/1iu/a2.c 鏈鏉J/usr/1iu鐩褰曚笅娌℃湁a2.c鏂囦欢锛屽綋閾炬帴鎴愬姛鏃跺氨浼氬嚭鐜癮2.c鏂囦欢銆 In 閫夐」婧愭枃浠剁洰鏍囨枃浠
less 鍔熻兘锛氭煡鐪嬫枃浠 浣跨敤鏂规硶锛 Less 鏂囦欢鍚 Less鐨勪綔鐢ㄥ拰more宸涓嶅氾紝涓嶅悓鐨勬槸less 鍏佽镐娇鐢ㄨ呭線鍥炲嵎鍔锛屾煡鐪嬪凡缁忕湅杩囩殑閮ㄥ垎銆
鍚嶇О锛歭ocate 浣跨敤鏉冮檺锛氭墍鏈変娇鐢ㄨ 浣跨敤鏂瑰紡锛 locate [-q] [-d ] [--database=] locate [-r ] [--regexp=] locate [-qv] [-o ] [--output=] locate [-e ] [-f ] [-l ] [-c] [-U ] [-u] locate [-Vh] [--version] [--help] 璇存槑锛 locate 璁╀娇鐢ㄨ呭彲浠ュ緢蹇閫熺殑鎼滃绘。妗堢郴缁熷唴鏄鍚︽湁鎸囧畾鐨勬。妗堛傚叾鏂规硶鏄鍏堝缓绔嬩竴涓鍖呮嫭绯荤粺鍐呮墍鏈夋。妗堝悕绉板強璺寰勭殑璧勬枡搴,涔嬪悗褰撳绘壘鏃跺氨鍙闇鏌ヨ㈣繖涓璧勬枡搴,鑰屼笉蹇呭疄闄呮繁鍏ユ。妗堢郴缁熶箣涓浜嗐傚湪涓鑸鐨刣istribution 涔嬩腑,璧勬枡搴撶殑寤虹珛閮借鏀惧湪contab 涓鑷鍔ㄦ墽琛屻 涓鑸浣跨敤鑰呭湪浣跨敤鏃跺彧瑕佺敤 # locate your_file_name 鐨勫瀷寮忓氨鍙浠ヤ簡銆傚弬鏁帮細 -u -U 寤虹珛璧勬枡搴,-u 浼氱敱鏍圭洰褰曞紑濮,-U 鍒欏彲浠ユ寚瀹氬紑濮嬬殑浣嶇疆銆 -e 灏嗘帓闄ゅ湪瀵绘壘鐨勮寖鍥翠箣澶栥 -l 濡傛灉鏄1锛庡垯鍚鍔ㄥ畨鍏ㄦā寮忋傚湪瀹夊叏妯″紡涓,浣跨敤鑰呬笉浼氱湅鍒版潈闄愭棤娉曠湅鍒扮殑妗f堛傝繖浼氬嬮熷害鍑忔參,鍥犱负locate 蹇呴』鑷冲疄闄呯殑妗f堢郴缁熶腑鍙栧緱妗f堢殑鏉冮檺璧勬枡銆 -f 灏嗙壒瀹氱殑妗f堢郴缁熸帓闄ゅ湪澶,渚嬪傛垜浠娌℃湁鍒扮悊瑕佹妸proc 妗f堢郴缁熶腑鐨勬。妗堟斁鍦ㄨ祫鏂欏簱涓銆 -q 瀹夐潤妯″紡,涓嶄細鏄剧ず浠讳綍閿欒璁鎭銆 -n 鑷冲氭樉绀轰釜杈撳嚭銆 -r 浣跨敤姝h勮繍绠楀紡鍋氬绘壘鐨勬潯浠躲 -o 鎸囧畾璧勬枡搴撳瓨鐨勫悕绉般 -d 鎸囧畾璧勬枡搴撶殑璺寰 -h 鏄剧ず杈呭姪璁鎭 -v 鏄剧ず鏇村氱殑璁鎭 -V 鏄剧ず绋嬪紡鐨勭増鏈璁鎭鑼冧緥锛 locate chdrv:瀵绘壘鎵鏈夊彨chdrv 鐨勬。妗 locate -n 100 a.out:瀵绘壘鎵鏈夊彨a.out 鐨勬。妗,浣嗘渶澶氬彧鏄剧ず100 涓 locate -u:寤虹珛璧勬枡搴
鍚嶇О锛歮ore 浣跨敤鏉冮檺锛氭墍鏈変娇鐢ㄨ 浣跨敤鏂瑰紡锛歮ore [-dlfpcsu] [-num] [+/pattern] [+linenum] [fileNames..] 璇存槑锛氱被浼糲at ,涓嶈繃浼氫互涓椤典竴椤电殑鏄剧ず鏂逛究浣跨敤鑰呴愰〉闃呰,鑰屾渶鍩烘湰鐨勬寚浠ゅ氨鏄鎸夌┖鐧介敭锛坰pace锛夊氨寰涓嬩竴椤垫樉绀,鎸塨 閿灏变細寰鍥烇紙back锛変竴椤垫樉绀,鑰屼笖杩樻湁鎼滃诲瓧涓茬殑鍔熻兘锛堜笌vi 鐩镐技锛,浣跨敤涓鐨勮存槑鏂囦欢,璇锋寜h 銆 鍙傛暟锛 -num 涓娆℃樉绀虹殑琛屾暟 -d 鎻愮ず浣跨敤鑰,鍦ㄧ敾闈涓嬫柟鏄剧ず[Press space to continue, q to quit.] ,濡傛灉浣跨敤鑰呮寜閿欓敭,鍒欎細鏄剧ず[Press h for instructions.] 鑰屼笉鏄鍝斿0 -l 鍙栨秷閬囪佺壒娈婂瓧鍏僞L锛堥佺焊瀛楀厓锛夋椂浼氭殏鍋滅殑鍔熻兘 -f 璁$畻琛屾暟鏃,浠ュ疄闄呬笂鐨勮屾暟,鑰岄潪鑷鍔ㄦ崲琛岃繃鍚庣殑琛屾暟锛堟湁浜涘崟琛屽瓧鏁板お闀跨殑浼氳鎵╁睍涓轰袱琛屾垨涓よ屼互涓婏級 -p 涓嶄互鍗峰姩鐨勬柟寮忔樉绀烘瘡涓椤,鑰屾槸鍏堟竻闄よ悿骞曞悗鍐嶆樉绀哄唴瀹 -c 璺-p 鐩镐技,涓嶅悓鐨勬槸鍏堟樉绀哄唴瀹瑰啀娓呴櫎鍏朵粬鏃ц祫鏂 -s 褰撻亣鍒版湁杩炵画涓よ屼互涓婄殑绌虹櫧琛,灏变唬鎹涓轰竴琛岀殑绌虹櫧琛 -u 涓嶆樉绀轰笅寮曞彿锛堟牴鎹鐜澧冨彉鏁癟ERM 鎸囧畾鐨則erminal 鑰屾湁鎵涓嶅悓锛 +/ 鍦ㄦ瘡涓妗f堟樉绀哄墠鎼滃昏ュ瓧涓诧紙pattern锛,鐒跺悗浠庤ュ瓧涓蹭箣鍚庡紑濮嬫樉绀 +num 浠庣琻um 琛屽紑濮嬫樉绀 fileNames 娆叉樉绀哄唴瀹圭殑妗f,鍙涓哄嶆暟涓鏁 鑼冧緥锛 more -s testfile 閫愰〉鏄剧ずtestfile 涔嬫。妗堝唴瀹,濡傛湁杩炵画涓よ屼互涓婄┖鐧借屽垯浠ヤ竴琛岀┖鐧借屾樉绀恒 more +20 testfile 浠庣20 琛屽紑濮嬫樉绀簍estfile 涔嬫。妗堝唴瀹广
鍚嶇О锛歮v 浣跨敤鏉冮檺锛氭墍鏈変娇鐢ㄨ 浣跨敤鏂瑰紡锛 mv [options] source dest mv [options] source... directory 璇存槑锛氬皢涓涓妗f堢Щ鑷冲彟涓妗f,鎴栧皢鏁颁釜妗f堢Щ鑷冲彟涓鐩褰曘 鍙傛暟锛-i 鑻ョ洰鐨勫湴宸叉湁鍚屽悕妗f,鍒欏厛璇㈤棶鏄鍚﹁嗙洊鏃ф。銆 鑼冧緥锛 灏嗘。妗坅aa 鏇村悕涓篵bb: mv aaa bbb 灏嗘墍鏈夌殑C璇瑷绋嬪紡绉昏嚦Finished 瀛愮洰褰曚腑: mv -i *.c
鍚嶇О锛歳m 浣跨敤鏉冮檺锛氭墍鏈変娇鐢ㄨ 浣跨敤鏂瑰紡锛歳m [options] name... 璇存槑锛氬垹闄ゆ。妗堝強鐩褰曘 鎶婅: -i 鍒犻櫎鍓嶉愪竴璇㈤棶纭璁ゃ -f 鍗充娇鍘熸。妗堝睘鎬ц句负鍞璇,浜︾洿鎺ュ垹闄,鏃犻渶閫愪竴纭璁ゃ -r 灏嗙洰褰曞強浠ヤ笅涔嬫。妗堜害閫愪竴鍒犻櫎銆 鑼冧緥锛 鍒犻櫎鎵鏈塁璇瑷绋嬪紡妗o紱鍒犻櫎鍓嶉愪竴璇㈤棶纭璁: rm -i *.c 灏咶inished 瀛愮洰褰曞強瀛愮洰褰曚腑鎵鏈夋。妗堝垹闄: rm -r Finished
鍚嶇О锛歴plit 浣跨敤鏉冮檺锛氭墍鏈変娇鐢ㄨ 浣跨敤鏂瑰紡锛歴plit [OPTION] [INPUT [PREFIX]] 璇存槑锛氬皢涓涓妗f堝垎鍓叉垚鏁颁釜銆傝屼粠INPUT 鍒嗗壊杈撳嚭鎴愬浐瀹氬ぇ灏忕殑妗f,鍏舵。鍚嶄緷搴忎负PREFIXaa, PREFIXab...锛汸REFIX 棰勮惧间负`x銆傝嫢娌℃湁INPUT 妗f垨涓篳-,鍒欎粠鏍囧噯杈撳叆璇昏繘璧勬枡銆 鍖″厹: -b, --bytes=SIZE SIZE 鍊间负姣忎竴杈撳嚭妗f堢殑澶у皬,鍗曚綅涓篵yte銆 -C, --line-bytes=SIZE 姣忎竴杈撳嚭妗d腑,鍗曡岀殑鏈澶byte 鏁般 -l, --lines=NUMBER NUMBER 鍊间负姣忎竴杈撳嚭妗g殑鍒楁暟澶у皬銆 -NUMBER 涓-l NUMBER 鐩稿悓銆 --verbose 浜庢瘡涓杈撳嚭妗h寮鍚鍓,鍒楀嵃鍑轰睛閿欒祫璁鍒版爣鍑嗛敊璇杈撳嚭銆 --help 鏄剧ず杈呭姪璧勮鐒跺悗绂诲紑銆 --version 鍒楀嚭鐗堟湰璧勮鐒跺悗绂诲紑銆 SIZE 鍙鍔犲叆鍗曚綅: b 浠h〃512, k 浠h〃1K, m 浠h〃1 Meg銆 鑼冧緥锛 PostgresSQL 澶у瀷璧勬枡搴撳囦唤涓庡洖瀛橈細 鍥燩ostgres 鍏佽歌〃鏍煎ぇ杩囦綘绯荤粺妗f堢殑鏈澶у归噺,鎵浠ヨ佸皢琛ㄦ牸mp 鍒板崟涓鐨勬。妗堝彲鑳戒細鏈夐棶棰,浣跨敤split杩涜屾。妗堝垎鍓层 % pg_mp dbname | split -b 1m - filename.mp. 閲嶆柊杞藉叆 % createdb dbname % cat filename.mp.* | pgsql dbname
鍚嶇О锛歵ouch 浣跨敤鏉冮檺锛氭墍鏈変娇鐢ㄨ 浣跨敤鏂瑰紡锛 touch [-acfm] [-r reference-file] [--file=reference-file] [-t MMDDhhmm[[CC]YY][.ss]] [-d time] [--date=time] [--time={atime,access,use,mtime,modify}] [--no-create] [--help] [--version] file1 [file2 ...] 璇存槑锛 touch 鎸囦护鏀瑰彉妗f堢殑鏃堕棿璁板綍銆俵s -l 鍙浠ユ樉绀烘。妗堢殑鏃堕棿璁板綍銆 鍙傛暟锛 a 鏀瑰彉妗f堢殑璇诲彇鏃堕棿璁板綍銆 m 鏀瑰彉妗f堢殑淇鏀规椂闂磋板綍銆 c 鍋囧傜洰鐨勬。妗堜笉瀛樺湪,涓嶄細寤虹珛鏂扮殑妗f堛備笌--no-create 鐨勬晥鏋滀竴鏍枫 f 涓嶄娇鐢,鏄涓轰簡涓庡叾浠杣nix 绯荤粺鐨勭浉瀹规ц屼繚鐣欍 r 浣跨敤鍙傝冩。鐨勬椂闂磋板綍,涓--file 鐨勬晥鏋滀竴鏍枫 d 璁惧畾鏃堕棿涓庢棩鏈,鍙浠ヤ娇鐢ㄥ悇绉嶄笉鍚岀殑鏍煎紡銆 t 璁惧畾妗f堢殑鏃堕棿璁板綍,鏍煎紡涓巇ate 鎸囦护鐩稿悓銆 --no-create 涓嶄細寤虹珛鏂版。妗堛 --help 鍒楀嚭鎸囦护鏍煎紡銆 --version 鍒楀嚭鐗堟湰璁鎭銆 鑼冧緥锛 鏈绠鍗曠殑浣跨敤鏂瑰紡,灏嗘。妗堢殑鏃跺欒板綍鏀逛负鐜板湪鐨勬椂闂淬傝嫢妗f堜笉瀛樺湪,绯荤粺浼氬缓绔嬩竴涓鏂扮殑妗f堛 touch file touch file1 file2 灏唂ile 鐨勬椂闂磋板綍鏀逛负5 鏈6 鏃18 鐐3 鍒,鍏鍏冧袱鍗冨勾銆傛椂闂寸殑鏍煎紡鍙浠ュ弬鑰僤ate 鎸囦护,鑷冲皯闇杈撳叆MMDDHHmm ,灏辨槸鏈堟棩鏃朵笌鍒嗐 touch -c -t 05061803 file touch -c -t 050618032000 file 灏唂ile 鐨勬椂闂磋板綍鏀瑰彉鎴愪笌referencefile 涓鏍枫 touch -r referencefile file 灏唂ile 鐨勬椂闂磋板綍鏀规垚5 鏈6 鏃18 鐐3 鍒,鍏鍏冧袱鍗冨勾銆傛椂闂村彲浠ヤ娇鐢╝m, pm 鎴栨槸24 灏忔椂鐨勬牸寮,鏃ユ湡鍙浠ヤ娇鐢ㄥ叾浠栨牸寮忓6 May 2000 銆 touch -d "6:03pm" file touch -d "05/06/2000" file touch -d "6:03pm 05/06/2000" file
鍚嶇О锛歝p 浣跨敤鏉冮檺锛氭墍鏈変娇鐢ㄨ 浣跨敤鏂瑰紡锛 cp [options] source dest cp [options] source... directory 璇存槑锛氬皢涓涓妗f堟嫹璐濊嚦鍙︿竴妗f,鎴栧皢鏁颁釜妗f堟嫹璐濊嚦鍙︿竴鐩褰曘 鎶婅: -a 灏藉彲鑳藉皢妗f堢姸鎬,鏉冮檺绛夎祫鏂欓兘鐓у師鐘朵簣浠ュ嶅埗銆 -r 鑻source 涓鍚鏈夌洰褰曞悕,鍒欏皢鐩褰曚笅涔嬫。妗堜害鐨嗕緷搴忔嫹璐濊嚦鐩鐨勫湴銆 -f 鑻ョ洰鐨勫湴宸茬粡鏈夌浉鍚屾。鍚嶇殑妗f堝瓨鍦,鍒欏湪澶嶅埗鍓嶅厛浜堜互鍒犻櫎鍐嶈屽嶅埗銆 鑼冧緥锛 灏嗘。妗坅aa 澶嶅埗(宸插瓨鍦),骞跺懡鍚嶄负bbb: cp aaa bbb 灏嗘墍鏈夌殑C璇瑷绋嬪紡鎷疯礉鑷矲inished 瀛愮洰褰曚腑: cp *.c Finished
鎸囦护鍚嶇О:ln 浣跨敤鏉冮檺:鎵鏈変娇鐢ㄨ 浣跨敤鏂瑰紡:ln [options] source dist,鍏朵腑option 鐨勬牸寮忎负: [-bdfinsvF] [-S backup-suffix] [-V {numbered,existing,simple}] [--help] [--version] [--] 璇存槑:Linux/Unix 妗f堢郴缁熶腑,鏈夋墍璋撶殑杩炵粨(link),鎴戜滑鍙浠ュ皢鍏惰嗕负妗f堢殑鍒鍚,鑰岃繛缁撳張鍙鍒嗕负涓ょ:纭杩炵粨(hard link)涓庤蒋杩炵粨(symbolic link),纭杩炵粨鐨勬剰鎬濇槸涓涓妗f堝彲浠ユ湁澶氫釜鍚嶇О,鑰岃蒋杩炵粨鐨勬柟寮忓垯鏄浜х敓涓涓鐗规畩鐨勬。妗,璇ユ。妗堢殑鍐呭规槸鎸囧悜鍙︿竴涓妗f堢殑浣嶇疆銆傜‖杩炵粨鏄瀛樺湪鍚屼竴涓妗f堢郴缁熶腑,鑰岃蒋杩炵粨鍗村彲浠ヨ法瓒婁笉鍚岀殑妗f堢郴缁熴 ln source dist 鏄浜х敓涓涓杩炵粨(dist)鍒皊ource,鑷充簬浣跨敤纭杩炵粨鎴栬蒋閾剧粨鍒欑敱鍙傛暟鍐冲畾銆 涓嶈烘槸纭杩炵粨鎴栬蒋閾剧粨閮戒笉浼氬皢鍘熸湰鐨勬。妗堝嶅埗涓浠,鍙浼氬崰鐢ㄩ潪甯稿皯閲忕殑纾佺熺┖闂淬 -f:閾剧粨鏃跺厛灏嗕笌dist 鍚屾。鍚嶇殑妗f堝垹闄-d:鍏佽哥郴缁熺$悊鑰呯‖閾剧粨鑷宸辩殑鐩褰-i:鍦ㄥ垹闄や笌dist 鍚屾。鍚嶇殑妗f堟椂鍏堣繘琛岃㈤棶-n:鍦ㄨ繘琛岃蒋杩炵粨鏃,灏哾ist 瑙嗕负涓鑸鐨勬。妗-s:杩涜岃蒋閾剧粨(symbolic link)-v:鍦ㄨ繛缁撲箣鍓嶆樉绀哄叾妗e悕-b:灏嗗湪閾剧粨鏃朵細琚瑕嗗啓鎴栧垹闄ょ殑妗f堣繘琛屽囦唤-S SUFFIX:灏嗗囦唤鐨勬。妗堥兘鍔犱笂SUFFIX 鐨勫瓧灏-V METHOD:鎸囧畾澶囦唤鐨勬柟寮--help:鏄剧ず杈呭姪璇存槑--version:鏄剧ず鐗堟湰 鑼冧緥: 灏嗘。妗坹y 浜х敓涓涓猻ymbolic link:zz ln -s yy zz 灏嗘。妗坹y 浜х敓涓涓猦ard link:zz ln yy xx
D. 如何编写一个简单的linux内核模块和设备驱动程序
如何编写Linux设备驱动程序
回想学习Linux操作系统已经有近一年的时间了,前前后后,零零碎碎的一路学习过来,也该试着写的东西了。也算是给自己能留下一点记忆和回忆吧!由于完全是自学的,以下内容若有不当之处,还请大家多指教。
Linux是Unix操作系统的一种变种,在Linux下编写驱动程序的原理和思想完全类似于其他的Unix系统,但它dos或window环境下的驱动程序有很大的区别。在Linux环境下设计驱动程序,思想简洁,操作方便,功能也很强大,但是支持函数少,只能依赖kernel中的函数,有些常用的操作要自己来编写,而且调试也不方便。
以下的一些文字主要来源于khg,johnsonm的Write linux device driver,Brennan's Guide to Inline Assembly,The Linux a-z,还有清华bbs上的有关device driver的一些资料。
一、Linux device driver 的概念
系统调用是操作系统内核和应用程序之间的接口,设备驱动程序是操作系统内核和机器硬件之间的接口。设备驱动程序为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是一个设备文件,应用程序可以象操作普通文件一样对硬件设备进行操作。设备驱动程序是内核的一部分,它完成以下的功能:
1、对设备初始化和释放。
2、把数据从内核传送到硬件和从硬件读取数据。
3、读取应用程序传送给设备文件的数据和回送应用程序请求的数据。
4、检测和处理设备出现的错误。
在Linux操作系统下有三类主要的设备文件类型,一是字符设备,二是块设备,三是网络设备。字符设备和块设备的主要区别是:在对字符设备发出读/写请求时,实际的硬件I/O一般就紧接着发生了,块设备则不然,它利用一块系统内存作缓冲区,当用户进程对设备请求能满足用户的要求,就返回请求的数据,如果不能,就调用请求函数来进行实际的I/O操作。块设备是主要针对磁盘等慢速设备设计的,以免耗费过多的CPU时间来等待。
已经提到,用户进程是通过设备文件来与实际的硬件打交道。每个设备文件都都有其文件属性(c/b),表示是字符设备还是块设备?另外每个文件都有两个设备号,第一个是主设备号,标识驱动程序,第二个是从设备号,标识使用同一个设备驱动程序的不同的硬件设备,比如有两个软盘,就可以用从设备号来区分他们。设备文件的的主设备号必须与设备驱动程序在登记时申请的主设备号一致,否则用户进程将无法访问到驱动程序。
最后必须提到的是,在用户进程调用驱动程序时,系统进入核心态,这时不再是抢先式调度。也就是说,系统必须在你的驱动程序的子函数返回后才能进行其他的工作。如果你的驱动程序陷入死循环,不幸的是你只有重新启动机器了,然后就是漫长的fsck。
读/写时,它首先察看缓冲区的内容,如果缓冲区的数据未被处理,则先处理其中的内容。
如何编写Linux操作系统下的设备驱动程序
二、实例剖析
我们来写一个最简单的字符设备驱动程序。虽然它什么也不做,但是通过它可以了解Linux的设备驱动程序的工作原理。把下面的C代码输入机器,你就会获得一个真正的设备驱动程序。
#define __NO_VERSION__
#include <linux/moles.h>
#include <linux/version.h>
char kernel_version [] = UTS_RELEASE;
这一段定义了一些版本信息,虽然用处不是很大,但也必不可少。Johnsonm说所有的驱动程序的开头都要包含<linux/config.h>,一般来讲最好使用。
由于用户进程是通过设备文件同硬件打交道,对设备文件的操作方式不外乎就是一些系统调用,如 open,read,write,close…, 注意,不是fopen, fread,但是如何把系统调用和驱动程序关联起来呢?这需要了解一个非常关键的数据结构:
struct file_operations
{
int (*seek) (struct inode * ,struct file *, off_t ,int);
int (*read) (struct inode * ,struct file *, char ,int);
int (*write) (struct inode * ,struct file *, off_t ,int);
int (*readdir) (struct inode * ,struct file *, struct dirent * ,int);
int (*select) (struct inode * ,struct file *, int ,select_table *);
int (*ioctl) (struct inode * ,struct file *, unsined int ,unsigned long);
int (*mmap) (struct inode * ,struct file *, struct vm_area_struct *);
int (*open) (struct inode * ,struct file *);
int (*release) (struct inode * ,struct file *);
int (*fsync) (struct inode * ,struct file *);
int (*fasync) (struct inode * ,struct file *,int);
int (*check_media_change) (struct inode * ,struct file *);
int (*revalidate) (dev_t dev);
}
这个结构的每一个成员的名字都对应着一个系统调用。用户进程利用系统调用在对设备文件进行诸如read/write操作时,系统调用通过设备文件的主设备号找到相应的设备驱动程序,然后读取这个数据结构相应的函数指针,接着把控制权交给该函数。这是linux的设备驱动程序工作的基本原理。既然是这样,则编写设备驱动程序的主要工作就是编写子函数,并填充file_operations的各个域。
下面就开始写子程序。
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include<linux/config.h>
#include <linux/errno.h>
#include <asm/segment.h>
unsigned int test_major = 0;
static int read_test(struct inode *node,struct file *file,char *buf,int count)
{
int left;
if (verify_area(VERIFY_WRITE,buf,count) == -EFAULT )
return -EFAULT;
for(left = count ; left > 0 ; left--)
{
__put_user(1,buf,1);
buf++;
}
return count;
}
这个函数是为read调用准备的。当调用read时,read_test()被调用,它把用户的缓冲区全部写1。buf 是read调用的一个参数。它是用户进程空间的一个地址。但是在read_test被调用时,系统进入核心态。所以不能使用buf这个地址,必须用__put_user(),这是kernel提供的一个函数,用于向用户传送数据。另外还有很多类似功能的函数。请参考robert著的《Linux内核设计与实现》(第二版)。然而,在向用户空间拷贝数据之前,必须验证buf是否可用。这就用到函数verify_area。
static int write_tibet(struct inode *inode,struct file *file,const char *buf,int count)
{
return count;
}
static int open_tibet(struct inode *inode,struct file *file )
{
MOD_INC_USE_COUNT;
return 0;
}
static void release_tibet(struct inode *inode,struct file *file )
{
MOD_DEC_USE_COUNT;
}
这几个函数都是空操作。实际调用发生时什么也不做,他们仅仅为下面的结构提供函数指针。
struct file_operations test_fops = {
NULL,
read_test,
write_test,
NULL, /* test_readdir */
NULL,
NULL, /* test_ioctl */
NULL, /* test_mmap */
open_test,
release_test,
NULL, /* test_fsync */
NULL, /* test_fasync */
/* nothing more, fill with NULLs */
};
这样,设备驱动程序的主体可以说是写好了。现在要把驱动程序嵌入内核。驱动程序可以按照两种方式编译。一种是编译进kernel,另一种是编译成模块(moles),如果编译进内核的话,会增加内核的大小,还要改动内核的源文件,而且不能动态的卸载,不利于调试,所以推荐使用模块方式。
int init_mole(void)
{
int result;
result = register_chrdev(0, "test", &test_fops);
if (result < 0) {
printk(KERN_INFO "test: can't get major number\n");
return result;
}
if (test_major == 0) test_major = result; /* dynamic */
return 0;
}
在用insmod命令将编译好的模块调入内存时,init_mole 函数被调用。在这里,init_mole只做了一件事,就是向系统的字符设备表登记了一个字符设备。register_chrdev需要三个参数,参数一是希望获得的设备号,如果是零的话,系统将选择一个没有被占用的设备号返回。参数二是设备文件名,参数三用来登记驱动程序实际执行操作的函数的指针。
如果登记成功,返回设备的主设备号,不成功,返回一个负值。
void cleanup_mole(void)
{
unregister_chrdev(test_major,"test");
}
在用rmmod卸载模块时,cleanup_mole函数被调用,它释放字符设备test在系统字符设备表中占有的表项。
一个极其简单的字符设备可以说写好了,文件名就叫test.c吧。
下面编译 :
$ gcc -O2 -DMODULE -D__KERNEL__ -c test.c
得到文件test.o就是一个设备驱动程序。
如果设备驱动程序有多个文件,把每个文件按上面的命令行编译,然后
ld -r file1.o file2.o -o molename。
驱动程序已经编译好了,现在把它安装到系统中去。
$ insmod –f test.o
如果安装成功,在/proc/devices文件中就可以看到设备test,并可以看到它的主设备号。要卸载的话,运行 :
$ rmmod test
下一步要创建设备文件。
mknod /dev/test c major minor
c 是指字符设备,major是主设备号,就是在/proc/devices里看到的。
用shell命令
$ cat /proc/devices
就可以获得主设备号,可以把上面的命令行加入你的shell script中去。
minor是从设备号,设置成0就可以了。
我们现在可以通过设备文件来访问我们的驱动程序。写一个小小的测试程序。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
main()
{
int testdev;
int i;
char buf[10];
testdev = open("/dev/test",O_RDWR);
if ( testdev == -1 )
{
printf("Cann't open file \n");
exit(0);
}
read(testdev,buf,10);
for (i = 0; i < 10;i++)
printf("%d\n",buf[i]);
close(testdev);
}
编译运行,看看是不是打印出全1 ?
以上只是一个简单的演示。真正实用的驱动程序要复杂的多,要处理如中断,dma,I/O port等问题。这些才是真正的难点。请看下节,实际情况的处理。
如何编写Linux操作系统下的设备驱动程序
三、设备驱动程序中的一些具体问题
1。 I/O Port。
和硬件打交道离不开I/O Port,老的isa设备经常是占用实际的I/O端口,在linux下,操作系统没有对I/O口屏蔽,也就是说,任何驱动程序都可对任意的I/O口操作,这样就很容易引起混乱。每个驱动程序应该自己避免误用端口。
有两个重要的kernel函数可以保证驱动程序做到这一点。
1)check_region(int io_port, int off_set)
这个函数察看系统的I/O表,看是否有别的驱动程序占用某一段I/O口。
参数1:I/O端口的基地址,
参数2:I/O端口占用的范围。
返回值:0 没有占用, 非0,已经被占用。
2)request_region(int io_port, int off_set,char *devname)
如果这段I/O端口没有被占用,在我们的驱动程序中就可以使用它。在使用之前,必须向系统登记,以防止被其他程序占用。登记后,在/proc/ioports文件中可以看到你登记的I/O口。
参数1:io端口的基地址。
参数2:io端口占用的范围。
参数3:使用这段io地址的设备名。
在对I/O口登记后,就可以放心地用inb(), outb()之类的函来访问了。
在一些pci设备中,I/O端口被映射到一段内存中去,要访问这些端口就相当于访问一段内存。经常性的,我们要获得一块内存的物理地址。
2。内存操作
在设备驱动程序中动态开辟内存,不是用malloc,而是kmalloc,或者用get_free_pages直接申请页。释放内存用的是kfree,或free_pages。 请注意,kmalloc等函数返回的是物理地址!
注意,kmalloc最大只能开辟128k-16,16个字节是被页描述符结构占用了。
内存映射的I/O口,寄存器或者是硬件设备的ram(如显存)一般占用F0000000以上的地址空间。在驱动程序中不能直接访问,要通过kernel函数vremap获得重新映射以后的地址。
另外,很多硬件需要一块比较大的连续内存用作dma传送。这块程序需要一直驻留在内存,不能被交换到文件中去。但是kmalloc最多只能开辟128k的内存。
这可以通过牺牲一些系统内存的方法来解决。
3。中断处理
同处理I/O端口一样,要使用一个中断,必须先向系统登记。
int request_irq(unsigned int irq ,void(*handle)(int,void *,struct pt_regs *),
unsigned int long flags, const char *device);
irq: 是要申请的中断。
handle:中断处理函数指针。
flags:SA_INTERRUPT 请求一个快速中断,0 正常中断。
device:设备名。
如果登记成功,返回0,这时在/proc/interrupts文件中可以看你请求的中断。
4。一些常见的问题。
对硬件操作,有时时序很重要(关于时序的具体问题就要参考具体的设备芯片手册啦!比如网卡芯片RTL8139)。但是如果用C语言写一些低级的硬件操作的话,gcc往往会对你的程序进行优化,这样时序会发生错误。如果用汇编写呢,gcc同样会对汇编代码进行优化,除非用volatile关键字修饰。最保险的办法是禁止优化。这当然只能对一部分你自己编写的代码。如果对所有的代码都不优化,你会发现驱动程序根本无法装载。这是因为在编译驱动程序时要用到gcc的一些扩展特性,而这些扩展特性必须在加了优化选项之后才能体现出来。
写在后面:学习Linux确实不是一件容易的事情,因为要付出很多精力,也必须具备很好的C语言基础;但是,学习Linux也是一件非常有趣的事情,它里面包含了许多高手的智慧和“幽默”,这些都需要自己亲自动手才能体会到,O(∩_∩)O~哈哈!