最初からオペレヌティングシステム。 レベル2叀い半分

ファむルシステムを䜜成したす。 ファむルシステムはそれ自䜓を曞き蟌みたせん。 ラボのこの半分では、FAT32ファむルシステムを実装し、SDカヌドドラむバヌをそれに固定し、むンタラクティブシェルを介しお少しやり取りしたす。


れロラボ


最初のラボ 若い半分ず叀い半分


最も若い郚分 。 カットの䞋で続けた。


フェヌズ232ビット脂質


このフェヌズでは、FAT32ファむルシステムを実装したす。 珟時点では排他的に読み取り専甚です。 䞻な䜜業は、 2-fs/fat32たす。


ディスクずファむルシステム


ディスク䞊のデヌタは、1぀以䞊のファむルシステムによっお管理されたす。 メモリアロケヌタず同様に、ファむルシステムはメモリの管理、割り圓お、および解攟を行いたす。 唯䞀の違いは、これは高速RAMではなく、䜎速で䞍揮​​発性のメモリであるこずです。 ぀たり、すべおの倉曎は将来い぀でも保存されたす。 コンピュヌタヌの再起動埌を含む。 倚くの異なるファむルシステムがありたす。 Linuxには、EXT4がありたす。 MacOSにはHFS +ずAPFSがありたす。 WindowsにはNTFSがありたす。 䞀郚のファむルシステムは、䞀床に耇数のOSに実装されたす。 FAT32はそのようなものです。 Linux、macOS、Windowsを含むすべおの䞻芁なオペレヌティングシステムに実装されおいたす。 元々は、DOSの埌のバヌゞョンずWindowsの前のバヌゞョンで䜿甚されおいたした。 FAT32の䞻な利点は、どこにでもあるこずです。 これは、最もクロスプラットフォヌムなファむルシステムの1぀です。


ディスク䞊に耇数のファむルシステムを配眮できるようにするために、この同じディスクをパヌティションに分割できたす。 各セクションは、異なるファむルシステム甚に個別にフォヌマットできたす。 ディスクをパヌティション分割するために、ディスクは、どのセクションが開始するか、ダりンロヌドされる堎所、およびこのセクションが䜿甚するファむルシステムのタむプを特定の堎所に曞き蟌みたす。 1぀の䞀般的なシステムは、マスタヌブヌトレコヌド、たたは単にMBRです。 MBRには、セクションを説明する4぀の゚ントリのテヌブルが含たれおいたす。 ただし、䞀郚のセクションは䜿甚枈みずしお宣蚀されない堎合がありたす。 GPTのような若干新しいパヌティションスキヌムがありたす。これは、特に4぀以䞊のパヌティションをサポヌトしたす。


この割り圓おでは、1぀のFAT32パヌティションを含むディスクからMBRを読み取るコヌドを実装したす。 この組み合わせは、ラズベリヌによっお䜿甚されたす。MBRずFAT32も䜿甚されたす。


ディスクのパヌティション分割


次の図は、MBRずFAT32を䜿甚したディスクパヌティションの物理レむアりトを瀺しおいたす。


MBRおよびFAT32


FAT構造 PDFには、これらの構造のサむズず内容に関する必芁な情報がすべお含たれおいたす。 最䜎限必芁な説明ずずもに。 ファむルシステムを実装するずきにドキュメントを䜿甚したす。 さらに、察応するりィキペディアの蚘事を調べるこずも圹立ちたす 。


マスタヌブヌトレコヌド


MBRは垞にディスクのれロセクタヌにありたす。 MBRには4぀のパヌティション゚ントリが含たれたす。 これらの各゚ントリには、セクションのタむプ、セクタヌ内のセクションのオフセット、およびこのセクションがブヌト可胜かどうかなどのさたざたなフラグが含たれたす。 CHSシリンダヌ、ヘッド、セクタヌなどの他のすべおのフィヌルドは完党に無芖できたす。 これは、ほずんどの最新の実装が行うこずです。 FAT32のパヌティションタむプが0xBたたは0xBあるこずも泚目に倀したす。


拡匵BIOSパラメヌタブロック


FAT32パヌティションの最初のセクタヌには、BIOSパラメヌタヌの拡匵ブロックが含たれおいたす。 頭字語EBPB。 このブロック自䜓は、BIOSたたはBPBパラメヌタヌブロックで始たりたす。 䞀緒に、FATファむルシステムに必芁なすべおのレむアりトオプションを決定したす。


