Saat menelusuri “Keluaran dmesg” Saya dapat melihat daftar nilai yang tidak dapat saya pahami dengan baik.
Memory: 2047804k/2086248k available (3179k kernel code, 37232k reserved, 1935k data, 436k init, 1176944k highmem)
virtual kernel memory layout:
fixmap : 0xffc57000 - 0xfffff000 (3744 kB)
pkmap : 0xff800000 - 0xffa00000 (2048 kB)
vmalloc : 0xf7ffe000 - 0xff7fe000 ( 120 MB)
lowmem : 0xc0000000 - 0xf77fe000 ( 887 MB)
.init : 0xc0906000 - 0xc0973000 ( 436 kB)
.data : 0xc071ae6a - 0xc08feb78 (1935 kB)
.text : 0xc0400000 - 0xc071ae6a (3179 kB)
Dari nilai-nilai saya mengerti bahwa saya memiliki 2GB RAM (memori fisik). Tapi hal-hal lain tampaknya menjadi Angka Ajaib bagi saya.
Saya ingin tahu tentang masing-masing (fixmap, pkmap,.. dll.) secara singkat (jika lebih ragu, saya akan memposting masing-masing sebagai Pertanyaan terpisah)?
Bisakah seseorang menjelaskannya kepada saya?
Jawaban yang Diterima:
Pertama, sistem 32 bit memiliki 0xffffffff
(4'294'967'295
) alamat linier untuk mengakses lokasi fisik di atas RAM.
Kernel membagi alamat ini menjadi pengguna dan ruang kernel.
Ruang pengguna (memori tinggi) dapat diakses oleh pengguna dan, jika perlu, juga oleh kernel.
Rentang alamat dalam notasi hex dan dec:
0x00000000 - 0xbfffffff
0 - 3'221'225'471
Ruang kernel (memori rendah) hanya dapat diakses oleh kernel.
Rentang alamat dalam notasi hex dan dec:
0xc0000000 - 0xffffffff
3'221'225'472 - 4'294'967'295
Seperti ini:
0x00000000 0xc0000000 0xffffffff
| | |
+------------------------+----------+
| User | Kernel |
| space | space |
+------------------------+----------+
Jadi, tata letak memori yang Anda lihat di dmesg
sesuai dengan pemetaan alamat linier dalam ruang kernel.
Pertama, urutan .text, .data dan .init yang menyediakan inisialisasi tabel halaman kernel sendiri (menerjemahkan linear ke alamat fisik).
.text : 0xc0400000 - 0xc071ae6a (3179 kB)
Rentang tempat kode kernel berada.
.data : 0xc071ae6a - 0xc08feb78 (1935 kB)
Rentang tempat segmen data kernel berada.
.init : 0xc0906000 - 0xc0973000 ( 436 kB)
Rentang tempat tabel halaman awal kernel berada.
(dan 128 kB lainnya untuk beberapa struktur data dinamis.)
Ruang alamat minimal ini cukup besar untuk menginstal kernel di RAM dan untuk menginisialisasi struktur data intinya.
Ukuran yang digunakan ditampilkan di dalam tanda kurung, ambil contoh kode kernel:
0xc071ae6a - 0xc0400000 = 31AE6A
Dalam notasi desimal, yaitu 3'255'914
(3179 kB).
Kedua, penggunaan ruang kernel setelah inisialisasi
lowmem : 0xc0000000 - 0xf77fe000 ( 887 MB)
Rentang lowmem dapat digunakan oleh kernel untuk mengakses alamat fisik secara langsung.
Ini bukan 1 GB penuh, karena kernel selalu membutuhkan setidaknya 128 MB alamat linier untuk mengimplementasikan alokasi memori yang tidak bersebelahan dan alamat linier yang dipetakan secara fix .
vmalloc : 0xf7ffe000 - 0xff7fe000 ( 120 MB)
Alokasi memori virtual dapat mengalokasikan frame halaman berdasarkan skema noncontiguous. Keuntungan utama dari skema ini adalah untuk menghindari fragmentasi eksternal, ini digunakan untuk area swap, modul kernel atau alokasi buffer ke beberapa perangkat I/O.
pkmap : 0xff800000 - 0xffa00000 (2048 kB)
Pemetaan kernel permanen memungkinkan kernel untuk membuat pemetaan jangka panjang dari bingkai halaman dengan memori tinggi ke dalam ruang alamat kernel. Saat halaman HIGHMEM dipetakan menggunakan kmap(), alamat virtual ditetapkan dari sini.
fixmap : 0xffc57000 - 0xfffff000 (3744 kB)
Ini adalah alamat linier yang dipetakan tetap yang dapat merujuk ke alamat fisik apa pun di RAM, bukan hanya 1 GB terakhir seperti alamat lowmem. Alamat linier yang dipetakan dengan fix sedikit lebih efisien daripada rekan lowmem dan pkmap mereka.
Ada deskriptor tabel halaman khusus yang ditetapkan untuk pemetaan tetap, dan pemetaan halaman HIGHMEM menggunakan kmap_atomic dialokasikan dari sini.
Jika Anda ingin menyelam lebih dalam ke lubang kelinci:
Memahami Kernel Linux