Sehubungan dengan ulasan negatif dari artikel percobaan “Mengembangkan OC-Scheduler yang menyerupai Microkernel Unix-like”, saya memutuskan untuk
memulai kembali serangkaian artikel, dengan mempertimbangkan beberapa komentar. Sekarang, setelah menyadari target audiens saya, saya dapat mengalihkan fokus dari jenis saya ke mereka yang benar-benar membutuhkannya.
Tanggapan terhadap komentar untuk artikel sebelumnya.
Catatan 1. Penjadwal terlalu sederhana.
Sejak publikasi artikel sebelumnya, kode ini telah banyak berubah. Inti penuh terbentuk, yang tidak lagi menjadi mikronuklear. Ada dukungan untuk ram disk awal (sistem file kernel), dukungan untuk memori virtual (MMU). Adalah mungkin bagi kernel untuk menulis program khusus. Ada panggilan sistem dan perpustakaan clib (stdio, string). Jadi, shell /initrd/sh.elf adalah program terpisah yang diuraikan oleh bootloader elf dan berjalan sebagai suatu proses.
Daftar perintah shell: exec <file.elf>, ps, kill, keluar. Dalam hal ini, shell dapat diluncurkan dari shell itu sendiri (menunjukkan multitasking).
Catatan 2. Terlalu banyak keajaiban di balik layar dalam tutorial video.
Saya memutuskan untuk menyorot teks yang sedang saya jelaskan. Dia juga menuju pemula yang membutuhkan klarifikasi dan hal-hal sederhana. Sejujurnya, saya terkejut bahwa pendatang baru yang tidak memiliki pengalaman dalam pemrograman tertarik pada topik yang begitu kompleks, meskipun itu adalah dosa untuk disembunyikan, saya mulai dari itu. Saya menggeser bias dari menjelaskan OS saya ke menjelaskan bagaimana menulis OC Anda.
Komentar 3. Di mana tautan ke
github ?
Sekarang dia. Dalam
deskripsi video di YouTube (ya, saya ingin Anda tidak melewati tutorial video saya, setidaknya lihatlah satu mata).
Komentar 4. Kita harus mulai dengan majelis terlebih dahulu.
Itu yang akan kita lakukan.
Komentar 5. Anda tidak menulis apa pun tetapi hanya berkomentar.
Ya, itu adalah kesalahan untuk berbicara tentang sesuatu yang besar segera. Sekarang kita akan bergerak selangkah demi selangkah, secara bertahap, dimulai dengan kernel Hello world yang paling sederhana. Video tutorial akan memungkinkan Anda untuk membuat gambar holistik dunia, dan kode sumber pada github akan membenamkan Anda dalam detail.
Daftar isi.
1. Membangun sistem (make, gcc, gas). Boot awal (multiboot). Luncurkan (qemu). Pustaka C (strcpy, memcpy, strext).
2. Pustaka C (sprintf, strcpy, strcmp, strtok, va_list ...). Membangun perpustakaan dalam mode kernel dan mode aplikasi pengguna.
3. Log sistem kernel. Memori video Output ke terminal (kprintf, kpanic, kassert).
4. Memori dinamis, banyak (kmalloc, kfree).
6. Pengaturan memori dan penanganan interupsi (GDT, IDT, PIC, syscall). Pengecualian
5. Memori virtual (direktori halaman dan tabel halaman).
6. Prosesnya. Perencana Multitasking. Panggilan sistem (bunuh, keluar, ps).
7. Sistem file kernel (initrd), elf dan internalnya. Panggilan sistem (exec).
8. Driver perangkat karakter. Panggilan sistem (ioctl, fopen, fread, fwrite). Pustaka C (fopen, fclose, fprintf, fscanf).
9. Shell sebagai program lengkap untuk kernel.
10. Mode perlindungan pengguna (ring3). Segmen Status Tugas (tss).
Ayo pergi. Bagian 1. Bangun sistem dan luncurkan
Dalam artikel ini saya hanya akan mencantumkan
langkah-langkah kunci . Untuk penjelasan terperinci, lihat tutorial video untuk artikel ini.
Anda membutuhkan Linux. Kami akan mengumpulkan hasil lama yang baik. Untuk mengkompilasi file executable kernel, flag-flag berikut diperlukan:
CC_FLAGS=-g -m32 -isystem $(IDIR) -I include -DKERNEL=1 -fno-stack-protector -Wall -Werror -fno-pie AS_FLAGS=-g --32 LD_FLAGS=-m elf_i386
Sebagai emulator perangkat keras, instal qemu emulator di Linux. Kami akan menjalankan kernel kami seperti ini:
qemu-system-i386 -kernel ./bin/kernel.elf
Ini juga akan membutuhkan skrip kecil untuk tautan. Diperlukan untuk memuat bagian di alamat yang benar dan dalam urutan yang benar. Juga di dalamnya kita akan menunjukkan titik masuk:
OUTPUT_FORMAT(elf32-i386) ENTRY(start) SECTIONS { . = 0x100000; .text : { *(.text) } .data : { *(.data) } .bss : { *(.bss) } }
Karena kernel akan dimuat sesuai dengan spesifikasi multiboot, header akan diperlukan di awal bagian kode:
.code32 .text # multiboot spec .align 4 multiboot: .long 0x1BADB002 # magic .long 0x00 # flags .long -(0x1BADB002 + 0x00) # checksum. m+f+c should be zero
Dianjurkan agar Anda segera beralih ke tumpukan Anda sendiri dan mengatur tabel deskriptor global. Tentukan tumpukan kami sendiri:
.bss .fill 8192,1 # 8Kb stack:
Tulis titik masuk. Anda mungkin menemukan sintaks assembler gnu tidak biasa. Saya dulu juga lebih suka sintaks Intel, kemudian setelah mencicipinya, menggali ke dalam kode sumber Linux, saya benar-benar lebih suka sintaks AT&T untuk diri saya sendiri.Hal utama yang perlu diingat adalah bahwa mereka memiliki operan yang berlawanan. Sisanya akan intuitif.
start: cli movl $stack,%esp push %esp push %ebx /* address of struct multiboot_t */ call kernel_start /* should never return */ hlt
Ini melengkapi kode boilerplate. Kesenangan dimulai. Sekarang kita dapat menulis kode dalam C. Dan pertama-tama, kita akan mendefinisikan pesan sambutan.
char *hello = "Hello world!"; int screen_size = 80 * 25;
Selanjutnya, kita menulis entry point itu sendiri dimana kode assembler akan mentransfer kontrol:
/* * Api - Kernel entry point */ extern void kernel_start(struct multiboot_t* multiboot, void* kstack) { char *video = (char*)0xB8000; char buff[screen_size + 1]; video[screen_size] = '\0'; memset(buff, ' ', screen_size); strext(video, buff, 0x7); strext(video, hello, 0x7); }
Di sini kita hanya menampilkan pesan di layar. Pada prinsipnya, Anda benar-benar dapat menyalin kode pelajaran pertama, karena itu adalah templat dan tidak akan pernah diubah. Untuk menampilkan sesuatu di layar, Anda hanya perlu menuliskannya langsung ke dalam memori video, melengkapi setiap karakter dengan simbol atribut. Untuk melakukan ini, Anda akan membutuhkan perpustakaan C Anda sendiri, yang akan kami tulis sendiri untuk kebutuhan kami. Sehingga akan lebih mudah untuk mengontrol prosesnya. Jadi misalnya, hari ini kita memiliki 2 fungsi yang kita kenal (strcpy, memcpy) dan salah satu strext kita sendiri untuk memasukkan byte atribut setelah setiap karakter.
Kesimpulan
Itu saja untuk hari ini. Tonton tutorial video dan cobalah melakukan hal yang sama pada Anda sendiri. Jika tidak berhasil, Anda dapat mengintip ke sumber untuk pelajaran tentang github. Tautan ke
github dalam deskripsi tutorial video:Sastra
1. James Molloy. Gulung mainan Anda sendiri UNIX-clone OS.
2. Gigi. Assembler untuk DOS, Windows, Unix
3. Kalashnikov. Assembler mudah!
4. Tanenbaum. Sistem operasi. Implementasi dan pengembangan.
5. Robert Love. Kernel Linux Deskripsi proses pengembangan.