EBPBには、特別な泚意を払う䟡倀のある領域が1぀ありたす。 予玄枈みセクタヌの数を決定するもの。 これは、FATが芋぀かるセクタヌのFAT32セクションの先頭からのオフセットです。 最埌のFATの盎埌に、クラスタヌのデヌタを含む領域がありたす。 次に、FAT、デヌタ領域、クラスタヌをさらに詳しく芋おいきたす。それだけです。


クラスタヌ


FATファむルシステムに保存されおいるすべおのデヌタはクラスタヌに分割されたす。 EBPBには、クラスタヌ内の各クラスタヌのセクタヌ数を確認できるフィヌルドがありたす。 クラスタヌの番号付けは2から始たりたす。図からわかるように、クラスタヌ2のデヌタはデヌタ領域の先頭にありたす。 クラスタヌ3のデヌタは、クラスタヌ2の盎埌に配眮されたす。


ファむル割り圓おテヌブル


FATはファむルアロケヌションテヌブルの略です。 ファむル配垃テヌブル。 FATずいう名前に基づいお、これはFATレコヌドのテヌブル配列です。 FAT32では、このような各曞き蟌みのサむズは32ビットです。 このテヌブル党䜓のサむズは、EPBPのFATあたりのセクタヌずセクタヌあたりのバむトフィヌルドによっお決たりたす。 冗長性のために、ファむルシステムに耇数のFATが存圚する堎合がありたす聖なるバックアップの名前で。 テヌブルの数はEPBPでも確認できたす。 FATのフィヌルド番号を参照しおください。


0ず1の番号が付けられたレコヌドに加えお、各FATレコヌドがクラスタヌの状態を決定したす。 泚2はクラスタヌ2のステヌタスを瀺したす。ドリンク3はクラスタヌ3のステヌタスを決定したす。 各クラスタヌには独自のFATレコヌドがありたす。


゚ントリ0ず1が最も可胜性が高いです。



これら2぀のレコヌドに加えお、他のすべおのレコヌドはデヌタ領域の特定のクラスタヌに察応しおいたす。 FATレコヌドはフルサむズで32ビットですが、䜿甚されるのは28ビットのみです。 䞊䜍4ビットは無芖されたす。 たた、倀は次のずおりです。



クラスタヌチェヌン


クラスタヌはクラスタヌのチェヌンを圢成したす。 これは、本質的にクラスタヌのリンクリストです。 クラスタヌがデヌタに䜿甚される堎合、その倀には次のクラスタヌぞのリンクが含たれるか、チェヌンの終わりを瀺すEOCマヌカヌになりたす。


䟋ずしお、8぀のFATレコヌドを含むチャヌトを考えたす。


クラスタヌチェヌン


クラスタヌは色で色分けされおいるため、どのチェヌンに属しおいるかを簡単に把握できたす。 最初の2぀の゚ントリはIDずEOCです。 レコヌド2は、察応するクラスタヌがデヌタクラスタヌであり、このチェヌン緑色が1クラスタヌのサむズであるこずを瀺しおいたす。 レコヌド3は、クラスタヌ3にデヌタが含たれおおり、チェヌンの次青がクラスタヌ5になり、クラスタヌ6がこのチェヌンを切断するこずを瀺したす。 同様に、クラスタヌ7ずクラスタヌ5はチェヌンを圢成したす赀。 クラスタヌ番号8は無料で䜿甚されおいたせん。


カタログず蚘録


クラスタヌチェヌンは、ファむルたたはディレクトリのデヌタです。 ディレクトリは、ファむル名ず他のすべおのメタデヌタを含む特別なファむルの本質です。 ガゞェット内には、カタログ゚ントリの配列がありたす。 各゚ントリには、名前、開始クラスタ、およびこの゚ントリがディレクトリか単なるファむルかが含たれたす。


他のディレクトリの゚ントリに関連付けられおいない特別なディレクトリが1぀ありたす。 ルヌトディレクトリ。 ルヌトディレクトリの開始クラスタヌは、EBPBにありたす。 これにより、他のすべおのファむルずディレクトリの堎所を特定できたす。


歎史的な理由により、物理ディレクトリの各゚ントリは、2぀の異なる方法で解釈できたす。 属性フィヌルドは、これらのメ゜ッドのいずれかを指したす。 これら2぀のバリ゚ヌションは次のずおりです。



11文字より長いファむル名を䜿甚するために、長いファむル名LFNがFAT32に远加されたす。 ゚ントリの名前が11文字を超える堎合、LFN゚ントリが前に付きたす。 ただし、これらのレコヌドは物理的に゜ヌトされおいたせん。 代わりに、シヌケンスを決定するためのフィヌルドが含たれおいたす。 したがっお、LFNレコヌドの物理的な順序は信頌できたせん。


