GNU/Linux >> Belajar Linux >  >> Linux

Segmentasi menggunakan register

  1. Anda pasti sudah membaca beberapa buku lama karena tidak ada yang memprogram untuk mode-nyata lagi;-) Dalam mode nyata , Anda bisa mendapatkan alamat fisik akses memori dengan phyical address = segment register * 0x10 + offset , offset menjadi nilai di dalam salah satu register tujuan umum. Karena register ini lebarnya 16 bit, panjang segmen akan menjadi 64kb dan tidak ada yang dapat Anda lakukan tentang ukurannya, hanya karena tidak ada atribut! Dengan * 0x10 multiplikasi, 1mb memori menjadi tersedia, tetapi ada kombinasi yang tumpang tindih tergantung pada apa yang Anda masukkan ke dalam register segmen dan daftar alamat . Saya belum menyusun kode apa pun untuk mode-nyata , tapi menurut saya terserah OS untuk menyiapkan register segmen selama pemuatan biner, seperti pemuat akan mengalokasikan beberapa halaman saat memuat biner ELF. Namun saya telah mengkompilasi kode kernel bare-metal, dan saya harus menyiapkan register ini sendiri.

  2. Empat segmen wajib dalam model datar karena kendala arsitektur. Dalam mode terlindungi register segmen tidak lagi berisi alamat basis segmen, melainkan pemilih segmen yang pada dasarnya merupakan offset ke dalam GDT. Bergantung pada nilai pemilih segmen , CPU akan berada dalam tingkat hak istimewa tertentu, ini adalah CPL (Tingkat Hak Istimewa Saat Ini). pemilih segmen menunjuk ke deskriptor segmen yang memiliki DPL (Descriptor Privilege Level), yang pada akhirnya menjadi CPL jika register segmen diisi dengan pemilih ini (setidaknya berlaku untuk pemilih segmen kode). Oleh karena itu, Anda memerlukan setidaknya sepasang pemilih segmen untuk membedakan kernel dari userland. Selain itu, segmen adalah segmen kode atau segmen data, sehingga Anda akhirnya mendapatkan empat deskriptor segmen di GDT.

  3. Saya tidak punya contoh OS serius yang menggunakan segmentasi, hanya karena segmentasi masih ada untuk kepatuhan mundur. Menggunakan pendekatan model datar hanyalah sarana untuk menghilangkannya. Lagi pula, Anda benar, paging jauh lebih efisien dan serbaguna, dan tersedia di hampir semua arsitektur (setidaknya konsepnya). Saya tidak dapat menjelaskan di sini paging internal, tetapi semua informasi yang perlu Anda ketahui ada di dalam orang Intel yang luar biasa:Intel® 64 dan IA-32 ArchitecturesSoftware Developer’s ManualVolume 3A:System Programming Guide, Part 1


Memperluas jawaban Benoit untuk pertanyaan 3...

Pembagian program menjadi bagian logis seperti kode, data konstan, data yang dapat dimodifikasi, dan tumpukan dilakukan oleh agen yang berbeda pada titik waktu yang berbeda.

Pertama, kompiler Anda (dan penghubung) membuat file yang dapat dieksekusi di mana divisi ini ditentukan. Jika Anda melihat sejumlah format file yang dapat dieksekusi (PE, ELF, dll), Anda akan melihat bahwa mereka mendukung beberapa jenis bagian atau segmen atau apa pun yang Anda ingin menyebutnya. Selain alamat dan ukuran serta lokasi di dalam file, bagian tersebut memiliki atribut yang memberi tahu OS tujuan dari bagian ini, mis. bagian ini berisi kode (dan inilah titik masuknya), ini - data konstan yang diinisialisasi, itu - data yang tidak diinisialisasi (biasanya tidak mengambil ruang dalam file), inilah sesuatu tentang tumpukan, di sana ada daftar dependensi (mis. DLL), dll.

Selanjutnya, saat OS mulai menjalankan program, ia mem-parsing file untuk melihat berapa banyak memori yang dibutuhkan program, di mana dan perlindungan memori apa yang diperlukan untuk setiap bagian. Yang terakhir biasanya dilakukan melalui tabel halaman. Halaman kode ditandai sebagai dapat dieksekusi dan hanya-baca, halaman data konstan ditandai sebagai tidak dapat dieksekusi dan hanya-baca, halaman data lainnya (termasuk tumpukan) ditandai sebagai tidak dapat dieksekusi dan baca-tulis. Beginilah seharusnya biasanya.

Seringkali program membutuhkan baca-tulis dan, pada saat yang sama, wilayah yang dapat dieksekusi untuk kode yang dihasilkan secara dinamis atau hanya untuk dapat memodifikasi kode yang ada. Akses RWX gabungan dapat ditentukan dalam file yang dapat dieksekusi atau diminta saat dijalankan.

Mungkin ada halaman khusus lainnya seperti halaman pelindung untuk perluasan tumpukan dinamis, mereka ditempatkan di sebelah halaman tumpukan. Misalnya, program Anda dimulai dengan halaman yang cukup dialokasikan untuk tumpukan 64KB dan kemudian ketika program mencoba mengakses di luar titik itu, OS mencegat akses ke halaman penjaga tersebut, mengalokasikan lebih banyak halaman untuk tumpukan (hingga ukuran maksimum yang didukung) dan memindahkan halaman penjaga lebih jauh. Halaman-halaman ini tidak perlu ditentukan dalam file yang dapat dieksekusi, OS dapat menanganinya sendiri. File seharusnya hanya menentukan ukuran tumpukan dan mungkin lokasinya.

Jika tidak ada perangkat keras atau kode di OS untuk membedakan memori kode dari memori data atau untuk menegakkan hak akses memori, pembagiannya sangat formal. Program DOS mode nyata 16-bit (COM dan EXE) tidak memiliki segmen kode, data, dan tumpukan yang ditandai dengan cara khusus. Program COM memiliki segalanya dalam satu segmen 64KB umum dan mereka mulai dengan IP=0x100 dan SP=0xFFxx dan urutan kode dan data bisa berubah-ubah di dalamnya, mereka bisa terjalin secara praktis dengan bebas. File DOS EXE hanya menentukan lokasi awal CS:IP dan SS:SP dan lebih dari itu, segmen kode, data, dan tumpukan tidak dapat dibedakan dengan DOS. Yang perlu dilakukan hanyalah memuat file, melakukan relokasi (hanya untuk EXE), menyiapkan PSP (Awalan Segmen Program, yang berisi parameter baris perintah dan beberapa info kontrol lainnya), memuat SS:SP dan CS:IP. Itu tidak dapat melindungi memori karena perlindungan memori tidak tersedia dalam mode alamat asli, sehingga format DOS 16-bit yang dapat dieksekusi sangat sederhana.


Linux
  1. Cara menggunakan BusyBox di Linux

  2. Cara Menggunakan Nginx untuk Mengarahkan

  3. Bagaimana Cara Menggunakan Halaman Man Untuk Mempelajari Cara Menggunakan Perintah?

  1. Cara menggunakan Perintah Su di Linux

  2. Kapan Menggunakan Nohup?

  3. Cara efektif menggunakan Halaman Man di Linux

  1. Mengapa Halaman Man Unix Menggunakan Double Backticks Di Tempat Dari Kutipan Ganda?

  2. Apakah Lebih Baik Menggunakan $(pwd) Atau $pwd?

  3. Linux – Penggunaan O_direct Di Linux?