理論コース:https://www.bilibili.com/video/bv1d4411vv7u7
便利な参照( Linux-0.11コメント済みバージョン):https://github.com/beride/linux0.11-1
メインブランチはLinux-0.11ソースコードです
bootsect.sの書き換えは、主に次の機能を完了します。
セットアップを書き換えると、主に次の機能が完了します。
実験指導書:https://www.lanqiao.cn/courses/115/labs/568/document/
実験的な指導書:https://www.lanqiao.cn/courses/115/labs/569/document/
実験指導帳:https://www.lanqiao.cn/courses/115/labs/570/document/
元のスイッチング方法はTSSを介したもので、これはレジスタのスナップショットに相当します。 Intelが提供する指示を通じて、現場で直接置き換えられますが、これは遅いです。スタックスイッチングがより効率的です。
実験指導書:https://www.lanqiao.cn/courses/115/labs/571/document/
参照:https://blog.csdn.net/qq_42518941/article/details/119182097
sem_t * sem_open ( const char * name , unsigned int value );
int sem_wait ( sem_t * sem );
int sem_post ( sem_t * sem );
int sem_unlink ( const char * name );実験指導書:https://www.lanqiao.cn/courses/115/labs/572/document/
論理アドレス - > gdt-> ldt->ページテーブル - >物理アドレス
GDTRによるグローバル記述子テーブルへのアクセスは、「セグメントセレクター」(実際のモードのセグメントレジスタ)を介して行われます。
15 3 2 1 0
|インデックス| | rpl |
セグメントセレクターには、記述子インデックス(インデックス)、TI、およびリクエスト特権レベル(RPL)の3つの部分が含まれます。そのインデックス(記述子インデックス)部分は、記述子テーブルの必要なセグメントの記述子の位置を示します。この位置から、対応する記述子は、GDTRに保存されている記述子テーブルベースアドレスに基づいて見つけることができます。次に、記述子テーブルのセグメントベースアドレスと論理アドレス(SEL:オフセット)を線形アドレスに変換できます。セグメントセレクターのTi値は1つの0または1。0です。0は、セレクターがGDTで選択されていることを意味し、1はLDTでセレクターが選択されていることを意味します。リクエスト特権レベル(RPL)は、セレクターの特権レベルを表し、4つの特権レベル(レベル0、レベル1、レベル2、およびレベル3)があります。
特権レベルに関する注意:タスクの各セグメントには特定のレベルがあります。プログラムがセグメントにアクセスしようとするときはいつでも、プログラムが持っている特権レベルを特権レベルと比較して、セグメントにアクセスできるかどうかを判断します。システム条約は、CPUが同じ特権レベルのセグメントのみにアクセスできるか、より低い特権レベルでのみアクセスできることです。
たとえば、論理アドレスを指定してください:21H:12345678Hは線形アドレスに変換されます
a。セレクターSEL = 21H = 00000000100 0 01(b)平均:Selector = 4のインデックス、つまり0100、およびGDTの4番目の記述子が選択されています。 Ti = 0は、セレクターがGDTで選択されていることを意味します。最後の01は、特権レベルRPL = 1を意味します。
b。オフセット= 12345678Hこの時点でGDTの4番目の記述子で説明されているセグメントベースアドレスが1111111Hで、次に線形アドレス= 111111H + 12345678H = 23456789H。
実験的な指導書:https://www.lanqiao.cn/courses/115/labs/573/document/
実験指導帳:https://www.lanqiao.cn/courses/115/labs/574/document/
機械的なディスクの読み取りと書き込みには、3つのパラメーターを見つける必要があります
block = C * ( H * S ) + H * S + S ;いくつかのセクターを1つのブロックに分割して、ディスクの効率を向上させます(Linux0.11 2つのセクターを1つのブロックに分割します)。より高いレベルの場合、ディスクIOを実行するために読み取りおよび書き込みブロック番号を入力するだけです。
分割:ブートブロック|スーパーブロック| INODE BITMAP |データビットマップ|イノードブロック|データブロック
FCB(Linux0.11のInode)を使用して、さまざまなタイプのファイル(例:デバイスファイル、ディレクトリファイルなど)を含むファイル情報を保存します。
struct m_inode
{
unsigned short i_mode ; // 文件类型和属性(rwx 位)。
unsigned short i_uid ; // 用户id(文件拥有者标识符)。
unsigned long i_size ; // 文件大小(字节数)。
unsigned long i_mtime ; // 修改时间(自1970.1.1:0 算起,秒)。
unsigned char i_gid ; // 组id(文件拥有者所在的组)。
unsigned char i_nlinks ; // 文件目录项链接数。
unsigned short i_zone [ 9 ]; // 直接(0-6)、间接(7)或双重间接(8)逻辑块号。
/* these are in memory also */
struct task_struct * i_wait ; // 等待该i 节点的进程。
unsigned long i_atime ; // 最后访问时间。
unsigned long i_ctime ; // i 节点自身修改时间。
unsigned short i_dev ; // i 节点所在的设备号。
unsigned short i_num ; // i 节点号。
unsigned short i_count ; // i 节点被使用的次数,0 表示该i 节点空闲。
unsigned char i_lock ; // 锁定标志。
unsigned char i_dirt ; // 已修改(脏)标志。
unsigned char i_pipe ; // 管道标志。
unsigned char i_mount ; // 安装标志。
unsigned char i_seek ; // 搜寻标志(lseek 时)。
unsigned char i_update ; // 更新标志。
}; ディスク上のファイルのブロック番号は、イノードおよびその他のファイルの説明情報に保存されます。複数のレベルのディスクブロック位置ガイダンスがあります。これらは、ブロック位置を取得するための直接インデックスと間接インデックスに分割されます。
ディレクトリに存在するサブディレクトリのイノードディスクブロック番号を含むディレクトリイノードに従って、対応するデータディスクブロック番号のデータを見つけます。レイヤーごとにレイヤーを検索すると、最終ターゲットディレクトリの場所を見つけることができます。
実験指導書:https://www.lanqiao.cn/courses/115/labs/575/document/