だから


続行する前に、FAT構造を理解する必芁がありたす。 その埌、次の質問に答えおください。


最初のセクタヌにMBR構造が含たれおいるかどうかを確認する方法は [mbr-magic]

ディスクの最初のセクタヌにMBRが含たれおいない堎合がありたす。 MBRが存圚するかどうかを確認するにはどうすればよいですか



FAT32クラスタヌの最倧数はいく぀ですか [最倧クラスタヌ]

FAT32の蚭蚈には、いく぀かの制限がありたす。 FAT32のクラスタヌの最倧数ず、これらの制限はどこから来たすか FAT16を䜿甚する堎合、同じ制限たたは他の制限がありたすか



単䞀ファむルの最倧サむズは [最倧ファむルサむズ]

最倧ファむルサむズに制限はありたすか もしそうなら、最倧ファむルサむズは䜕であり、この境界を決定するものは䜕ですか

ヒント ディレクトリ内の゚ントリの構造を芋おください。



LFNレコヌドがあるかどうかを刀断する方法 [lfn-identity]

ディレクトリ内の゚ントリをよく芋るず、LFNが目の前にあるのか、通垞の゚ントリにあるのかを正確に刀断するのはどのバむトですか 具䜓的には、これらのバむトは䜕で、どのような倀が必芁ですか



/a/b/c.txt [マニュアル怜玢] を芋぀けるにはどうすればよいですか

EBPBを念頭に眮いお、 /a/b/c.txtファむルの初期クラスタヌを芋぀けるために実行するすべおの手順を説明したす。

コヌド構造


ファむルシステムを曞くこずは非垞に奇劙なこずです。 FAT32は、それを読むだけですが、䟋倖ではありたせん。 2-fs/fat32提䟛されるコヌドは基本的に基本構造を提䟛したすが、倚くの蚭蚈䞊の決定ず実装の倧郚分は完党にあなたのものです。


次に、すでに準備が敎っおいるものに぀いお説明したす。 fat32/srcディレクトリからコヌドを読み取りたす。


ファむルシステムの特性


そこで、 traitsモゞュヌルを芋぀けるこずができたす。 ゚ントリポむントはtraits/mod.rs そこには、玄7぀の特性ず1぀の構造がありたす。 ファむルシステムを実装する堎合、これをすべお実装したす。


ほずんどの特性の架空の実装を提䟛するDummy構造が1぀ありたす。 このタむプはスタブずしお䜿甚できたす。 コヌドをよく芋るず、このスタブはいく぀かの堎所で䜿甚されおいたす。 たぶんあなたは䟿利になるでしょう。


次の順序でtraits/からコヌドを読むこずをお勧めしたす。



キャッシュデバむス



ドラむブに盎接アクセスするのは非垞に高䟡な操䜜です。 したがっお、すべおのアクセスはキャッシュされたセクタヌで実行されたす。 CachedDevice構造は、 vfat/cache.rs 。 セクタヌキャッシュぞの透過的か぀明瀺的なアクセスを提䟛したす。 本質的に、これは内郚的にHashMapをストレヌゞずしお䜿甚するBlockDeviceラッパヌです。 HashMapのキヌは、セクタヌ番号になりたす。 CachedDeviceを実装するず、 BlockDeviceキャッシュバヌゞョンずしお透過的に䜿甚できたす。 さらに、 get()およびget_mut()メ゜ッドが提䟛され、キャッシュされたセクタヌを盎接参照できたす。


さらに、 CachedDevice定矩されおいる論理セクタヌず物理セクタヌ間の察応を監芖するには、 CachedDevice構造がCachedDevice 。 このためにvirtual_to_physical()メ゜ッドが提䟛されvirtual_to_physical()たす。 これず同じ方法を䜿甚しお、特定の論理セクタヌに぀いお読み取る必芁がある物理セクタヌの数を決定する必芁がありたす。


有甚性


util.rsファむルには、スラむス &[T] および動的配列 Vec<T> の1぀の有甚な特性ずその実装が含たれおいたす。 これを䜿甚しお、特定の条件を維持しながら盞互に転送できたす。 たずえば、 &[u32]を&[u8]にキャストするには&[u8]次を䜿甚できたす。


 use util::SliceExt; let x: &[u32] = &[1, 2, 3, 4]; assert_eq!(x.len(), 4); let y: &[u8] = unsafe { x.cast() }; assert_eq!(y.len(), 16); 

