Saya sangat ingin tahu sekarang. Saya seorang programmer Python, dan pertanyaan ini mengejutkan saya: Anda menulis OS. Bagaimana Anda menjalankannya? Itu harus dijalankan entah bagaimana, dan seperti itu di dalam OS lain?
Bagaimana aplikasi dapat berjalan tanpa di OS? Bagaimana Anda memberi tahu komputer untuk menjalankan, katakanlah, C, dan jalankan perintah-perintah ini ke layar, jika tidak memiliki OS untuk dijalankan?
Apakah ini ada hubungannya dengan kernel UNIX? Jika demikian, apakah itu kernel Unix, atau kernel secara umum?
Saya yakin OS lebih rumit dari itu, tetapi bagaimana cara kerjanya?
kernel
operating-systems
Thor Correia
sumber
sumber
Jawaban:
Ada banyak situs web yang melalui proses boot (seperti Bagaimana Komputer Boot Up ). Singkatnya, ini adalah proses multi-tahap yang terus membangun sistem sedikit demi sedikit sampai akhirnya dapat memulai proses OS.
Dimulai dengan firmware pada motherboard yang mencoba untuk menghidupkan dan menjalankan CPU. Ini kemudian memuat BIOS yang seperti sistem operasi mini yang membuat perangkat keras lain berjalan dan berjalan. Setelah selesai, ia mencari perangkat boot (disk, CD, dll) dan, setelah ditemukan, ia menemukan MBR (master boot record) dan memuatnya ke dalam memori dan menjalankannya. Ini sepotong kecil kode yang kemudian tahu bagaimana menginisialisasi dan memulai sistem operasi (atau boot loader lainnya karena semuanya menjadi lebih rumit). Pada titik ini hal-hal seperti kernel akan dimuat dan mulai berjalan.
Sangat luar biasa bahwa ini bekerja sama sekali!
sumber
Sistem operasi "logam kosong" tidak berjalan di dalam apa pun. Ini menjalankan instruksi penuh yang ditetapkan pada mesin fisik, dan memiliki akses ke semua memori fisik, semua register perangkat dan semua instruksi istimewa, termasuk yang mengendalikan perangkat keras dukungan memori virtual.
(Jika sistem operasi berjalan pada mesin virtual, mungkin berpikir itu dalam situasi yang sama seperti di atas. Perbedaannya adalah bahwa hal-hal tertentu ditiru atau dengan cara lain ditangani oleh hypervisor; yaitu tingkat yang menjalankan mesin virtual .)
Bagaimanapun, sementara OS mungkin diimplementasikan dalam (misalnya) C, itu tidak akan memiliki semua perpustakaan C normal yang tersedia untuk itu. Secara khusus, itu tidak akan memiliki perpustakaan 'stdio' yang normal. Sebaliknya, itu akan menerapkan (misalnya) driver perangkat disk yang memungkinkannya untuk membaca dan menulis blok disk. Ini akan menerapkan sistem file di atas lapisan blok disk, dan di atas itu akan mengimplementasikan panggilan sistem yang dibuat oleh perpustakaan runtime aplikasi pengguna untuk (misalnya) membuat, membaca dan menulis file ... dan seterusnya.
Perlu jenis aplikasi khusus (misalnya sistem operasi) yang tahu cara berinteraksi langsung dengan perangkat keras I / O, dll.
Kamu tidak.
Aplikasi (yang demi argumen yang ditulis dalam C) dikompilasi dan dihubungkan pada beberapa mesin lain untuk memberikan gambar kode asli. Kemudian gambar ditulis ke hard drive di tempat yang dapat ditemukan oleh BIOS. BIOS memuat gambar ke dalam memori, dan menjalankan instruksi untuk melompat ke titik masuk aplikasi.
Ada (biasanya) tidak ada "menjalankan C dan menjalankan perintah" dalam aplikasi kecuali itu adalah sistem operasi full-blown. Dan dalam hal ini, merupakan tanggung jawab sistem operasi untuk mengimplementasikan semua infrastruktur yang diperlukan untuk mewujudkannya. Tanpa sihir. Hanya banyak kode.
Jawaban Bill mencakup bootstrap yang merupakan proses di mana Anda beralih dari mesin yang dimatikan ke mesin di mana sistem operasi normal aktif dan berjalan. Namun, perlu dicatat bahwa ketika BIOS menyelesaikan tugasnya, BIOS (biasanya) memberikan kendali penuh atas perangkat keras ke sistem operasi utama, dan tidak memainkan bagian lebih lanjut - hingga sistem berikutnya restart. OS utama tentu tidak menjalankan "dalam" BIOS dalam arti konvensional.
Ya itu.
Kernel UNIX adalah inti dari sistem operasi UNIX. Ini adalah bagian dari UNIX yang melakukan semua hal "bare metal" yang dijelaskan di atas.
Gagasan "kernel" adalah bahwa Anda mencoba memisahkan perangkat lunak sistem menjadi hal-hal inti (yang memerlukan akses perangkat fisik, semua memori, dll.), Dan hal-hal non-inti. Kernel terdiri dari hal-hal inti.
Pada kenyataannya, perbedaan antara kernel / inti dan non-kernel / non-inti lebih rumit dari itu. Dan ada banyak perdebatan tentang apa yang sebenarnya termasuk dalam kernel, dan apa yang tidak. (Cari mikro-kernel misalnya.)
sumber
The idea of a "kernel" is that you try to separate the system software into core stuff
Mudah diingat dengan memperhatikan bahwa istilahkernel
tersebut berasal dari bahasa JermanKern
, yang berarti inti / inti.Pada awalnya tidak ada daya pada CPU.
Dan Pria itu berkata "biarkan ada kekuatan", dan CPU mulai membaca dari alamat yang diberikan dalam memori dan menjalankan instruksi yang hadir di sana. Kemudian yang berikutnya dan seterusnya sampai akhir kekuasaan.
Ini adalah boot up. Tugasnya adalah memuat perangkat lunak lain untuk mendapatkan akses ke lingkungan, tempat perangkat lunak utama berada, dan memuatnya.
Akhirnya, layar yang ramah mengundang Anda untuk masuk.
sumber
0x7C00
untuk semuax86
arsitektur yang kompatibel dan pertama-tama harus diisi oleh BIOS yang biasanya memuat sektor pertama dari perangkat apa pun yang dapat di-boot yangMaaf terlambat, tapi saya akan menggambarkannya seperti ini:
Motherboard mendapat daya.
Sirkuit pengaturan waktu mulai dan stabil jika perlu, hanya berdasarkan karakteristik kelistrikannya. Beberapa perangkat yang lebih baru sebenarnya dapat menggunakan mikroprosesor atau sequencer yang sangat terbatas.
- Jerman pada pukul 5:20 pada 25 Oktober
Daya diberikan ke CPU dan RAM.
CPU memuat (berdasarkan kabel internal) data dari BIOS. Pada beberapa mesin, BIOS dapat dicerminkan ke RAM dan kemudian dieksekusi dari sana tapi itu jarang terjadi IIRC.
-Micheal Steil, 17 Kesalahan Microsoft Dibuat di Sistem Keamanan Xbox ( arsip )
BIOS melakukan panggilan ke port perangkat keras dan alamat yang digunakan oleh motherboard untuk disk dan IO perangkat keras lainnya dan memutar disk, membuat sisa RAM berfungsi, antara lain.
Kode BIOS (melalui pengaturan CMOS, disimpan dalam perangkat keras) menggunakan perintah IDE atau SATA tingkat rendah untuk membaca sektor booting setiap disk, dalam urutan yang ditentukan oleh CMOS atau pengguna menimpa dengan menu.
Disk pertama dengan sektor boot menjalankan sektor bootnya dijalankan. Sektor boot ini adalah Majelis yang memiliki instruksi untuk memuat lebih banyak data dari disk, memuat
NTLDR
tahap yang lebih besar , lebih lanjutGRUB
, dll.Akhirnya, kode mesin OS dijalankan oleh bootloader, secara langsung atau tidak langsung melalui pemuatan rantai memuat sektor boot dari lokasi alternatif atau offset.
Anda kemudian mendapatkan panik kernel, penguin mati lemas, atau disk Anda terhenti karena head crash. =) Dalam skenario alternatif, kernel Anda mengatur tabel proses, struktur dalam memori, dan me-mount disk, memuat driver, modul, dan GUI atau serangkaian layanan (jika di server). Kemudian, program dieksekusi saat tajuknya dibaca, dan perakitannya dibawa ke memori dan dipetakan sesuai.
sumber
Ada banyak jawaban bagus tapi saya ingin menambahkan ini: Anda menyebutkan Anda berasal dari latar belakang Python. Python adalah bahasa ninterpreted (atau "interpiled" atau apa pun, setidaknya dalam kasus penggunaan CPython khas). Ini berarti Anda memiliki beberapa perangkat lunak lain (juru bahasa Python) yang melihat sumbernya dan menjalankannya dengan cara tertentu. Ini adalah model yang bagus dan memungkinkan bahasa tingkat tinggi yang cukup bagus disarikan dari perangkat keras yang sebenarnya. Kelemahannya adalah Anda selalu membutuhkan perangkat lunak juru bahasa ini terlebih dahulu.
Perangkat lunak juru bahasa tersebut, biasanya, ditulis dalam bahasa yang mengkompilasi ke kode mesin, misalnya C atau C ++. Kode mesin adalah apa yang bisa ditangani oleh CPU. Apa yang dapat dilakukan CPU adalah membaca beberapa byte dari memori dan tergantung pada nilai byte yang memulai operasi tertentu. Jadi satu byte urutan adalah perintah untuk memuat beberapa data dari memori ke dalam register, urutan lain untuk menambahkan dua nilai, yang lain untuk menyimpan nilai dari register kembali ke memori utama dan segera (register adalah area memori khusus yang merupakan bagian dari cpu di mana ia dapat bekerja terbaik), sebagian besar dari perintah ini cukup rendah pada level itu. Yang dapat dibaca manusia untuk instruksi kode mesin ini adalah kode assembler. Kode mesin ini, pada dasarnya, adalah apa yang disimpan dalam file .exe or.com di windows atau di dalam binari Linux / Unix.
Sekarang jika komputer dinyalakan itu bodoh, ia memiliki beberapa kabel yang akan membaca instruksi kode mesin tersebut. Pada PC ini biasanya (saat ini) adalah sebuah chip EEPROM di mainboard yang berisi BIOS (sistem input keluaran dasar), sistem ini tidak dapat berbuat banyak, ia dapat memudahkan akses ke beberapa perangkat keras dll dan kemudian melakukan operasi kunci: pergi ke boot dan salin beberapa byte pertama (alias master boot record, MBR) ke dalam memori dan kemudian beri tahu CPU "di sini, ada program Anda" CPU akan memperlakukan byte tersebut di sana sebagai kode mesin dan menjalankannya. Biasanya ini adalah beberapa sistem operasi loader yang akan memuat kernel dengan beberapa parameter dan kemudian menyerahkan kontrol ke kernel itu, yang kemudian akan memuat semua drivernya untuk mengakses semua perangkat keras, memuat beberapa desktop atau program shell atau apa pun dan memungkinkan pengguna untuk login dan gunakan sistem.
sumber
Anda bertanya "Bagaimana aplikasi dapat berjalan tanpa di OS". Jawaban yang mudah adalah "OS bukan aplikasi". Sementara OS dapat dibuat dengan alat yang sama seperti aplikasi, dan dibuat dari bahan baku yang sama, mereka bukan hal yang sama. OS tidak harus bermain dengan aturan yang sama seperti aplikasi.
OTOH, Anda dapat menganggap perangkat keras dan firmware yang sebenarnya sebagai "OS" di mana "aplikasi" OS berjalan. Perangkat kerasnya adalah OS yang sangat sederhana - ia tahu cara menjalankan instruksi yang ditulis dalam kode mesin, dan ia tahu bahwa ketika dijalankan ia harus melihat alamat memori yang sangat spesifik untuk instruksi pertamanya. Jadi, itu dimulai dan kemudian segera menjalankan instruksi pertama, diikuti oleh yang kedua, dan seterusnya.
Jadi, OS hanyalah kode mesin yang ada di lokasi yang diketahui, dan yang dapat langsung berinteraksi dengan perangkat keras.
sumber
Jawaban untuk pertanyaan Anda membutuhkan pengetahuan tentang bagaimana kode asli (untuk CPU) terlihat dan bagaimana ditafsirkan oleh CPU.
Biasanya seluruh proses kompilasi didasarkan pada menerjemahkan hal-hal yang Anda tulis dalam C, Pascal atau bahkan Python (menggunakan pypy) dan C # ke dalam hal-hal yang dimengerti CPU, yaitu instruksi sederhana seperti "simpan sesuatu di bawah [alamat memori]", "tambah nomor yang disimpan di bawah register eax dan ebx "," panggil fungsi foo "," bandingkan eax hingga 10 ". Instruksi itu, dieksekusi satu per satu, melakukan hal-hal yang ingin Anda lakukan dengan kode Anda.
Sekarang pikirkan ini: Anda tidak benar-benar membutuhkan OS untuk menjalankan kode asli ini! Yang Anda butuhkan adalah memuat kode ini ke dalam memori dan memberi tahu CPU itu ada dan Anda ingin dieksekusi. Namun, jangan terlalu khawatir dengan itu. Itulah pekerjaan yang harus dikhawatirkan oleh BIOS - ini memuat kode Anda (hanya satu dan satu sektor), tepat setelah CPU dimulai, dengan alamat fisik 0x7C00. Kemudian CPU mulai menjalankan sektor yang satu ini (512 B) dari kode Anda. Dan Anda dapat melakukan apa pun yang Anda bayangkan! Tanpa, tentu saja, dukungan apa pun dari OS. Itu karena ANDA adalah sistem operasi. Keren ya Tidak ada perpustakaan standar, tidak ada peningkatan, tidak ada python, tidak ada program, tidak ada driver! Anda harus menulis semuanya sendiri.
Dan bagaimana Anda berkomunikasi dengan perangkat keras? Anda punya dua pilihan:
Sekarang Anda bertanya apa itu kernel. Singkatnya, kernel adalah semua yang tidak Anda lihat dan alami secara langsung. Ia mengelola, bersama dengan driver, semuanya, mulai dari keyboard Anda hingga hampir setiap perangkat keras di dalam PC Anda. Anda berkomunikasi dengannya melalui shell grafis atau terminal. Atau dengan fungsi di dalam kode Anda, sekarang dijalankan, untungnya, dengan dukungan OS.
Untuk pemahaman yang lebih baik saya dapat memberikan Anda satu saran: cobalah untuk menulis OS Anda sendiri. Bahkan jika itu akan menulis "Halo dunia" di layar.
sumber
Ada beberapa perbedaan untuk bagaimana sistem operasi beroperasi yang sangat bergantung pada sistem. Agar berguna, sistem perlu memiliki beberapa perilaku yang dapat diprediksi saat memulai, seperti "mulai mengeksekusi di alamat X". Untuk sistem yang memiliki penyimpanan non-volatile (seperti memori Flash) yang dipetakan ke dalam ruang program mereka, ini cukup mudah karena Anda hanya memastikan bahwa Anda meletakkan kode start-up di lokasi yang tepat dalam ruang program prosesor. Ini sangat umum untuk mikrokontroler. Beberapa sistem harus mengambil program start-up mereka dari beberapa lokasi lain sebelum menjalankannya. Sistem ini akan memiliki beberapa operasi bawaan (atau hampir bawaan) ke dalamnya. Ada beberapa prosesor yang mengambil kode start-up mereka melalui i2c dari chip lain,
Sistem yang menggunakan keluarga prosesor x86 biasanya menggunakan proses boot multi-tahap yang cukup rumit karena evolusi dan masalah kompatibilitas ke belakang. Sistem menjalankan beberapa firmware (disebut BIOS - Basic Input / Output System, atau yang serupa) yang ada di beberapa memori non-volatile pada motherboard. Terkadang beberapa atau semua firmware ini disalin (dipindahkan) ke RAM untuk membuatnya berjalan lebih cepat. Kode ini ditulis dengan pengetahuan tentang perangkat keras apa yang akan ada dan dapat digunakan untuk booting.
Firmware start-up biasanya ditulis dengan asumsi tentang perangkat keras apa yang akan hadir pada sistem. Bertahun-tahun yang lalu pada mesin 286 mungkin akan ada asumsi bahwa akan ada pengontrol floppy drive di alamat I / O X dan akan memuat sektor 0 ke lokasi memori tertentu jika diberi seperangkat perintah tertentu (dan kode pada sektor 0 tahu cara menggunakan fungsi BIOS sendiri untuk memuat lebih banyak kode, dan akhirnya cukup kode untuk menjadi OS yang dimuat). Pada mikrokontroler mungkin ada asumsi bahwa ada port serial yang beroperasi dengan pengaturan tertentu sehingga harus menunggu perintah (untuk memperbarui firmware yang lebih kompleks) dari untuk jumlah waktu X sebelum melanjutkan dengan proses boot.
Proses start-up yang tepat dari sistem yang diberikan tidak begitu penting bagi Anda karena mengetahui bahwa itu berbeda pada sistem yang berbeda, tetapi juga bahwa mereka semua memiliki kesamaan. Seringkali dalam kode start-up (bootstrap) ketika I / O perlu dilakukan, perangkat I / O disurvei daripada mengandalkan interupsi. Ini karena interupsi yang rumit, gunakan stack RAM (yang mungkin belum sepenuhnya diatur), dan Anda tidak perlu khawatir tentang memblokir operasi lain ketika Anda adalah satu-satunya operasi.
Setelah pertama kali dimuat, kernel OS (kernel adalah bagian utama dari sebagian besar OS) pada awalnya akan banyak bertindak seperti firmware. Ini perlu diprogram dengan pengetahuan atau menemukan perangkat keras yang ada, mengatur beberapa RAM sebagai ruang stack, melakukan berbagai tes, mengatur berbagai struktur data, mungkin menemukan dan memasang sistem file, dan kemudian mungkin memulai beberapa program yang lebih seperti program yang biasa Anda tulis (program yang mengandalkan OS yang ada).
Kode OS biasanya ditulis dalam campuran C dan assembly. Kode pertama untuk kernel OS mungkin selalu dalam perakitan dan melakukan hal-hal seperti mengatur stack, yang bergantung pada kode C, dan kemudian memanggil fungsi C. Perakitan tulisan tangan lainnya juga akan ada di sana karena beberapa operasi yang perlu dilakukan oleh OS sering tidak dapat diekspresikan dalam C (seperti penukaran konteks / penukaran tumpukan). Seringkali flag-flag khusus harus dilewatkan ke kompiler C untuk mengatakannya agar tidak bergantung pada pustaka standar yang digunakan sebagian besar program C dan untuk tidak berharap bahwa ada
int main(int argc, char *argv[])
dalam program. Selain itu, opsi tautan khusus yang tidak pernah digunakan oleh sebagian besar pemrogram aplikasi harus digunakan. Ini dapat membuat program kernel berharap untuk dimuat pada alamat tertentu atau mengatur hal-hal agar terlihat seperti ada variabel eksternal di lokasi tertentu meskipun variabel-variabel itu tidak pernah dideklarasikan dalam kode C apa pun (ini berguna untuk memori yang dipetakan I / O atau lokasi memori khusus lainnya).Seluruh operasi tampak seperti sulap pada awalnya, tetapi setelah Anda melihatnya dan memahami bagian-bagiannya, sulap menjadi hanya seperangkat program yang membutuhkan lebih banyak perencanaan dan pengetahuan sistem untuk diimplementasikan. Namun, men-debug mereka membutuhkan sihir.
sumber
Untuk memahami bagaimana sistem operasi bekerja, mungkin bermanfaat untuk membaginya menjadi dua kategori: yang hanya menyediakan layanan untuk aplikasi berdasarkan permintaan, dan yang menggunakan fitur perangkat keras dalam CPU untuk mencegah aplikasi melakukan hal-hal yang seharusnya tidak dilakukan. MS-DOS adalah gaya lama; semua versi Windows sejak 3.0 adalah gaya yang terakhir (setidaknya ketika menjalankan sesuatu yang lebih kuat dari 8086).
IBM PC asli yang menjalankan PC-DOS atau MS-DOS akan menjadi contoh gaya "OS" sebelumnya. Jika aplikasi ingin menampilkan karakter di layar, pasti ada beberapa cara untuk melakukannya. Itu bisa memanggil rutin yang akan meminta MS-DOS untuk mengirimnya ke "output standar". Jika berhasil, MS-DOS akan memeriksa apakah output sedang diarahkan dan, jika tidak, itu akan memanggil rutin yang disimpan dalam ROM (dalam kumpulan rutin yang disebut IBM Input Dasar / Sistem Output) yang akan menampilkan karakter di posisi kursor dan pindahkan kursor ("tulis teletype"). Rutin BIOS itu kemudian akan menyimpan sepasang byte di suatu tempat di kisaran 0xB800: 0 hingga 0xB800: 3999; perangkat keras pada Color Graphics Adapter akan berulang kali mengambil pasangan byte dalam rentang itu, menggunakan byte pertama dari setiap pasangan untuk memilih bentuk karakter dan yang kedua untuk memilih warna foreground dan background. Bytes diambil dan diproses menjadi sinyal merah, hijau, dan biru, dalam urutan yang menghasilkan tampilan teks yang dapat dibaca.
Program pada IBM PC dapat menampilkan teks dengan menggunakan rutin DOS "output standar", atau dengan menggunakan rutin BIOS "write teletype", atau dengan menyimpannya langsung untuk menampilkan memori. Banyak program yang perlu menampilkan banyak teks dengan cepat memilih untuk pendekatan yang terakhir, karena itu bisa ratusan kali lebih cepat daripada menggunakan rutinitas DOS. Ini bukan karena rutinitas DOS dan BIOS sangat tidak efisien; kecuali tampilan itu dikosongkan, itu hanya bisa ditulis pada waktu-waktu tertentu. Rutin BIOS untuk menampilkan karakter dirancang sehingga dapat dipanggil kapan saja; setiap permintaan dengan demikian harus mulai lagi menunggu waktu yang tepat untuk melakukan operasi penulisan. Sebaliknya, kode aplikasi yang tahu apa yang perlu dilakukan dapat mengatur dirinya sendiri di sekitar peluang yang tersedia untuk menulis tampilan.
Poin kunci di sini adalah bahwa sementara DOS dan BIOS menyediakan sarana untuk mengeluarkan teks ke tampilan, tidak ada sesuatu yang "magis" tentang kemampuan seperti itu. Sebuah aplikasi yang ingin menulis teks ke layar dapat melakukannya dengan efektif, setidaknya jika perangkat keras layar bekerja sesuai dengan yang diharapkan oleh aplikasi (jika seseorang telah menginstal Adaptor Layar Monokrom, yang mirip dengan CGA tetapi memiliki memori karakternya. terletak di 0xB000: 0000-0xB000: 3999), BIOS akan secara otomatis menampilkan karakter di sana; aplikasi yang diprogram untuk bekerja dengan MDA atau CGA dapat melakukannya juga, tetapi aplikasi yang diprogram hanya untuk CGA akan sama sekali tidak berguna di MDA).
Pada sistem yang lebih baru, segalanya sedikit berbeda. Prosesor memiliki berbagai mode "hak istimewa". Mereka memulai dalam mode yang paling istimewa, di mana kode diizinkan untuk melakukan apa pun yang diinginkan. Mereka kemudian dapat beralih ke mode terbatas, di mana hanya rentang memori yang dipilih atau fasilitas I / O yang tersedia. Kode tidak dapat beralih langsung dari mode terbatas kembali ke mode privilege, tetapi prosesor telah menetapkan titik masuk mode istimewa, dan kode mode terbatas dapat meminta prosesor untuk mulai menjalankan kode di salah satu titik masuk dalam mode istimewa. Selain itu, ada titik masuk mode-istimewa yang dikaitkan dengan sejumlah operasi yang akan dilarang dalam mode terbatas. Misalkan, misalnya, seseorang ingin menjalankan beberapa aplikasi MS-DOS secara bersamaan, dengan masing-masing memiliki layar sendiri. Jika aplikasi dapat menulis langsung ke pengontrol tampilan di 0xB800: 0, tidak akan ada cara untuk mencegah satu aplikasi menimpa layar aplikasi lain. Di sisi lain, OS dapat menjalankan aplikasi dalam mode terbatas dan menjebak akses apa pun ke memori tampilan; jika menemukan bahwa aplikasi yang seharusnya berada di "latar belakang" sedang mencoba untuk menulis 0xB800: 160, itu dapat menyimpan data ke beberapa memori yang telah disisihkan sebagai penyangga layar aplikasi latar belakang. Jika aplikasi itu kemudian beralih ke latar depan, buffer kemudian dapat disalin ke layar nyata. OS dapat menjalankan aplikasi dalam mode terbatas dan menjebak akses apa pun ke memori tampilan; jika menemukan bahwa aplikasi yang seharusnya berada di "latar belakang" sedang mencoba untuk menulis 0xB800: 160, itu dapat menyimpan data ke beberapa memori yang telah disisihkan sebagai penyangga layar aplikasi latar belakang. Jika aplikasi itu kemudian beralih ke latar depan, buffer kemudian dapat disalin ke layar nyata. OS dapat menjalankan aplikasi dalam mode terbatas dan menjebak akses apa pun ke memori tampilan; jika menemukan bahwa aplikasi yang seharusnya berada di "latar belakang" sedang mencoba untuk menulis 0xB800: 160, itu dapat menyimpan data ke beberapa memori yang telah disisihkan sebagai penyangga layar aplikasi latar belakang. Jika aplikasi itu kemudian beralih ke latar depan, buffer kemudian dapat disalin ke layar nyata.
Hal-hal penting yang perlu diperhatikan adalah (1) walaupun seringkali berguna untuk memiliki serangkaian rutinitas standar untuk melakukan berbagai layanan standar seperti menampilkan teks, mereka tidak melakukan apa pun yang aplikasi yang sedang berjalan dalam "mode istimewa" tidak dapat melakukan jika diprogram dengan benar untuk menangani perangkat keras yang diinstal; (2) meskipun sebagian besar aplikasi yang berjalan hari ini akan dicegah oleh sistem operasi mereka dari melakukan I / O secara langsung, sebuah program yang dijalankan dalam mode istimewa dapat melakukan apa pun yang diinginkan, dan dapat mengatur aturan apa pun yang diinginkan untuk mode terbatas program.
sumber
Seperti yang dikatakan Stephen C., ini bukan hanya tentang memulai Sistem Operasi, tetapi juga tentang cara kerjanya, berinteraksi dengan perangkat keras dan dengan perangkat lunak di atasnya.
Saya hanya akan menambahkan jawabannya, bahwa Anda mungkin ingin melihat "The Elements of Computing Systems" . Ini adalah buku dan beberapa alat, yang menjelaskan bagaimana komputer, sistem operasi, dan kompiler berinteraksi. Hal unik tentang itu adalah memberi Anda alat untuk dengan cepat mengembangkan sistem operasi Anda sendiri dalam lingkungan simulasi, mengabaikan banyak detail yang diperlukan untuk yang nyata, sehingga Anda dapat memahami konsep - konsepnya . Itu pekerjaan yang bagus untuk membiarkan Anda melihat hutan, bukan pohon.
Jika Anda ingin masuk ke detail lebih lanjut tentang bagaimana Sistem Operasi berinteraksi dengan perangkat keras, maka periksa Minix .
sumber
Aplikasi Anda berjalan dalam OS. Sistem Operasi ini menyediakan layanan untuk aplikasi Anda, hal-hal seperti membuka file dan menulis byte ke dalamnya. Layanan ini biasanya disediakan melalui panggilan sistem.
Sistem Operasi berjalan di dalam perangkat keras. Perangkat keras menyediakan layanan untuk Sistem Operasi, hal-hal seperti mengatur baud rate port serial dan menulis byte ke dalamnya. Layanan ini biasanya disediakan melalui register yang dipetakan memori atau port I / O.
Untuk memberikan contoh yang sangat sederhana tentang cara kerjanya:
Aplikasi Anda memberi tahu sistem operasi untuk menulis sesuatu ke file. Untuk aplikasi Anda, sistem operasi menyediakan konsep seperti file dan direktori.
Pada perangkat keras, konsep-konsep ini tidak ada. Perangkat keras menyediakan konsep seperti disk yang dibagi dalam blok-blok tetap sebesar 512 byte. Sistem operasi memutuskan blok mana yang akan digunakan untuk file Anda, dan beberapa blok lain untuk metadata seperti nama file, ukuran, dan lokasi pada disk. Kemudian memberitahu perangkat keras: tulis 512 byte ini ke sektor dengan nomor ini pada disk dengan nomor itu; tulis 512 byte ini ke sektor dengan angka berbeda pada disk dengan angka yang sama; dan seterusnya.
Cara sistem operasi memberi tahu perangkat keras untuk melakukan itu sangat bervariasi. Salah satu fungsi sistem operasi adalah untuk melindungi aplikasi dari perbedaan-perbedaan ini. Sebagai contoh disk, pada satu jenis perangkat keras, sistem operasi harus menulis disk dan nomor sektor ke port I / O, dan kemudian menulis byte satu per satu ke port I / O yang terpisah. Pada perangkat keras jenis lain, sistem operasi harus menyalin seluruh 512 byte sektor ke area memori, menulis lokasi memori tersebut ke lokasi memori khusus, dan menulis disk dan nomor sektor ke nomor yang lain. lokasi memori khusus.
Perangkat keras kelas atas saat ini sangat rumit. Manual yang memberikan semua detail pemrogramannya adalah doorstoppers dengan ribuan halaman; misalnya, manual CPU Intel terbaru adalah tujuh volume, dengan total lebih dari 4000 halaman — dan itu hanya untuk CPU. Sebagian besar komponen lain mengekspos blok memori atau port I / O, yang sistem operasi dapat memberitahu CPU untuk memetakan ke alamat dalam ruang alamatnya. Beberapa komponen ini mengekspos lebih banyak hal di balik beberapa port I / O atau alamat memori; sebagai contoh, RTC (Real Time Clock, komponen yang membuat waktu komputer saat dimatikan) memperlihatkan beberapa ratus byte memori di belakang sepasang port I / O, dan itu adalah komponen yang sangat sederhana yang berasal dari PC / AT asli. Hal-hal seperti hard disk memiliki seluruh prosesor yang terpisah, dimana sistem operasi berbicara melalui perintah standar. GPU bahkan lebih rumit.
Beberapa orang di komentar di atas menyarankan Arduino. Saya setuju dengan mereka, itu jauh lebih sederhana untuk dipahami — ATmega328, yang melakukan segalanya pada Arduino Uno kecuali mengekspos konektor USB sebagai port serial, memiliki manual dengan hanya beberapa ratus halaman. Di Arduino, Anda berjalan langsung di perangkat keras, tanpa sistem operasi di antaranya; hanya beberapa rutinitas pustaka kecil, yang tidak harus Anda gunakan jika tidak mau.
sumber
Contoh yang bisa dijalankan
Secara teknis, program yang berjalan tanpa OS, adalah OS. Jadi mari kita lihat cara membuat dan menjalankan beberapa OS dunia halo yang sangat kecil.
Kode semua contoh di bawah ini ada pada repo GitHub ini .
Sektor boot
Pada x86, hal tingkat paling sederhana dan terendah yang dapat Anda lakukan adalah membuat Master Boot Sector (MBR) , yang merupakan jenis sektor boot , dan kemudian instal ke disk.
Di sini kita membuat satu dengan satu
printf
panggilan:Hasil:
Diuji pada Ubuntu 18.04, QEMU 2.11.1.
main.img
berisi yang berikut ini:\364
dalam oktal ==0xf4
dalam hex: pengkodean untukhlt
instruksi, yang memberitahu CPU untuk berhenti bekerja.Karenanya program kami tidak akan melakukan apa-apa: hanya memulai dan berhenti.
Kami menggunakan oktal karena
\x
nomor hex tidak ditentukan oleh POSIX.Kami dapat memperoleh enkode ini dengan mudah dengan:
tetapi
0xf4
pengkodean juga didokumentasikan pada manual Intel tentu saja.%509s
menghasilkan 509 ruang. Diperlukan untuk mengisi file hingga byte 510.\125\252
dalam oktal ==0x55
diikuti oleh0xaa
: byte ajaib yang diperlukan oleh perangkat keras. Itu harus byte 511 dan 512.Jika tidak ada, perangkat keras tidak akan memperlakukan ini sebagai disk yang dapat di-boot.
Perhatikan bahwa bahkan tanpa melakukan apa pun, beberapa karakter sudah dicetak di layar. Itu dicetak oleh firmware, dan berfungsi untuk mengidentifikasi sistem.
Jalankan pada perangkat keras nyata
Emulator memang menyenangkan, tetapi perangkat keras adalah masalahnya.
Perhatikan bahwa ini berbahaya, dan Anda dapat menghapus disk Anda secara tidak sengaja: hanya lakukan ini pada mesin lama yang tidak mengandung data penting! Atau bahkan lebih baik, devboards seperti Raspberry Pi, lihat contoh ARM di bawah ini.
Untuk laptop biasa, Anda harus melakukan sesuatu seperti:
Bakar gambar ke stik USB (akan menghancurkan data Anda!):
pasang USB di komputer
Hidupkan
katakan itu untuk boot dari USB.
Ini berarti membuat firmware memilih USB sebelum hard disk.
Jika itu bukan perilaku default mesin Anda, terus tekan Enter, F12, ESC atau kunci aneh lainnya setelah dinyalakan hingga Anda mendapatkan menu boot di mana Anda dapat memilih untuk boot dari USB.
Seringkali dimungkinkan untuk mengonfigurasi urutan pencarian di menu-menu itu.
Misalnya, pada Lenovo Thinkpad T430 lama saya, UEFI BIOS 1.16, saya dapat melihat:
Halo Dunia
Sekarang kita telah membuat program minimal, mari kita pindah ke dunia halo.
Pertanyaan yang jelas adalah: bagaimana cara melakukan IO? Beberapa pilihan:
port serial . Ini adalah protokol standar yang sangat sederhana yang mengirim dan mengambil karakter dari terminal host.
Sumber .
Sayangnya ini tidak terpapar pada kebanyakan laptop modern, tetapi merupakan cara umum untuk menggunakan papan pengembangan, lihat contoh ARM di bawah ini.
Ini benar-benar memalukan, karena antarmuka seperti itu sangat berguna untuk men-debug kernel Linux misalnya .
gunakan fitur debug chip. ARM menyebut semihosting mereka misalnya. Pada perangkat keras nyata, ini memerlukan beberapa perangkat keras dan dukungan perangkat lunak tambahan, tetapi pada emulator itu bisa menjadi pilihan nyaman gratis. Contoh .
Di sini kita akan melakukan contoh BIOS karena lebih sederhana pada x86. Tetapi perhatikan bahwa itu bukan metode yang paling kuat.
utama
link.ld
Kumpulkan dan tautkan dengan:
Hasil:
Diuji pada: Lenovo Thinkpad T430, UEFI BIOS 1.16. Disk dihasilkan pada host Ubuntu 18.04.
Selain instruksi perakitan pengguna darat standar, kami memiliki:
.code16
: memberitahu GAS untuk mengeluarkan kode 16-bitcli
: nonaktifkan interupsi perangkat lunak. Itu bisa membuat prosesor mulai berjalan lagi setelahhlt
int $0x10
: melakukan panggilan BIOS. Inilah yang mencetak karakter satu per satu.Bendera tautan penting adalah:
--oformat binary
: mengeluarkan kode rakitan biner mentah, jangan membengkokkannya di dalam file ELF seperti halnya untuk executable userland biasa.Gunakan C sebagai ganti perakitan
Karena C mengkompilasi ke perakitan, menggunakan C tanpa pustaka standar cukup sederhana, pada dasarnya Anda hanya perlu:
main
, terutama:TODO: tautan jadi beberapa contoh x86 di GitHub. Ini ARM yang saya buat .
Akan lebih menyenangkan jika Anda ingin menggunakan pustaka standar, karena kami tidak memiliki kernel Linux, yang mengimplementasikan banyak fungsi pustaka standar C melalui POSIX .
Beberapa kemungkinan, tanpa masuk ke sistem operasi lengkap seperti Linux, termasuk:
Newlib
Contoh terperinci di: https://electronics.stackexchange.com/questions/223929/c-standard-libraries-on-bare-metal/223931
Di Newlib, Anda harus mengimplementasikan syscall sendiri, tetapi Anda mendapatkan sistem yang sangat minim, dan sangat mudah untuk menerapkannya.
Misalnya, Anda dapat mengarahkan ulang
printf
ke sistem UART atau ARM, atau menerapkannyaexit()
dengan semihosting .sistem operasi tertanam seperti FreeRTOS dan Zephyr .
Sistem operasi seperti itu biasanya memungkinkan Anda untuk mematikan penjadwalan pre-emptive, sehingga memberi Anda kendali penuh atas runtime program.
Mereka dapat dilihat sebagai semacam Newlib pra-implementasi.
LENGAN
Dalam ARM, ide-ide umumnya sama. Saya telah mengunggah:
beberapa contoh sederhana QEMU di sini di GitHub . Contoh prompt.c mengambil input dari terminal host Anda dan mengembalikan semua output melalui UART yang disimulasikan:
Lihat juga: https://stackoverflow.com/questions/38914019/how-to-make-bare-metal-arm-programs-and-run-them-on-qemu/50981397#50981397
pengaturan blinker Raspberry Pi yang sepenuhnya otomatis di: https://github.com/cirosantilli/raspberry-pi-bare-metal-blinker
Lihat juga: https://stackoverflow.com/questions/29837892/how-to-run-ac-program-with-no-os-on-the-raspberry-pi/40063032#40063032
Untuk Raspberry Pi, https://github.com/dwelch67/raspberrypi sepertinya tutorial yang paling populer saat ini.
Beberapa perbedaan dari x86 termasuk:
IO dilakukan dengan menulis ke alamat sihir secara langsung, tidak ada
in
danout
instruksi.Ini disebut memori yang dipetakan IO .
untuk beberapa perangkat keras nyata, seperti Raspberry Pi, Anda dapat menambahkan sendiri firmware (BIOS) ke gambar disk.
Itu adalah hal yang baik, karena itu membuat memperbarui firmware itu lebih transparan.
Firmware
Sebenarnya, sektor boot Anda bukan perangkat lunak pertama yang berjalan pada CPU sistem.
Apa yang sebenarnya berjalan pertama adalah apa yang disebut firmware , yang merupakan perangkat lunak:
Firmwares yang terkenal meliputi:
Firmware melakukan hal-hal seperti:
lewati setiap hard disk, USB, jaringan, dll. hingga Anda menemukan sesuatu yang dapat di-boot.
Ketika kami menjalankan QEMU,
-hda
mengatakan itumain.img
adalah hard disk yang terhubung ke perangkat keras, danhda
adalah yang pertama diadili, dan digunakan.muat 512 byte pertama ke alamat memori RAM
0x7c00
, letakkan RIP CPU di sana, dan biarkan berjalanmenunjukkan hal-hal seperti menu boot atau panggilan cetak BIOS pada tampilan
Firmware menawarkan fungsionalitas mirip OS di mana sebagian besar OS bergantung. Misalnya subset Python telah porting untuk dijalankan di BIOS / UEFI: https://www.youtube.com/watch?v=bYQ_lq5dcvM
Dapat dikatakan bahwa firmware tidak dapat dibedakan dari OS, dan bahwa firmware adalah satu-satunya pemrograman bare metal yang "benar" yang dapat dilakukan.
Seperti yang dikatakan CoreOS dev ini :
Poskan keadaan awal BIOS
Seperti banyak hal dalam perangkat keras, standardisasi lemah, dan salah satu hal yang tidak boleh Anda andalkan adalah keadaan awal register ketika kode Anda mulai berjalan setelah BIOS.
Jadi bantulah diri Anda sendiri dan gunakan beberapa kode inisialisasi seperti berikut: https://stackoverflow.com/a/32509555/895245
Mendaftar suka
%ds
dan%es
memiliki efek samping yang penting, jadi Anda harus membidiknya meskipun Anda tidak menggunakannya secara eksplisit.Perhatikan bahwa beberapa emulator lebih bagus daripada perangkat keras asli dan memberikan Anda kondisi awal yang bagus. Kemudian ketika Anda menjalankannya pada perangkat keras nyata, semuanya rusak.
GNU GRUB Multiboot
Sektor boot sederhana, tetapi tidak terlalu nyaman:
Karena alasan itulah GNU GRUB membuat format file yang lebih nyaman yang disebut multiboot.
Contoh kerja minimal: https://github.com/cirosantilli/x86-bare-metal-examples/tree/d217b180be4220a0b4a453f31275d38e697a99e0/multiboot/hello-world
Saya juga menggunakannya pada repo contoh GitHub saya untuk dapat dengan mudah menjalankan semua contoh pada perangkat keras nyata tanpa membakar USB satu juta kali. Pada QEMU tampilannya seperti ini:
Jika Anda menyiapkan OS Anda sebagai file multiboot, GRUB kemudian dapat menemukannya di dalam sistem file biasa.
Inilah yang dilakukan sebagian besar distro, menempatkan gambar OS di bawah
/boot
.File multiboot pada dasarnya adalah file ELF dengan header khusus. Mereka ditentukan oleh GRUB di: https://www.gnu.org/software/grub/manual/multiboot/multiboot.html
Anda dapat mengubah file multiboot menjadi disk yang dapat di-boot dengan
grub-mkrescue
.El Torito
Format yang dapat dibakar ke CD: https://en.wikipedia.org/wiki/El_Torito_%28CD-ROM_standard%29
Dimungkinkan juga untuk menghasilkan gambar hibrida yang bekerja pada ISO atau USB. Ini dapat dilakukan dengan
grub-mkrescue
( contoh ), dan juga dilakukan oleh kernel Linux saatmake isoimage
menggunakanisohybrid
.Sumber daya
sumber