カスタムLinuxドラむバヌの䜜成





私の友人や知人の倚くが私の神殿に指を向けおいるか、Linux甚のドラむバヌを曞いおいるこずがわかったずきに頭蓋骚が圧迫されおいるのではないかず考えおいたす。 「ドラむバヌ」ずいう蚀葉は、ほずんど神秘的な意味に包たれおおり、遞択した教祖だけがタオの著䜜を理解できたす。

幞いなこずに、これはそうではありたせん。 他のオペレヌティングシステム甚のドラむバヌを䜜成するこずで、どのようなこずが起こるかわかりたせん。 最も䞀般的なものですが、Linuxでは、ドラむバヌのハヌドりェアアヌキテクチャに関係なく、非垞に簡単に蚘述されおいたす。 ドラむバヌを䜜成するには、C蚀語の基本知識、Linuxオペレヌティングシステム基本の理解、取埗したいものの理解、ドキュメントず゜ヌスコヌドを読みたいずいう欲求、そしお忍耐が必芁です。 それだけです

デバむス甚のドラむバヌの䜜成方法を確認したすか その埌、猫の䞋に飛び蟌みたす



ドラむバヌの䜜成のしやすさは、Linux゜ヌスコヌドが芋事に文曞化されおおり、゜ヌスで利甚可胜であるずいう事実によっお説明されおいたす。ネット䞊には倚くの䟋があり、倚くの文献がありたす。 ドラむバヌを䜜成するには、お気に入りの配垃キットずカヌネル゜ヌス、および必芁なアヌキテクチャ甚のコンパむラヌのみが必芁です。 PowerPC 8360プロセッサ甚のトレヌニングではなく、最初のドラむバを䜜成したした。これはFPGAチップず察話し、デフォルト蚭定をリセットしたした。 奇劙なこずに、このアヌキテクチャ甚のSPIドラむバヌを少し曞き盎しおみたした。 これは、Linuxカヌネルでのプログラム䜜成の統䞀された暙準化により、そのようなこずができるずいう事実に基づいおいたす。

Linuxドラむバヌドラむバヌのハンドブックは「Linuxデバむスドラむバヌ」です。 この本は開発の包括的なガむドであり、本に䜕かが欠けおいる堎合は、カヌネル゜ヌスで間違いなく芋぀けるこずができたす。 もちろん、この投皿はこの玠晎らしい本に取っお代わるものではありたせん。 さらに、これらの䜜品の読みに基づいお曞かれたしたが、それでもこの本の簡単な改䜜ではありたせん。 これらの行の著者は、読者にLinuxのシンプルさず優雅さに興味を持たせ、ドラむバヌ開発に入る人々のしきい倀を䞋げるこずを目指しおいたす。 信じお-それは非垞に簡単です



ドラむバヌを䜜成する察象





この蚘事の䞻な目的はドラむバヌを䜜成するこずなので、ハヌドりェアには最小限の泚意を払いたす。 誰もがはんだごおの友達であり、友達ではない人たちであるこずを願っおいたす。友達を䜜り始める時です。䜕がどのように行われたかを簡単に説明したす。



LPTポヌトを介しおコンピュヌタヌに接続されたHD44780ファミリヌのディスプレむ甚のドラむバヌを䜜成したす。 私はポヌトが叀く、ディスプレむのタむプが私よりも小さいこずを知っおいたすが、それでもこれはハヌドりェアの詳现を説明するこずなく、Linux甚のドラむバヌを蚘述する矎しいシンプルな䟋です。 さらに、他のアヌキテクチャ向けにこの画面甚にこのドラむバを䜜り盎すこずは、1行を眮き換えるだけの問題です



そのため、LPTポヌトが必芁です。 叀いプリンタヌ甚のコヌドずオプションの36ピンCENTRONICSコネクタヌ。ただし、ケヌブルを簡単に開梱できたす。 もちろん、HD44780ファミリヌの画面では、少なくずも4x40文字が最適ですが、最小の文字でも十分です。 さお、コントラストを調敎するための10 kOhmの可倉抵抗噚。 ずっず前にLPTポヌトを持っおいなかったので、最初に出䌚ったPCIカヌドを賌入したしたPCI-Eも䜿甚できたす。 さらに、このボヌドは非垞に倚くの䞭囜語に出くわしたので、その䞊にはんだ付けされたチップに関するドキュメントを芋぀けるこずすらできたせんでした。 䜕も、私たちもそれを逆にしたす:)。





ハヌドりェア゜ヌス



これらのコンポヌネントを入手するこずは難しくなく、あなたの手はすべおを行うために焊りで燃えおいたす。



è­Šå‘Š!!!

泚意深く読んでください









私たちは鉄で最も困難な状況で働いおいるこずを瀺したいず思いたす。そしお、私たちはコアレベルでも働きたす。 私たちはいわば、患者の内偎に䜏んでいたす。 プログラムおよびカヌネルの゚ラヌがクラッシュしたす。 kernel_panicを振る時間さえないかもしれないずころで、突然すべおが機胜しなくなりたす。 ドラむバを起動しおアンロヌドし、突然暗黙のグリッチが開始したこずに泚意しおください-それだけで、あなたのやり方は再起動しおいたす。 システムが皌働しおいる堎合は、再起動コマンド。 ただない堎合は、ハヌドりェアをリセットしたす。 深刻な堎合でも、システムが自動的に再起動する堎合がありたす。



さらに、䜕をしおいるのかわからない堎合ポヌトぞの曞き蟌み、メモリ領域ぞのアクセスなど、これを行わない方が良いでしょう。 これらすべおのために、せいぜい、蚭定x70でBIOSをリセットするために䜿甚されたポヌト70hに曞き蟌たれた誀った倀を壊したり、機噚を台無しにしたりするこずもありたすたずえば、GPIOフットを地面に眮くこずによっお。 したがっお、ハヌドりェアず゜フトりェアの䞡方のレベルで、あなたがしおいるこずを明確に理解しおください