MBRおよびEBPB


mbr.rs構造は、 mbr.rsファむルにありたす。 圌女はBlockDeviceからMBRを読み取り、分析する責任がありたす。 同様に、 BiosParameterBlock構造䜓を䜿甚できたす。 ファむルvfat/ebpb.rsにありたす。 圌女は、FAT32のBPBおよびEBPBセクションの読み取りず分析を担圓しおいたす。


共有


vfat/shared.rsのShared<T>構造は、タむプTぞのセキュアな可倉アクセスに䜿甚できたすT ファむルシステムの実装に圹立ちたす。 特に、コヌドのさたざたな郚分からFSぞのアクセスを共有する機胜が必芁な堎合。 先に進む前に、 Shared<T>䜿甚する方法ず理由を理解しおください。


ファむルシステム


ファむルシステム自䜓のカヌネルは、 vfat/vfat.rsファむルにありたす。 明らかにこれはVFat構造です。 ご芧のずおり、構造にはCachedDeviceが含たれおいCachedDevice 。 実装は、提䟛されたBlockDeviceをCachedDeviceラップする必芁がCachedDeviceたす。


VFATずは䜕ですか

VFATは、FAT32の前身であるMicrosoftの別のファむルシステムです。 さたざたな歎史的理由から、これはFAT32ず同矩語になりたした。 垞に正しい名前ずは限らず、この愚かな䌝統を続けたす。

タむプ&Shared<VFat>のFileSystemプロパティの郚分的な実装&Shared<VFat>すでに存圚したす。 さらに、 from()メ゜ッドがShared<VFat>返すこずに気付くかもしれたせん。 䞻なタスクは、 from()メ゜ッドの実装、および&Shared<VFat>必芁なFileSystemプロパティを完了するこずです。 これは、ファむルシステムプロパティの必芁な郚分を実装する他の構造の実装に぀ながりたす。


別のvfat/ディレクトリが芋぀かりたす



ファむルシステムを実装するずきは、必芁なコヌドでこれをすべお補完する必芁がありたす。 これらの構造のいずれかを、必芁ず思われる方法で補足するこずを恐れないでください。 ただし、既存のメ゜ッドに察しお提䟛されおいる特性たたは眲名の定矩を倉曎しないでください。


vfat.rsから始たるすべおのコヌドを読んで、そこで䜕が起こっおいるのかを理解しおください。


実装


これで、FAT32ファむルシステムを実装するために必芁なものがすべお揃いたした。 最適な順序で実装を行うこずができたす。


提䟛されおいるすべおのブランクを必ず曎新しおください

すべおのリポゞトリのコピヌが最新であるこずを確認しおください。 git pullを䜿甚しお2-fsずosの最新バヌゞョンを入手し、必芁なものをすべお修正したす。

実装をテストするための厳密なテストセットを提䟛したす。 テストを実行make clean && make fetch前に、 2-fsディレクトリでmake clean && make fetch実行したす。 耇数のファむルを2-fs/files/resources/アップロヌドしたす。 これらのファむルは単䜓テストで䜿甚されたす。 このディレクトリには、MBR、EBPB、FAT32を含むむメヌゞず、実装のさたざたな郚分をテストするために䜿甚されるハッシュがありたす。 Linuxの* BlessやmacOSのHex Fiendなどの16進゚ディタヌを䜿甚しお画像を分析するず䟿利な堎合がありたす。


テストは、 cargo testを䜿甚しお実行できたす。 デバッグメッセヌゞを衚瀺するには、 cargo test -- --nocapture実行したす。 これにより、 stdoutずstderrむンタヌセプトが防止されたす。 さらに、必芁ず思われる量のテストを自由に远加できたす。 マヌゞの競合を防ぐため、 tests.rs以倖の名前のファむルにテストを远加するこずをお勧めしたす。


次のルヌルに埓うこずもお勧めしたす。



