Linux-0.11
Kursus Teori: https://www.bilibili.com/video/bv1d4411v7u7
Referensi yang berguna ( Linux-0.11 Versi komentar): https://github.com/beride/linux0.11-1
Cabang utama adalah kode sumber Linux-0.11
Lihat Perbedaan Kode: Permintaan Tarik Pilih cabang yang sesuai dan bandingkan dengan main
✔️ Boot Sistem Operasi LAB0 (Cabang Lab0)
Menulis ulang bootsect.s terutama melengkapi fungsi -fungsi berikut:
- Bootsect.s dapat mencetak pesan "XXX sedang boot ..." di layar.
Pengaturan penulisan ulang terutama melengkapi fungsi -fungsi berikut:
- Bootsect.s dapat menyelesaikan pemuatan setup.s dan melompat ke pengaturan. Mulai alamat eksekusi. dan output. Setup.s dapat memperoleh setidaknya satu parameter perangkat keras dasar (seperti parameter memori, parameter kartu grafis, parameter hard disk, dll.), Simpan di alamat tertentu dalam memori, dan output ke layar. Pengaturan tidak lagi memuat kernel Linux, simpan saja informasi di atas yang ditampilkan di layar.
Buku Instruksi Eksperimental: https://www.lanqiao.cn/courses/115/labs/568/document/
✔️ Lab1 mengimplementasikan panggilan sistem (cabang lab1)
- Jumlah total panggilan sistem yang dimodifikasi dalam kernel/system_call.s adalah 74.
- Tambahkan makro di include/unistd.h untuk menunjukkan penentuan posisi tabel fungsi panggilan.
- Tulis dua fungsi (sys_iam, sys_whoami) definisi fungsi in include/linux/sys.h. Dan tambahkan dua fungsi baru ke tabel fungsi setelahnya.
- Menambahkan kernel/who.c untuk mengimplementasikan dua panggilan sistem.
- Ubah Makefile
- OBJ meningkatkan siapa ketergantungan (who.o)
- Tambahkan kondisi generasi ketergantungan untuk siapa.s dan who.o dalam dependensi
- Buat Execute ./run untuk memasukkan subsistem Linux, dan tambahkan definisi makro IAM dan whoami di /usr/include/unistd.h (sama seperti titik 2).
- Menulis program pengujian dalam pengujian keadaan pengguna apakah berhasil.
Buku Instruksi Eksperimental: https://www.lanqiao.cn/courses/115/labs/569/document/
✔️ Lab2 mengimplementasikan pelacakan lintasan operasi proses (cabang lab2)
- Process.c mengimplementasikan skenario yang mensimulasikan komputasi CPU hybrid dan komputasi IO, dan menjalankannya dengan cara multi-proses.
- Cetak beberapa keadaan switching proses kernel (waktu status PID) ke /var/process.log.
- Setelah fungsi init () di Init/Main memasuki pernyataan status pengguna, Associate File Descriptor 3 ke /var/process.log.
- Menerapkan fungsi fprintk () dalam kernel/printk untuk mencetak output ke log proses.log.
- Temukan titik switching status dan tambahkan fprintk () untuk menulis log.
- Proses mulai kernel/system_call.s -> sys_fork (call copy_process)
- Jalankan, memblokir status sakelar kernel/sched.c -> jadwal sys_pause sleep_on interruptible_sleep_on wake_up
- Keluar Kernel/Exit.c -> do_exit sys_waitpid
- Catatan: GCC di Linux-0.11 tidak dapat dikompilasi // dikomentari.
Buku Instruksi Eksperimental: https://www.lanqiao.cn/courses/115/labs/570/document/
✔️ Lab3 menggantikan proses TSS asli di Linux0.11 untuk beralih ke switching stack (cabang lab3)
Metode switching asli adalah melalui TSS, yang setara dengan snapshot register. Itu langsung diganti di tempat melalui instruksi yang disediakan oleh Intel, yang lebih lambat. Stack Switching lebih efisien.
Kernel/SCHED.C
- Metode sakelar asli didasarkan pada sakelar TSS, dan kami ingin mengomentarinya di file header.
- Switch_to baru, membutuhkan dua parameter (1: pointer ke PCB 2 berikutnya: Posisi tugas berikutnya dalam array digunakan untuk beralih LDT).
kernel/system_call.s
- Tulis implementasi perakitan switch_to
- Mengalihkan PCB
- Tulis ulang posisi tumpukan kernel TSS (TSS dipertahankan saat ini, tetapi hanya ada satu TSS di dunia, dan tidak digunakan untuk melakukan switching proses.)
- Ganti tumpukan kernel
- Sakelar LDT
Kernel/fork.c.
- Keluar dari pengaturan TSS di PCB.
- Tambahkan variabel anggota baru - Kernel Stack ke PCB, yang digunakan untuk menyimpan informasi tumpukan kernel.
- Tulis informasi tumpukan di sini dan biarkan PCB variabel anggota menunjuk ke pointer.
Buku Instruksi Eksperimental: https://www.lanqiao.cn/courses/115/labs/571/document/
Referensi: https://blog.csdn.net/qq_42518941/article/details/119182097
✔️ Lab4 Menerapkan Panggilan Sistem Semaphore di Linux0.11 (Cabang Lab4)
Poin Pengetahuan Pra-Kunci
- Kernel/send.c sleep_on melewati header antrian menunggu yang masuk, mengatur arus ke status pemblokiran, dan secara aktif menjalankan jadwal (). TMP menyimpan antrian pemblokiran asli. Saat terbangun, antrian pemblokiran semuanya diatur ke Runnable.
- Kernel/SCHED.C Wake_UP Bangun semua PCB yang diblokir. Hanya pemimpin tim bangun yang dapat dilihat dalam program ini, tetapi harus dibaca dalam kombinasi dengan sleep_on. Setelah digabungkan, Anda akan menemukan bahwa kepala bangun akan bangun selanjutnya.
Tulis aplikasi "pc.c" untuk menyelesaikan masalah produser-konsumen klasik dan lengkapi fungsi-fungsi berikut:
- Menetapkan proses produsen, N proses konsumen (n> 1)
- Buat buffer bersama dengan file
- Proses produser menulis bilangan bulat 0, 1, 2, ..., m, m> = 500 ke buffer pada gilirannya
- Proses konsumen dibaca dari buffer, membacakan satu per satu, dan menghapus nomor baca dari buffer, dan kemudian mengeluarkan ID proses dan + angka ke output standar
- Buffer hanya dapat menghemat hingga 10 angka secara bersamaan
Menerapkan semaphore
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 );
- sem_open membuka semaphore
- Jika semaphore saat ini sama dengan nol, memblokir proses
- Tambahkan satu semaphore
- Matikan semaphore
Fokus menunggu dan memposting
- Tunggu
- Hubungi Kernel/SCHED.C Sleep_on untuk menunggu pemblokiran
- Gunakan interupsi Linux (Linux0.11 inti tunggal) untuk melindungi zona kritis
- minus satu nilai sem
- pos
- Tambahkan satu ke nilai SEM. Jika nilainya lebih besar dari 0, hubungi kernel/sched.c Wake_up untuk membangunkan proses yang diblokir oleh semaphore ini.
- Gunakan interupsi Linux (Linux0.11 inti tunggal) untuk melindungi zona kritis
Buku Instruksi Eksperimental: https://www.lanqiao.cn/courses/115/labs/572/document/
✔️ Pemetaan dan berbagi alamat LAB5 (Cabang Lab5)
Alamat logis -> GDT -> LDT -> Tabel Halaman -> Alamat Fisik
Pengetahuan Teori Instrumen
Pemilih segmen
Akses ke Tabel Deskriptor Global oleh GDTR dilakukan melalui "Pemilih Segmen" (Daftar Segmen dalam Mode Nyata)
15 3 2 1 0
| Indeks | | Rpl |
- 3-15 adalah indeks deskriptor, yang menunjukkan deskriptor dari segmen yang diperlukan dalam tabel deskriptor.
- 2 Untuk menunjukkan apakah pemilih dipilih dalam GDT atau dalam LDT (0 mewakili GDT 1 mewakili LDT).
- 0-1 adalah tingkat hak istimewa yang harus dipilih.
Pemilih segmen mencakup tiga bagian: indeks deskriptor (indeks), TI, dan tingkat hak istimewa permintaan (RPL). Bagian indeks (indeks deskriptor) menunjukkan deskriptor dari segmen yang diperlukan dalam posisi tabel deskriptor. Dari posisi ini, deskriptor yang sesuai dapat ditemukan berdasarkan alamat dasar tabel deskriptor yang disimpan dalam GDTR. Kemudian, alamat basis segmen dalam tabel deskriptor ditambah alamat logis (sel: offset) dapat dikonversi menjadi alamat linier. Nilai TI dalam pemilih segmen hanya satu 0 atau 1. 0 berarti bahwa pemilih dipilih dalam GDT, dan 1 berarti pemilih dipilih dalam LDT. Level Privilege Permintaan (RPL) mewakili tingkat hak istimewa pemilih, dan ada 4 tingkat hak istimewa (Level 0, Level 1, Level 2, dan Level 3).
Catatan pada tingkat hak istimewa: Setiap segmen dalam tugas memiliki tingkat tertentu. Setiap kali program mencoba mengakses segmen, tingkat hak istimewa yang dimiliki program dibandingkan dengan tingkat hak istimewa yang akan diakses untuk menentukan apakah segmen tersebut dapat diakses. Konvensi sistem adalah bahwa CPU hanya dapat mengakses segmen dari tingkat hak istimewa yang sama atau pada tingkat hak istimewa yang lebih rendah.
Misalnya, berikan alamat logis: 21h: 12345678h dikonversi ke alamat linier
A. Selector sel = 21h = 000000000000100 0 01 (b) Berarti: Indeks pemilih = 4, yaitu, 0100, dan deskriptor keempat dalam GDT dipilih; TI = 0 berarti pemilih dipilih dalam GDT; 01 terakhir berarti tingkat hak istimewa RPL = 1.
B. Offset = 12345678h Jika alamat basis segmen yang dijelaskan dalam deskriptor keempat GDT saat ini adalah 1111111h, maka alamat linier = 111111H + 12345678H = 23456789H.
Kunjungi GDT
- Pertama dapatkan alamat basis GDT dari register GDTR.
- Kemudian dalam GDT, deskriptor segmen dinilai pada indeks posisi 13-bit pemilih segmen tinggi.
- Dapatkan alamat dasar, tambahkan offset untuk mendapatkan alamat linier.
Akses LDT
- Pertama dapatkan alamat basis GDT dari register GDTR.
- Dapatkan indeks posisi segmen di mana LDT terletak dari register LDTR (LDTR adalah 13 bit lebih tinggi).
- Deskriptor segmen LDT diperoleh dalam GDT dengan indeks posisi ini untuk mendapatkan alamat basis segmen LDT.
- Gunakan pemilih segmen untuk mendapatkan deskriptor segmen dari segmen LDT.
- Dapatkan alamat dasar, tambahkan offset untuk mendapatkan alamat linier.
Buku Instruksi Eksperimental: https://www.lanqiao.cn/courses/115/labs/573/document/
✔️ Kontrol Perangkat Terminal Lab6 (Cabang Lab6)
- Ketika interupsi keyboard terjadi, kode pemindaian keyboard dihapus dan kode pemindaian diproses sesuai dengan tabel KEY_TABLE.
- Lengkapi fungsi penulisan untuk kunci F12.
- Setelah diproses, masukkan karakter dengan kode pemindaian yang sesuai ke put_queue.
- Hubungi do_tty_interrupt untuk pemrosesan akhir, di mana copy_to_cooked melakukan preprocessing akhir, dan kemudian hubungi con_write ke output ke kartu grafis.
- tulis -> sys_write -> tty_write -> con_write.
Buku Instruksi Eksperimental: https://www.lanqiao.cn/courses/115/labs/574/document/
✔️ Implementasi Sistem File Proc Lab7 (Lab Cabang7)
Pengetahuan Teoritis
disk
Membaca dan Menulis Disk Mekanis Membutuhkan Tiga Parameter Untuk Menemukan
- Silinder (c)
- Kepala (h)
- Sektor
block = C * ( H * S ) + H * S + S ;
Membagi beberapa sektor menjadi satu blok untuk meningkatkan efisiensi disk IO (Linux0.11 membagi 2 sektor menjadi satu blok). Untuk tingkat yang lebih tinggi, Anda hanya perlu memasukkan nomor blok baca dan tulis untuk melakukan disk IO.
Divisi: Blok Boot | Super Block | Bitmap Inode | Bitmap Data | Blok Inode | Blok Data
dokumen
Gunakan FCB (inode di Linux0.11) untuk menyimpan informasi file, termasuk berbagai jenis file (misalnya: file perangkat, file direktori ...).
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 ; // 更新标志。
}; Nomor blok file pada disk disimpan dalam inode dan beberapa informasi deskripsi file lainnya. Mungkin ada beberapa tingkat panduan posisi blok disk, yang dibagi menjadi indeks langsung dan indeks tidak langsung untuk mendapatkan posisi blok.
Daftar isi
Temukan data dalam nomor blok disk data yang sesuai sesuai dengan inode direktori, yang berisi nomor blok disk inode dari subdirektori yang ada di direktori. Cari layer demi layer dan Anda dapat menemukan lokasi direktori target akhir.
Buku Instruksi Eksperimental: https://www.lanqiao.cn/courses/115/labs/575/document/