降りる





私のコンピュヌタヌに組み蟌たれおいるlpt-portの幞運な所有者にずっお、あなたの堎合、ポヌトは暙準アドレス378hにあるず蚀えたす。 私は真倜䞭に目が芚めるこずができ、私はこの数字を蚀うでしょう、ずおも倚くはそれに関連しおいたす。 しかし、今では敵の報酬が䞎えられおおり、それを打ち負かす必芁がありたす

ボヌドをPCIたたはPCI-Eスロットに挿入し、起動しお、次のコマンドでPCIバスで䜕が起こるかを監芖したす。



lspci -v 
 05:01.0 Serial controller: Device 4348:5053 (rev 10) (prog-if 02 [16550]) Subsystem: Device 4348:5053 Flags: medium devsel, IRQ 18 I/O ports at c030 [size=8] I/O ports at c020 [size=8] Kernel driver in use: serial
      
      







ご芧のように、LinuxはPCIバス䞊で䜕かを芋぀け、明らかに䜕らかの誀ったドラむバヌを残そうずしたした。 ただし、このポヌトが眮かれおいるアドレスに最も関心がありたす。 I / Oポヌト、぀たり番号c030hおよびc020hです。

次に、どのアドレスが原因であるかを芋぀ける必芁がありたす。 これを行うには、ほが同じ方法でLEDを抵抗付きの出力ポヌトに接続したす玄310オヌムの抵抗、たたはそれ以䞊でもそれでも構いたせん





怜蚌スキヌム



この皮のテスト甚のLEDのブランクは既にあるため、CENTRONICSコネクタヌにワむダヌを盎接挿入し、8本すべおのワむダヌに適合しなかったため、6本最初の4぀ず最埌の2぀のみを挿入したした。





組み立おられたポヌトテスタヌ



そしお、怜蚌のための小さなプログラムをスケッチしたす。



ポヌトを操䜜するために、ここwww.faqs.org/docs/Linux-mini/IO-Port-Programming.html#s9から䟋を取り䞊げたした。 修正する必芁があるのは次の行のみです。



 #include <asm/io.h>
      
      







に



 #include <sys/io.h>
      
      







1秒あたりの通垞の遅延を䜜成したすusleep100000の代わりに;

、sleep1;を曞き蟌み、ポヌトに3぀の出力を順番に䜜成したす。



 outb(0, BASEPORT); sleep(1); outb(0xAA, BASEPORT); sleep(1); outb(0xFF, BASEPORT); sleep(1);
      
      







#define BASEPORTの倉曎をポヌト0xc030に定矩したす。 コンパむルし、ルヌトの䞋から実行したす。LEDは点灯したせん。 別の数字に倉曎-0xc020-゚ヌルop





れロ





ピンAAh





そしお、もちろん、2番目のFFhで



結果は明らかです。 ぀たり 掚枬したポヌト番号で、,を始めるこずができたす。 このボヌドのLPTポヌトはそのアドレスにありたす。 0Xc020 



ティンスミスプログラマヌの泚意をマゞックナンバヌ0xAAに匕き付けたいず思いたす-これは1ず0のシヌケンスです。 このように 10101010b 。 デバッグには非垞に䟿利です。 䞀般に、ハヌドりェアを扱う人はだれでも簡単に2進数、10進数、16進数を前埌に倉換する必芁がありたす。



滝ディスプレむ





ドラムロヌル、それは鉄片をたずめる時間です これを行うには、すべおを䞀緒にはんだ付けする必芁がありたす。 次のスキヌムに埓っおすべおを収集したす。





私はスキヌムがGOSTに準拠しおいないこずを知っおいたすが、これはラゞオ雑誌でもありたせん



スクリヌンに電力を䟛絊するために、USBワむダヌを倖し、スクリヌンに2本のワむダヌを接続したした。 トリッキヌなオプションがありたす。手がたったく届かないずいうこずです。LPTワむダで盎接USB電源をオンにしお、倚くのアヌスワむダの1぀をはんだ付けするこずです。 手が届くず、私は間違いなくそれを行いたす。 この蚘事のみを远加したす:)。

その結果、電源を入れた埌、次のようになりたす。 2぀のストリップが衚瀺されるように、抵抗噚で茝床を調敎したす。 ディスプレむが初期化されおいないこずを瀺しおいたす。





デバむスの組み立お



ふhardware、ハヌドりェアは完成したした。プログラムに移りたしょう。



プログラムの画面で悪の実隓に到達する





ここから取り出したArduinoコヌドを、ディスプレむを操䜜するための既補ずしお䜿甚したした。 私もこのプラットフォヌムが奜きではありたせんが、コヌドはI2Cを介しお接続されたディスプレむに適しおいたす。 最埌の蚀葉で䜕も蚀われなくおも、心配しないでください。 䞀番䞋の行は、同じディスプレむがバスの名前ずしお2本のワむダを介しお接続され、LPTポヌトのように、送信されたバむトをパラレルバスに再び倉換するレゞスタがありたす。 その結果、I2Cでの䜜業の䞀郚を捚おお、良いラむブラリを取埗したす。

枅朔にするために、私はそれを互いに曞き盎し、必芁な機胜をいく぀か远加し、競合する機胜のいく぀かを名前を倉曎し、他のいく぀かの倉曎を加えたした芚えおいたせんが、倧量の氎が挏れたした。

ちなみに、コヌドはSTM32で䜿甚され、ディスプレむもI2Cで接続されおいたした。 そしお今、私たちはすでにそれをx86ずLinuxの䞋に移怍しおいたす。 ここにありたす-コヌドの移怍性の倧きな力 新しいプラットフォヌムにすでにコヌドを適応させるのにたった10分しか費やしおいたせん。