あなたが望む順序ですべおを行うこずができたす。 ただし、次の順序をお勧めしたす。


  1. mbr.rs解析MBRを実装したす。 おそらく実装には、 unsafeでunsafe䜿甚する必芁がありたす。 ただし、1行で十分です。 最も可胜性の高いスラむス:: from_raw_parts_mutたたはmem :: transmute 。 mem::transmute()非垞に匷力なツヌルです。 できるだけ長く䜿甚しないでください。 それ以倖の堎合は、䜕をしおいるかを完党に理解する必芁がありたす。 Debugを実装するには、 Formatter debug_struct()を䜿甚したす。 CachedDevice Debug .
  2. EBPB ebpb.rs . MBR, unsafe .
  3. MBR EBPB. . BlockDevice Cursor<&mut [u8]> . :

     println!("{:#?}", x); 
  4. CachedDevice vfat/cached.rs .
  5. VFat::from() vfat/vfat.rs . MasterBootRecord , BiosParameterBlock CachedDevice . MBR EBPB.
  6. FatEntry vfat/fat.rs .
  7. VFat::fat_entry , VFat::read_cluster VFat::read_chain . Cluster . . . . VFat::fat_entry .
  8. vfat/metadata.rs . Date , Time Attributes , . FAT . Timestamp Metadata , Entry , File Dir .
  9. Dir vfat/dir.rs Entry vfat/entry.rs .
    Dir , Cluster Shared<VFat> . File vfat/file.rs . , Iterator<Item=Entry> entries() . entries() unsafe . VecExt SliceExt . FAT — , Dir .

    Entry
    LFN, , union . VFatDirEntry . Rust . .

    . , , . union . .

    . , LFN, , . . .

    UTF-16 LFN. decode_utf16() . UTF-16 Vec<u16> .
    Dir::find()

    Dir::find() traits::Dir Dir . , Dir::find() . . eq_ignore_ascii_case() .
  10. File vfat/file.rs . , Cluster Shared<VFat> . traits::File File . entries() Dir .
  11. VFat::open() vfat/vfat.rs . components() , Path . , , std , , . read_dir() , is_file() , is_dir() .

    Dir::find() . VFat::open() . 17 . Dir .

, - , , . ! , , .


SD-



SD- Raspbrerry Pi 3, Foreign function interface FFI . FFI Rust 19.1 Rust . . os/kernel/src/fs .


Foregin Function Interface


FFI Rust , . , Rust, extern :


 extern { static outside_global: u32; fn outside_function(param: i16) -> i32; } 

outside_function outside_global . :


 unsafe { let y = outside_function(10); let global = outside_global; } 

, unsafe . Rust , . . , , Rust , . outside_function outside_global . .


Rust , ( ) . Rust (mangles) , . . , , . #[no_mangle] :


 #[no_mangle] fn call_me_maybe(ptr: *mut u8) { .. } 

() :


 void call_me_maybe(unsigned char *); call_me_maybe(...); 

Rust ? [foreign-safety]

, Rust , . , Rust , Rust , , Rust.



Rust ? [mangling]

. C++ Rust . , ? , , Rust .

SD-


SD- os/kernel/ext/libsd.a . . ぀たり . os/kernel/src/sd.rs , .


wait_micros , . . . :


 /* * Sleep for `us` microseconds. */ void wait_micros(unsigned int us); 

— API Rust-. Sd , SD- new() . BlockDevice Sd . unsafe . , MBR kmain . , . , , .


: 64- ARM unsigned int u32 Rust.



? [foreign-sync]

SD- ( sd_err ) . . ? , Rust unsafe -. ? ?
: ! ( , ) ?



. kernel/src/fs/mod.rs .


, . , . , , static FILE_SYSTEM: FileSystem kernel/src/kmain.rs . , .


. . FileSystem kernel/src/fs/mod.rs , FAT32 SD-. Sd ( BlockDevice ) initialize() . FileSystem , VFat . , kmain .


, ( / ) SD-. , — .


4: Mo'sh


cd , pwd , ls cat . os/kernel/src/shell.rs .




. ( cwd current working directory) — , . cwd /a , hello /a/hello . cwd /a/b/c , hello /a/b/c/hello . / , . . /hello hello .


cd <dir> . cd /hello/there , cwd /hello/there . cd you , cwd cd /hello/there/you .


. , cwd .


チヌム


, : cd , pwd , ls cat . :



. . . — , . , .


実装


os/kernel/src/shell.rs . PathBuf , . PathBuf cd . . , .


, , — . おめでずうございたす


必ずビンアロケヌタヌを䜿甚しおください

ほずんどの堎合、ファむルシステムの実装はメモリを非垞に集䞭的に䜿甚したす。メモリ䞍足を回避するには、必ずビンアロケヌタヌを䜿甚しおください。割り圓おるだけでなく、メモリを解攟するこずもできたす。



ヒント既存のメ゜ッドPathBufを䜿甚Pathし、目的に合わせお䜿甚​​したす。



ヒントあなたは、具䜓的に泚意を匕く必芁がありたす..し、.実装時にcd。

そのようなこず。

Source: https://habr.com/ru/post/J353024/


All Articles