Saya tertarik pada perbedaan antara Highmem dan Lowmem:
- Mengapa ada perbedaan seperti itu?
- Apa yang kita dapat dengan melakukannya?
- Fitur apa yang dimiliki masing-masing?
Saya tertarik pada perbedaan antara Highmem dan Lowmem:
Jawaban:
Pada arsitektur 32-bit, kisaran ruang alamat untuk mengatasi RAM adalah:
0x00000000 - 0xffffffff
atau 4'294'967'295
(4 GB).
Kernel linux membagi yang naik 3/1 (bisa juga 2/2, atau 1/3 1 ) menjadi ruang pengguna (memori tinggi) dan ruang kernel (memori rendah).
Rentang ruang pengguna:
0x00000000 - 0xbfffffff
Setiap proses pengguna yang baru lahir mendapatkan alamat (rentang) di dalam area ini. Proses pengguna umumnya tidak dipercaya dan karena itu dilarang mengakses ruang kernel. Lebih lanjut, mereka dianggap tidak mendesak, sebagai aturan umum, kernel mencoba menunda alokasi memori untuk proses-proses tersebut.
Kisaran ruang kernel:
0xc0000000 - 0xffffffff
Proses kernel mendapatkan alamatnya (rentang) di sini. Kernel dapat langsung mengakses 1 GB alamat ini (well, bukan 1 GB penuh, ada 128 MB yang disediakan untuk akses memori tinggi).
Proses yang muncul dalam ruang kernel dipercaya, mendesak dan dianggap bebas kesalahan, permintaan memori diproses secara instan.
Setiap proses kernel juga dapat mengakses rentang ruang pengguna jika diinginkan. Dan untuk mencapai hal ini, kernel memetakan alamat dari ruang pengguna (memori tinggi) ke ruang kernelnya (memori rendah), 128 MB yang disebutkan di atas khusus disediakan untuk ini.
1 Apakah pembagiannya adalah 3/1, 2/2, atau 1/3 dikontrol oleh CONFIG_VMSPLIT_...
opsi; Anda mungkin dapat memeriksa di bawah /boot/config*
untuk melihat opsi mana yang dipilih untuk kernel Anda.
Referensi pertama untuk beralih ke Linux Device Drivers (tersedia baik online dan dalam bentuk buku), khususnya bab 15 yang memiliki bagian pada topik.
Dalam dunia yang ideal, setiap komponen sistem akan dapat memetakan semua memori yang perlu diakses. Dan ini adalah kasus untuk proses di Linux dan sebagian besar sistem operasi: proses 32-bit hanya dapat mengakses memori virtual kurang dari 2 ^ 32 byte (sebenarnya sekitar 3GB pada arsitektur Linux 32-bit yang khas). Semakin sulit untuk kernel, yang harus dapat memetakan memori penuh dari proses yang sistemnya sebut sedang dieksekusi, ditambah seluruh memori fisik, ditambah perangkat keras yang dipetakan dengan memori lain.
Jadi ketika kernel 32-bit perlu memetakan lebih dari 4GB memori, itu harus dikompilasi dengan dukungan memori yang tinggi. Memori tinggi adalah memori yang tidak dipetakan secara permanen di ruang alamat kernel. (Memori rendah adalah kebalikannya: selalu dipetakan, sehingga Anda dapat mengaksesnya di kernel hanya dengan mendereferensi pointer.)
Ketika Anda mengakses memori tinggi dari kode kernel, Anda perlu menelepon kmap
terlebih dahulu, untuk mendapatkan pointer dari struktur data halaman ( struct page
). Memanggil kmap
berfungsi baik halaman dalam memori tinggi atau rendah. Ada juga kmap_atomic
yang menambahkan kendala tetapi lebih efisien pada mesin multiprosesor karena menggunakan penguncian yang lebih halus. Pointer yang didapat kmap
adalah resource: ia menggunakan ruang alamat. Setelah selesai, Anda harus menelepon kunmap
(atau kunmap_atomic
) untuk membebaskan sumber daya itu; maka pointer tidak lagi valid, dan konten halaman tidak dapat diakses sampai Anda menelepon kmap
lagi.
Ini relevan dengan kernel Linux; Saya tidak yakin bagaimana setiap kernel Unix menangani ini.
Memori Tinggi adalah segmen memori yang dapat ditangani oleh program ruang-pengguna. Itu tidak bisa menyentuh Memori Rendah.
Memori Rendah adalah segmen memori yang dapat ditangani oleh kernel Linux secara langsung. Jika kernel harus mengakses Memori Tinggi, ia harus memetakannya ke ruang alamatnya sendiri terlebih dahulu.
Ada tambalan yang diperkenalkan baru-baru ini yang memungkinkan Anda mengontrol di mana segmennya. Pengorbanannya adalah Anda dapat mengambil memori yang dapat dialamatkan dari ruang pengguna sehingga kernel dapat memiliki lebih banyak memori yang tidak harus dipetakan sebelum digunakan.
Sumber daya tambahan:
HIGHMEM adalah rentang ruang memori kernel, tetapi BUKAN memori yang Anda akses, tetapi ini adalah tempat di mana Anda meletakkan apa yang ingin Anda akses.
Peta memori virtual Linux 32bit yang khas adalah seperti:
0x00000000-0xbfffffff: proses pengguna (3GB)
0xc0000000-0xffffffff: ruang kernel (1GB)
(Vektor khusus CPU dan apa pun diabaikan di sini).
Linux membagi ruang kernel 1GB menjadi 2 bagian, LOWMEM dan HIGHMEM. Perpecahan bervariasi dari instalasi ke instalasi.
Jika suatu instalasi memilih, katakanlah, 512MB-512MB untuk mem RENDAH dan TINGGI, 512MB LOWMEM (0xc0000000-0xdfffffff) dipetakan secara statis pada saat boot kernel; biasanya begitu banyak byte pertama dari memori fisik digunakan untuk ini sehingga alamat virtual dan fisik dalam kisaran ini memiliki offset konstan, katakanlah, 0xc0000000.
Di sisi lain, 512MB yang terakhir (HIGHMEM) tidak memiliki pemetaan statis (walaupun Anda dapat meninggalkan halaman yang dipetakan secara semi-permanen di sana, tetapi Anda harus melakukannya secara eksplisit dalam kode driver Anda). Sebagai gantinya, halaman dipetakan sementara dan tidak dipetakan di sini sehingga alamat virtual dan fisik dalam rentang ini tidak memiliki pemetaan yang konsisten. Penggunaan umum dari HIGHMEM termasuk buffer data satu kali.
Banyak orang mengatakan bahwa memori rendah untuk sistem operasi. Ini biasanya benar tetapi tidak harus demikian. Memori tinggi dan memori rendah hanya dua bagian dari ruang memori, tetapi dalam sistem Linux, memori rendah hanya untuk kernel dan memori tinggi untuk proses pengguna.
Menurut "Buku Dinosaurus (konsep sistem operasi)", kita dapat menempatkan sistem operasi dalam memori rendah atau memori tinggi. Faktor utama yang mempengaruhi keputusan ini adalah lokasi vektor interupsi. Karena vektor interupsi sering dalam memori rendah, programmer biasanya juga menempatkan sistem operasi dalam memori rendah.