ポヌトの操䜜は1぀の機胜で実行されたす。これは非ポヌタブルノヌドであり、プラットフォヌムによっおは出力方法を倉曎する必芁がありたす。 I2Cに関する結論がありたした。



  void expanderWrite(unsigned char _data){ outb(((_data) | _backlightval), BASEPORT); //x86 instruction!!!!! }
      
      







この機胜に泚意しおください。 眮き換えお、コヌドをAVR、STM32、MIPSなどで実行できたす。

すでにおなじみのポヌトぞの結論。 ポヌトは、ヘッダヌlcd.hで定矩されおいたす。 すべお、今、私たちは結論を出すこずができたす。 プログラムはさらに簡単になり、より芖芚的になりたした。

print_to_stringラッパヌ関数は衚瀺に䜿甚されたす。



 void print_to_string (unsigned char col, unsigned char row, unsigned char c[], unsigned char len);
      
      







最初のパラメヌタヌは列番号0から19、2番目の行番号0から3、3番目は文字ストリングぞのポむンタヌ、最埌はストリングの長さです。 行の末尟の「\ 0」はチェックされたせん。長さは個別に制埡する必芁がありたす その結果、衚瀺を詊しおください



 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/io.h> #include "lcd.h" #define LCD_STRINGS 4 // #define LCD_COLUMNS 20 // int main() { LCD_init(0, LCD_COLUMNS, LCD_STRINGS);//  print_to_string (0, 0, "XXXXXXXXXXXXXXXXXXXX" , 20); print_to_string (0, 1, "YYYYYYYYYYYYYYYYYYYY" , 20); print_to_string (0, 2, "ZZZZZZZZZZZZZZZZZZZZ" , 20); print_to_string (0, 3, "MMMMMMMMMMMMMMMMMMMM" , 20); exit(0); }
      
      







その結果、次のようなものが画面に衚瀺されるはずです。





初めおのデビュヌ



このポルノに驚かないでください。 この画面は壊れたピクセルのために曞き萜ずされたした。あるいは、コントロヌラヌはそこの静的なものから単に死にたしたそれらのいく぀かがありたす。 それは仕事には適しおいたせんが、そのようなすべおの実隓には適しおいたす。 そのようなくだらないスクリヌンは䞭囜人をやる



これは停止される可胜性がありたす、なぜなら この䟋では、任意の文字を衚瀺したり、フォントをダりンロヌドしたりできたす。 しかし、ドラむバヌずしおではありたせん。 想像力が蚱す限り、悪魔などでリメむクできたすが。

したがっお、さらに読みたいず退屈した人のために、この䟋の完党版をここに投皿したす 。

私たちのグロヌバルな目暙はデバむスドラむバヌなので、始めたしょう。



ドラむバヌ構築ツヌル





ドラむバヌの䜜成を開始するには、必芁なツヌルをむンストヌルする必芁がありたす。 UbuntuおよびDebian甚のツヌルを準備する方法は、このブログで詳しく説明されおいたす。markloiseau.com/ 2012/04 / hello-world-loadable-kernel-module-tutorialの蚘事

debianパッケヌゞを収集する必芁がなく、自分だけのためにモゞュヌルを䜜成する堎合、次のコマンドで必芁なコンポヌネントをむンストヌルするだけで十分であるず簡単に蚀いたす。



 sudo apt-get install build-essential linux-headers-$(uname -r)
      
      







カヌネルの゜ヌスもダりンロヌドするこずを匷くお勧めしたす。 これを行うには2぀のオプションがありたす。 最初の明らかな、しかしおそらくわずかなslightlyは、次のコマンドでカヌネルのバヌゞョンを芋぀けるこずです



 uname - a
      
      







www.kernel.orgからダりンロヌドしたす。 私はリンクをたどっおカヌネルのバヌゞョンを探すのが面倒な人です。このビゞネスの自動化を信じおいたす。



 #    sudo -s cd /usr/src/ apt-get source linux-image-$(uname -r) #      . #      linux_3.8.0-9.18.tar.gz      /usr/src/linux-3.8.0
      
      







たた、このパスを芚えおいるか、たずえば/ usr / src / linuxなどのリンクを远加したすが、これはお勧めしたせん。 カヌネルはアップグレヌドする傟向がありたす。 あるべきかそうでないべきか、自分で決めおください。

これで本圓の宝物が手に入りたした。最新のドキュメントの保管庫、膚倧な量の゜ヌスコヌドの䟋、そしおもちろん、モゞュヌルを構築するために必芁な橋頭headです。

ドキュメント、ドラむバヌなどをパパに登り、゜ヌスコヌドを閲芧するこずを匷くお勧めしたす-これは非垞に䟿利です



自分のドラむバヌ





メむクファむルを修正し、既補のドラむバヌを入手するだけだず思う​​堎合、あなたは深く誀解しおいたす。 これで、私たちは別の䞖界にいたす。ナヌザヌ空間ではなく、カヌネル空間にいたす。 そしお、ここではたったく異なるルヌルが適甚されたす。

状況のすべおの貧困を実珟するには、カヌネルが1぀の倧きな、倧きなプログラムであるこずを理解する必芁がありたす。 そしおこれは、グロヌバル倉数、関数などを意味したす カヌネルの他の堎所で利甚できるかもしれたせん したがっお、すべおのグロヌバル倉数それらは最倧限に回避する必芁がありたすは静的ずしお宣蚀する必芁がありたす

ドラむバヌをカヌネルに組み蟌むこずでカヌネルを再構築するこずはせず、再起動するたびにカヌネルを再詊行したす。 確かに面癜いですが、非垞に長いです。 代わりに、実行時にすぐにロヌドおよびアンロヌドするカヌネルモゞュヌルを䜜成したす。

将来のモゞュヌルでは、ナヌザヌ空間のプログラムず比范しお、倉曎はそれほど重芁ではありたせん。 たず、すべおのファむルを1぀に転送したす。これにより、コンパむルに問題が発生しないようにしたすたたは、ファむルを盞互に組み蟌みたす。 ヘッダヌは残したすが、関数のすべおのパラメヌタヌを明確に定矩したすパラメヌタヌがない堎合は、voidを登録する必芁がありたす。 私たちはコアスペヌスにいるこずを思い出し、私たちが持っおいるすべおのラむブラリは異なっおいたす。 すべおのヘッダヌをnuclearに倉曎したす。



 #include <linux/module.h> #include <linux/init.h> #include <linux/fs.h> /* everything... */ #include <asm/io.h> #include <linux/unistd.h> #include <linux/delay.h> /* udelay */ #include <asm/uaccess.h> #include <linux/miscdevice.h>
      
      







unistd.hずio.hでさえ栞になっおいるこずに泚意しおください。



ドラむバヌの䞻な基盀ずしお、 hello worldモゞュヌルを䜿甚したす。 init関数を修正したしょう



 static int __init hello_init(void) { LCD_init(0, LCD_COLUMNS, LCD_STRINGS); print_to_string (0, 1, "Hello Habrahabr " , 20); printk(KERN_INFO "Lpt module init\n"); return 0; // Non-zero return means that the module couldn't be loaded. }
      
      







ここではすべおが実質的に倉曎されおいたせん。 鉄を扱う機胜は倉化しおいたす最もプラットフォヌムに䟝存。 栞出力ポヌト機胜で既に動䜜したす



 void expanderWrite(unsigned char _data){ //outb(((_data) | _backlightval), BASEPORT); //x86 instruction rootfs!!!!! outb_p(((_data) | _backlightval),BASEPORT); //x86 instruction kernel!!!!! }
      
      







そしお、奇劙なこずに、遅延機胜。 䞀般的に、遅延は別の歌であり、蚘事党䜓に圓おるこずができたす。 私たちはすべおを玠早く手に入れ、あらゆる皮類のナンセンスに察しお可胜な限りコアを占有するべきです。 しかし、ただ



 static inline int delayMicroseconds(int value) { //usleep(value); //rootfs if (value > 1000) msleep(value/1000); udelay(value%1000); return 0; //kernel }
      
      







この詐欺の説明は簡単です。カヌネル内のudelayは、1000を超える倀を取るこずはできたせん。 むンシデントを回避するには、そのようなスタブが必芁です。

その埌、次のようなメむクファむルでほが収集したす。



 TARGET = lptlcd obj-m := $(TARGET).o KERNELDIR ?= /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) CC = gcc all: $(MAKE) -C $(KERNELDIR) M=$(PWD) clean: rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
      
      







そしお、次のコマンドでモゞュヌルをシステムにロヌドしたす。



 sudo insmod lptlcd.ko
      
      







すべおを正しく行った堎合、゚ラヌは発生せず、画面は正しく初期化され、dmesgはモゞュヌルのメッセヌゞを最終行ずしお衚瀺したす。



[10036.950566] Lpt module init







次のコマンドでモゞュヌルをアンロヌドできたす



 sudo rmmod lptlcd
      
      







dmesgはこう蚀いたす



[10077.176714] Cleaning up module







䞀般的に、垞にdmesgを抌さないために、スクリプトがありたす。Jtu 同志が私に提案した解決策がありたす 。



 while true; do sudo dmesg -c; sleep 1; done
      
      







たたは、Ubuntu以倖のディストリビュヌションを䜿甚しおいる堎合は、rootずしお実行し、sudoを削陀する必芁がありたす。



画面䞊の結果





こんにちは



これらすべおを芋たなら-おめでずうございたす、これは画面に碑文を衚瀺する最初の動䜜する圹に立たないカヌネルモゞュヌルです これは確かにおもしろいですが、ただ実隓を通垞のドラむバヌに倉えお䜜業する必芁がありたす。 このためには、少なくずも少しは材料に぀いお話さなければなりたせん。



材料に぀いおのいく぀かの蚀葉





奜むず奜たざるずにかかわらず、いく぀かのハヌドりェアを知らなくおも遠くたで行くこずはできたせん。シンボリック、ブロック、ネットワヌクデバむスがありたす。 各デバむスには、メゞャヌおよびマむナヌデバむス番号もありたす。 「 The Linux Kernel Module Programming Guide 」ずいう本よりも良いこずを蚀うこずは䞍可胜です。このため、ネタバレの本から匕甚したす。

メゞャヌおよびマむナヌデバむス番号
メゞャヌおよびマむナヌデバむス番号

いく぀かのデバむスファむルを芋おみたしょう。 以䞋は、プラむマリハヌドドラむブの最初の3぀のパヌティションを衚すものです。

 # ls -l /dev/hda[1-3] brw-rw---- 1 root disk 3, 1 Jul 5 2000 /dev/hda1 brw-rw---- 1 root disk 3, 2 Jul 5 2000 /dev/hda2 brw-rw---- 1 root disk 3, 3 Jul 5 2000 /dev/hda3
      
      









コンマ区切りの列に泚目しおください。 最初の番号は、デバむスの「高い番号」ず呌ばれたす。 2番目-「ゞュニア番号」。 メゞャヌ番号は、ハヌドりェアの保守に䜿甚されるドラむバヌを瀺したす。 各ドラむバヌには、固有のメゞャヌ番号がありたす。 同じメゞャヌ番号を持぀すべおのデバむスファむルは、同じドラむバヌによっお管理されたす。 䞊蚘のデバむスファむルはすべお、同じドラむバヌによっお制埡されるため、3に等しいメゞャヌ番号を持っおいたす。

マむナヌ番号は、ドラむバヌが制埡するハヌドりェアを区別するために䜿甚されたす。 䞊蚘の䟋に戻るず、3぀のデバむスすべおが同じドラむバヌによっお凊理されたすが、それぞれに固有のマむナヌ番号があるため、ドラむバヌはそれらを異なるハヌドりェアデバむスずしお「認識」したす。

デバむスは、ブロックずシンボリックずいう2぀の倧きなグルヌプに分けられたす。 ブロックデバむスずキャラクタヌデバむスの䞻な違いは、ブロックデバむスずデヌタがバむト郚分で亀換されるこずです-ブロック。 内郚バッファがあり、為替レヌトが増加したす。 ほずんどのUnixシステムでは、1ブロックのサむズは1キロバむトたたは2の环乗である別の数倀です。シンボリックデバむスは、デヌタがバむト単䜍で順番に続く情報転送の単なるチャネルです。 ほずんどのデバむスは、ブロックサむズによっお制限されず、バッファリングする必芁がないため、文字クラスに属したす。 リストの最初の文字がls-l / devによっお受信された堎合、 'b'の堎合、これはブロックデバむスであり、 'c'の堎合、それは文字です。 䞊蚘の䟋で瀺されたデバむスはブロックデバむスです。 以䞋は、いく぀かのキャラクタデバむスシリアルポヌトのリストです。

 crw-rw---- 1 root dial 4, 64 Feb 18 23:34 /dev/ttyS0 crw-r----- 1 root dial 4, 65 Nov 17 10:26 /dev/ttyS1 crw-rw---- 1 root dial 4, 66 Jul 5 2000 /dev/ttyS2 crw-rw---- 1 root dial 4, 67 Jul 5 2000 /dev/ttyS3
      
      









メゞャヌデバむス番号がどのように割り圓おられるかを知りたい堎合は、/ usr / src / linux / documentation / devices.txtファむルを調べおください。

すべおのデバむスファむルは、mknodナヌティリティを䜿甚しおシステムのむンストヌル䞭に䜜成されたす。 たずえば、「coffee」ずいう名前でメゞャヌ番号12、マむナヌ番号2の新しいデバむスを䜜成するには、コマンドmknod / dev / coffee c 12 2.を実行する必芁がありたす。/devディレクトリにデバむスファむルを配眮する矩務はありたせんこれは、受け入れられおいる契玄に準拠しおいたす。 ただし、デバッグのためにデバむスドラむバヌを開発する堎合、デバむスファむルをホヌムディレクトリに配眮するこずは、おそらくそれほど悪い考えではありたせん。 唯䞀のこず-デバッグの完了埌にデバむスファむルを配眮する堎所を修正するこずを忘れないでください。

議論䞭のトピックには明らかに関係ないが、私がしたいコメントがいく぀かありたす。 デバむスファむルにアクセスするず、カヌネルは最倧のファむル番号を䜿甚しお、この呌び出しを凊理するドラむバヌを決定したす。 これは、カヌネルが実際にマむナヌ番号を䜿甚せず、さらには䜕も知らないこずを意味したす。 これに぀いお心配しおいるのは、ドラむバヌ自䜓だけです。 マむナヌ番号を䜿甚しお、異なる物理デバむスを区別したす。

ちなみに、「デバむス」ず蚀うずきは、手で持぀こずができるPCIボヌドよりも抜象的なものを意味したす。 次の2぀のデバむスファむルを芋おください。

 % ls -l /dev/fd0 /dev/fd0u1680 brwxrwxrwx 1 root floppy 2, 0 Jul 5 2000 /dev/fd0 brw-rw---- 1 root floppy 2, 44 Jul 5 2000 /dev/fd0u1680
      
      









珟時点では、これらのデバむスファむルに぀いおは、どちらも同じドラむバヌメゞャヌ番号2によっお提䟛されるブロックデバむスであるず蚀えたす。 ドラむブが1぀しかない堎合でも、䞡方ずもフロッピヌドラむブを衚しおいるず䞻匵するこずさえできたす。 しかし、なぜ2぀のファむルなのでしょうか しかし、問題はこれです。そのうちの1぀は1.44 Mbフロッピヌディスクドラむブです。 もう1぀は同じドラむブですが、1.68 MBフロッピヌディスク甚であり、䞀郚の人々が「スヌパヌフォヌマット」ディスクず呌ぶものに察応しおいたす。 このようなフロッピヌディスクは、暙準のフォヌマット枈みフロッピヌディスクよりも倚くのデヌタを栌玍できたす。 マむナヌ番号が異なる2぀のデバむスファむルが、実際には同じ物理デバむスを衚す堎合です。 ですから、私たちの議論では、「デバむス」ずいう蚀葉は、より抜象的なものを意味する堎合がありたす。





デバむスファむルを䜜成する





キャラクタヌデバむスドラむバヌファむルを䜿甚したす。 本「Linux Device Driver」の改䜜に関䞎しないように、たた私の人生を単玔化するために、 この蚘事からキャラクタヌドラむバヌを登録する既補の䟋を取り䞊げたした。 この蚘事では、無料の修正マむナヌを怜玢したせんが、動的マむナヌを䜿甚したす。 私たちにずっお、これはたさにそれです。



したがっお、モゞュヌルは次のようになりたす。䞊で実装した画面の凊理は倉曎されたせんが、残りの郚分は最初から曞き盎したす。

file_operations構造を定矩したす



 static const struct file_operations lptlcd_fops = { .owner = THIS_MODULE, .read = dev_read, .write = dev_write, };
      
      







dev_readずdev_writeは、それぞれデバむスファむルからの読み取りず曞き蟌みを凊理する関数コヌルバックの登録ぞのポむンタヌです。 ここでもただできたすが、おそらく.openおよび.releaseポむンタヌを远加しお、デバむスファむルの1回限りの開閉を確認する必芁がありたすが、今のずころ私は怠け者です。



ドラむバヌを登録するには、この構造を開始したす



 static struct miscdevice lptlcd_dev = { MISC_DYNAMIC_MINOR, "lptlcd", &lptlcd_fops };
      
      







ここで、 MISC_DYNAMIC_MINORはダむナミックマむナヌのマクロで、行「lptlcd」はデバむスの名前、/ dev /フォルダヌでの衚瀺方法この堎合は/ dev / lptlcd、lptlcd_fopsはfile_operations構造䜓ぞのポむンタヌです。



ドラむバヌ登録コヌドも非垞に簡単です



 static int __init dev_init( void ) { int ret; //   ret = misc_register( &lptlcd_dev ); //    if( ret ) printk( KERN_ERR "=== Unable to register misc device\n" ); //  LCD_init(0, LCD_COLUMNS, LCD_STRINGS); print_to_string (0, 0, "lptlcd init " , 16); return ret; }
      
      







デバむスの登録解陀は簡単です。



 static void __exit dev_exit( void ) { misc_deregister( &lptlcd_dev ); }
      
      





さお、マクロむンストヌルのコヌルバック、ラむセンス、䜜成者、バヌゞョンを忘れないでください



 module_init( dev_init ); module_exit( dev_exit ); MODULE_LICENSE("GPL"); MODULE_AUTHOR( "Dolin Sergey <dlinyj@gmail.com>" ); MODULE_VERSION( "0.1" );
      
      







魔法はdev_readずdev_write関数から始たりたす。 最初から始めたす



 static char *info_str = "lcdlpt device driver\nAuthor Dolin Sergey aka dlinyj dliny@gmail.com\n"; // buffer! static ssize_t dev_read( struct file * file, char * buf, size_t count, loff_t *ppos ) { int len = strlen( info_str ); if( count < len ) return -EINVAL; if( *ppos != 0 ) { return 0; } if( copy_to_user( buf, info_str, len ) ) return -EINVAL; *ppos = len; return len; }
      
      







圌女は次のこずを行いたす。たずえば、次のようにデバむスファむルを読み取るず、



 cat /dev/lptlcd
      
      







次に、info_strポむンタヌの埌の行が衚瀺されたす。

コヌドは非垞に明癜なので、コメントは䞍芁です。 唯䞀のこずは、copy_to_user関数ずcopy_from_user関数が、ナヌザヌずカヌネルのアドレススペヌス間のデヌタコピヌを䜿甚するこずです。



もう1぀のdev_write関数は、デヌタを画面にプッシュしたす。

 static int str_pos = 0; //  static int col_pos = 0; //  static ssize_t dev_write( struct file *file, const char *buf, size_t count, loff_t *ppos ) { int i; //  . for (i=0; i<count;i++) { //     setCursor(col_pos, str_pos); //       ,    if ((col_pos==0) && (str_pos==0)) clear(); //   ,     if (buf[i] != '\n') { write_l(buf[i]); col_pos++; } //  ,      else {col_pos=LCD_COLUMNS;} //        if (col_pos == LCD_COLUMNS) { col_pos=0; str_pos++; //   ,      if (str_pos == LCD_STRINGS) { str_pos=0; } } } return count; }
      
      







私の意芋では、远加たたは削陀しないでください。ここですべおが明確であるこずを願っおいたす。

コンパむルし、カヌネルにモゞュヌルを远加しお、ファむルがあるこずを確認したす。



 $ ls /dev/lptlcd /dev/ttylptlcd
      
      







私たちはそれから読み、䜕かを曞き蟌もうずしたす



 $ cat /dev/lptlcd lcdlpt device driver Author Dolin Sergey aka dlinyj dliny@gmail.com echo -ne "Trolo Pysh\nPysh" > /dev/lptlcd
      
      







これは次のように衚瀺されたす。





私はUFOドラむバヌです。



これで、完党に機胜するドラむバヌず埀埩デバむスが完成したした。おめでずうございたす、シャンパンのために倉庫に走っお、そしおナヌザヌ空間で、魔法の泡を䜿っおこのデバむスを䜿っお魔法のプログラムを曞いおください。

しかし、それにもかかわらず、いく぀かの疑いが個人的に私をかじっおいたす、ここに䜕か間違っおいたす...



もっず欲しい!!!





そこで、完党に機胜するドラむバヌを䜜成したした。これは既に日垞の緎習で䜿甚できたす。その䞊に任意のテキストを衚瀺し、ファむルのテキストも衚瀺しお、プログラムで䜿甚する。しかし、䞍完党さ、䞍完党さの感芚がありたす。

たずえば、AVRのディスプレむの初期化に関するDIHALTの蚘事など、画面䞊のドキュメントを受け取っお読むず、その豊富な機䌚に驚くでしょう。䟋

1.テキストをメモリにロヌドしおから、衚瀺領域を移動するだけで、新しいデヌタをロヌドするためのクロックサむクルを節玄できたす芚えおいるように、かなりの遅延がありたす。

2.任意の䜍眮にテキストを衚瀺できたす。

3.画面をクリアできたす。

4.もちろん、独自のフォントをアップロヌドできたす。これに぀いおはお䞖蟞にしないでください。8文字しか䜿甚できたせん。たずえば、ラテン文字ず郚分的にロヌドされたロシア語8文字を含む、ロシア語フォントなしのこの画面でロシア語メニュヌを実装するタスクは、郚門党䜓にずっお非垞に楜しいリバスになりたす泳いだ。そのため、これはいく぀かの特定のキャラクタヌに䜿甚されたす。



職堎のコヌヒヌマシンでフォントダりンロヌド機胜を䜿甚する良い䟋が芋぀かりたした。この䟋では、ちょうどRussifiedの同様の画面がむンストヌルされおいたす。





コヌヒヌマシンの画面



ここでは、シンボルの䜿甚を明確に芋るこずができたす

。-砂糖の2぀のシンボル、空の円離陞するずは思わなかった、および完党。

-実行䞭の行の5文字5列の文字。



合蚈2 + 5-予備のキャラクタヌが1぀だけ残っおいたすが、これもおそらく䜿甚されたす。本圓に逃げないでください。



䞀般に、ディスプレむには倚くのチップが搭茉されおいるので、ドキュメントの䞭で読むのが面倒です。しかし、私たちが芋るように、私たちはただこれをすべお行うこずはできたせん。そしおこの玠晎らしい瞬間に、長い間そこにあった茂みからピアノを手に入れる時が来たした。

このアむデアの実装を開始する前郚品を賌入する前に、グヌグルで怜玢し、他の誰かがそれをしたした。そしお、芋よそのようなドラむバヌは既に存圚したす。圌は曞いたマむケルマクレランずドラむバヌはここに䜏んでいたす。

正盎なずころ、このドラむバヌは私に耇雑な印象を䞎えたした。ドラむバヌを曞かない方法に぀いおの貎重なガむドになったずだけ蚀っおみたしょう-バむトのバカな蚘録があり、それがどこで、どこで、なぜかは明らかではないので、異なるスむッチングスキヌムで曞き盎すこずは簡単な䜜業ではありたせん。クラスずしおの移怍性はありたせん。そしお、さたざたなコア甚の䞀連の定矩によっおMoskが䜜成されたす。さらに、圓初、ドラむバヌは完党な配線図ずしお考えられおいたしたデヌタポヌトごずに8ビット、lcd-mod.sourceforge.net / wiring.phpを参照、そしお私はすぐに4ビットバスを目指したした。䜎速ですがバむトが2぀のパッケヌゞで送信されるため玄2倍、最初にはんだ付けが少なくなり、次に他のポヌトを探す必芁がなくなりたす。 3番目に、4ビットバス甚の優れた論理コヌドが既にありたした。その結果、私は自分でドラむバヌをれロから䜜成し、同時にその方法を指瀺するこずにしたした。



さお、歌詞で地獄に。そのドラむバヌには貎重なものがありたす-それは制埡シヌケンスたたはESCシヌケンスを凊理しおいたす。頑匵っおこの「ピアノ」を揺るがすず、あらゆる皮類のReadmeずその方法を芋぀けるこずができたす。オフサむトにも事実がありたす。このすべおのデヌタを登る必芁がないように、すべおを1぀のヒヌプずロシア語に配眮するこずにしたした。最初に、これらのシヌケンスに関するいく぀かの単語、printf挔算子が '\ n'の圢匏でラむンフィヌドを远加したずきにそれらすべおに出くわしたした-これはASCIIの0Ah文字ずしお解釈される最も単玔なESCシヌケンスです。同じパセリは、このディスプレむの管理にありたす。



したがっお、画面の制埡シヌケンス







他の䟿利なコマンドは、\ 033プレフィックスなしで機胜したす







このアむデアは私にはずおもクヌルに思えたので、私はこの機胜を私たちのプロゞェクトで倧胆に借りるこずにしたした。



ずころで、これらのすべおのシヌケンスは通垞のコン゜ヌルで玠晎らしく機胜し、テキストを衚瀺するずきに䜿甚できたす。



誰がただこれが䜕であり、なぜ理解しおいないのか、それに぀いおはlcd-mod.sourceforge.net/faq.phpで詳しく説明しおいたす。苊しむこずのないように、私はそれを自由に翻蚳し、写真付きのスポむラヌに慎重に入れたした



よくある質問
Q. , , ?

A. , vt52- ru.wikipedia.org/wiki/VT52 , . , ASCII . , — '\r' '\n' (. ). , :



 echo -en "Line One\r\nLine Two" > /dev/lptlcd
      
      













“Line One” “Line Two” . , “echo” :

-n — '\n'

-e —



Q. , ?

A. . 䟋

 echo -en "line1\r\nline2" > /dev/lptlcd
      
      





(. )

Q. , , n n- , n-1 , ?

A. , “echo”. , '\n' . -n, .



Q. ?

A. : ESC-Y[Y-+037][X-+037]. 䟋

 echo -en "\033[Y\037\037Hello" > /dev/lptlcd
      
      









Hello 0:0



, “Hello”;

 echo -en "\033[Y\040\040Hello" > /dev/lptlcd
      
      





, 1, 1;





Hello 1:1 ( )



 echo -en "\033[Y\041\041Hello" > /dev/lptlcd
      
      





, 2, 2





Hello 2:2 ( , )



“037” , , , vt52 ( :) )..



Q. ?

A. HD4480 , . GUI , ( ). , . , .

, : Esc-R[ ][8 , ]. , 5 . . 䟋

 echo -en "\033[R1\037\037\037\037\037\037\037\037" > /dev/lptlcd
      
      





1, . , .









 echo -en "\033[R2\037\000\037\000\037\000\037\000" > /dev/lptlcd
      
      





0 .









«» , :

 echo -en "\000\001\002\003\004\005\006\007" > /dev/lptlcd
      
      









, .





䞀般に、ご芧のずおり、dev_write関数を曞き換える必芁がありたす。そしお今、圌女はこのように芋え始めたした



 static ssize_t dev_write( struct file *file, const char *buf, size_t count, loff_t *ppos ) { int i; for (i=0; i<count;i++) handleInput(buf[i]); return count; }
      
      







そしお、すべおのダヌティデブリヌフィング䜜業は、handleInput関数によっお凊理されたした。この関数のコヌドは巚倧なので、ここでは説明したせん。圌に察凊しおバックドアを芋぀けるために圌の宿題を残しおおきたす。コヌドでむヌスタヌ゚ッグを芋぀けた人、コメントでメモした人、甘い人。

バックドアビデオをシヌドするにはドラむバヌに実装されたす





ASCII-ART Moveむヌスタヌ゚ッグによっお開始され



たす。同様のビデオを画面に衚瀺しおくれた人には、私からプレれントがもらえたす



䞀般に、結果ずしお、さたざたな有甚な情報や圹に立たない情報を衚瀺するために䜿甚できるコヌシャ画面を取埗したした。ここでは、たずえば、珟圚の時刻を衚瀺できたす。



 while true; do echo -en "\033[H`date +\"%d.%m.%Y\"` \r\n`date +%r`" > /dev/lptlcd ; sleep 1s; done
      
      









そしお、圌らはただ行きたす



もちろん、圌は曞いた-それを人々ず共有する゜ヌスコヌドはこちらから入手できたすコヌド亀換にgithubを䜿甚する぀もりはありたせんが、残念です。



やりたいこず





テヌブルの小さな画面が必芁な理由がほずんど理解されおいないずいうだけで、それは本圓です。特にタブレットやその他の機噚の時代。すべおがスマヌトフォンにリダむレクトできる堎合。もう1぀は、新幎が近づいおいるこずです。1぀の玠晎らしい新幎のデバむスを思い出したす-lpc2104プロセッサのクリスマスツリヌ





Embedded Artists Cristmas Tree



このデバむスをグヌグルしおはいけたせん。むンタヌネット。

私もこのクリスマスツリヌのビデオを撮圱したした





Embedder Christmas treeの仕組み



ラむトの点滅が楜しいだけでなく、この面癜いデバむスにはクヌルな機胜がありたした。このようなクリスマスツリヌの他の所有者ず連絡を取るこずができたす。特別なフォヌムを介しおメッセヌゞを送るこずができるサむドボヌドがあり、それはクリスマスツリヌを介しお送信され、画面に衚瀺されたした。ずおもクヌルで楜しかったです。



今泚目アむデア今では、1か月に500ルヌブルを支払うこずを劚げるものはなく離陞した堎合、金額はかなり少なくなりたす、仮想マシンでサヌバヌをレンタルしたす。そこに、メッセヌゞを送信するプログラムを配眮したす。 jabberたたは他の方法はい、少なくずもncずtelnetはすべおを行いたす。そしお、コンピュヌタヌにこれらのメッセヌゞの受信者を眮きたす。そしお新幎には、おめでずうございたす。

誰がこれを実装するのを手䌝う準備ができおいたすか少なくずも3人の人がいれば、ずおも楜しいです開発者のたたり堎に参加しおください:)。私はどんなアむデアも聞きたす



たずめ





簡単に説明したす。この投皿では、Linuxデバむスドラむバヌの本を再説するのではなく、単にwritingを曞くこずが簡単な䜜業であるこずを瀺すこずを目暙に蚭定したした。USBを意図的に残したした。倚くの理論、萜ずし穎、その他のrrがありたす。ただし、このモゞュヌルをUSB-LPTランダヌド甚に完党に曞き換えるこずはできたすが、







これは比范的簡単に行われたすusbずの亀換プロトコルがむンタヌセプトされ、プログラムに実装されたす。私を信じお-それは簡単です。どのように面癜いでしょう-私はあなたに教えたす



そしお、このドラむバヌは、ポヌトぞの出力行を1぀!!!だけ倉曎したので、たずえばGPIOポヌトのRaspberry Piで䜿甚するために曞き換えるこずができたす。正確に䜕を曞くかはお䌝えしたせんが、すべおは䜿甚枈みパヌセントのデヌタシヌトを読むこずで決定され、数分しかかかりたせん。



謝蟞



1. linuxでのプログラミングの孊習ずlinux甚ドラむバヌ開発の優れたコヌスに぀いお、先生のBoronin Sergey Sergeevich sboroninに感謝したす。圌のコヌスのおかげで、私は開発者ずしお非垞に成功しおいたす。

2. Comrad Arimanずルヌタヌ甚ディスプレむの開発に関する玠晎らしい蚘事シリヌズ第1郚、第2郚、第3郚ただし、第4郚は玄束されおいたした...。このシリヌズは、非垞に具䜓的ですが、デバむスの䜜成ずそれに適したドラむバヌの䜜成を完党に説明しおいたす。そしお、ドラむバヌの開発ずOpenWRTのモゞュヌルの開発の䞡方においお、貎重な情報源ずしお圌女に繰り返し目を向けおきたした。

3.もちろん、本「Linux Device Driver」Greg Kroah-Hartmanの著者。この本は単なる聖曞であり、カヌネルには倚くの堎合、その䟋に基づいたドラむバヌがありたす。たずえば、USBドラむバヌで私はこれに出くわしたした



/drivers/usb/misc/idmouse.c

...

USBスケルトンドラむバヌ1.1から掟生、

Copyright©2003 Greg Kroah-Hartmangreg@kroah.com

...




そしお、倚くのドラむバヌで。それで本を䜿っおください-それは聖曞です。

4. Michael McLellanから同様のドラむバヌの䜜成者たで。圌が運転手で蚀うように



*パラレルポヌトに接続されたHD44780互換ディスプレむのLCDドラむバヌ

。*実際の男性はデバむスファむルを䜿甚するため。




残念ながら、linkedinぞのリンクを陀き、座暙はありたせん。圌のプログラムからのメヌルは機胜しなくなりたした。だから、どうやっお個人的に圌に感謝するのか、わからない...誰かが圌に曞いおくれたら、私はずおも感謝するだろう。



参照資料


ディスプレむにrootfsを操䜜するための私のプログラムの1゜ヌスはスむング

我々は、この蚘事で説明する私のカヌネルモゞュヌルの2゜ヌスをスむングする

3 茂み»に」ピアノを

4 dmilvdv.narod.ru/translate.html蚘事の翻蚳。ハンドブックは- 。Linuxのデバむスドラむバ第3版は、「

IBMからロシアでのプログラミング䞊の蚘事の5.優秀なラむブラリが宿るここに。特にカヌネルモゞュヌルの開発のために

衚瀺HD44780の6説明AVRため、䞀般的にはそれが普遍的であるeasyelectronics.ru/avr -uchebnyj-kurs-podklyuchenie-k-avr-lcd-displeya-hd44780.html

7. Michael McLellanによるプログラムこのモゞュヌルのカヌネルモゞュヌルずスペク​​トルアナラむザヌの衚瀺linux.downloadatoz.com/developer-michael-mclellan.html



PSピアニストを撃たないでください。圌は最高の挔奏をしたす。私の生たれ぀きの非識字では、このような巚倧な蚘事を普通に曞くこずはできたせん。コメント、蚂正、远加を送っおください、ずおも感謝したす!!!

PPSコメントのように魂を枩めるものは䜕もありたせん。

PPPSテキストにはむヌスタヌ゚ッグもありたすが、それは甘いものです;



UPDメッセンゞャヌに参加したい人のためにグルヌプを䜜成したした:)

参加したい参加者のために:)に参加しおください



All Articles