Pertanyaan Apakah mungkin untuk memetakan suatu proses ke dalam memori tanpa memetakan kernel?


Itu OSDev wiki mengatakan itu:

Ini tradisional dan umumnya baik untuk memetakan kernel Anda di setiap proses pengguna

Kenapa begitu? Tidak bisakah proses dipetakan ke memori semata-mata? Apa keuntungan dari pemetaan kernel dan bukankah itu membuang-buang ruang?

Juga, apakah mungkin untuk mengakses ruang kernel dari ruang pengguna dan mengapa saya melakukan itu?


4
2017-10-20 10:57


asal


Jawaban:


Ini tradisional dan umumnya baik untuk memetakan kernel Anda di setiap proses pengguna

Jadi ketika Anda membuat panggilan sistem, kernel tidak harus mengubah tabel halaman untuk mengakses memori itu sendiri. Memiliki semua memori fisik yang dipetakan sepanjang waktu membuatnya lebih murah untuk a read sistem panggilan untuk menyalin barang dari mana saja di pagecache, misalnya.

apakah mungkin untuk mengakses ruang kernel dari ruang pengguna dan mengapa saya melakukan itu?

Biasanya kernel akan menonaktifkan ini. Entri tabel halaman memiliki bit pengguna / supervisor yang mengontrol apakah dapat digunakan saat tidak dalam mode kernel (mis. ring 3, menurut saya). Kernel dengan demikian dapat meninggalkan memori yang dipetakan sementara masih melindunginya dari read / write oleh user-space. (Lihat juga ini untuk diagram peninggalan halaman direktori.)

CPU memiliki fitur kinerja untuk mendukung use case ini: ada bit "global" di setiap PTE yang (jika diset) berarti CPU dapat menyimpannya dalam cache di TLB bahkan ketika CR3 berubah (misalnya di seluruh konteks switch, ketika kernel menginstal tabel halaman baru). Kernel menetapkan ini untuk pemetaan kernel yang disertakan dalam setiap proses.

Dan BTW, mungkin hanya ada satu salinan fisik tabel untuk pemetaan kernel tersebut, dengan Page Map Level 4 Tabel tingkat atas (PML4) untuk setiap tabel halaman pengguna-halaman yang berbeda hanya dengan menunjuk ke struktur PDPTE kernel yang sama (sebagian besar / yang semuanya sebenarnya adalah 1GiB pemetaan hugepage, daripada pointer ke level entri lebih lanjut). Lihat diagram yang ditautkan di atas.


Sebenarnya ada sejumlah kecil memori yang memungkinkan kernel user-space untuk membaca (dan mengeksekusi): Kernel memetakan beberapa halaman 4k disebut area VDSO ke dalam ruang alamat dari setiap proses (di bagian paling atas dari memori virtual).

Untuk beberapa panggilan sistem sederhana namun umum seperti gettimeofday() dan getpid(), ruang-pengguna bisa call berfungsi di halaman-halaman ini (yang misalnya dijalankan rdtsc dan skala hasilnya dengan konstanta yang diekspor oleh kernel) daripada menggunakan syscall untuk masuk ke mode kernel dan melakukan hal yang sama di sana. Hal ini dapat menghemat 50 hingga 100 siklus clock untuk perjalanan ke mode kernel pada CPU x86 modern, dan lebih dari tidak perlu menyimpan / mengembalikan barang di dalam kernel sebelum mengirim ke sistem yang tepat.


Apakah mungkin untuk memetakan suatu proses ke dalam memori tanpa memetakan kernel?

Dengan proses 32-bit pada kernel 64-bit, seluruh ruang alamat virtual 4GiB tersedia untuk ruang-pengguna.  (Kecuali untuk 3 atau lebih 4k halaman VDSO.)

Sebaliknya (ketika alamat virtual pengguna-ruang sama lebar dengan alamat virtual kernel-space) Linux menggunakan setengah bagian atas untuk pemetaan kernel dari semua memori fisik (dengan 1G hugepages pada x86).

i386 Linux memiliki opsi konfigurasi untuk membuat split 1: 3, IIRC, kram lebih lanjut tetapi memungkinkan lebih banyak ruang alamat virtual untuk proses ruang-pengguna. IDK jika ini umum untuk kernel 32-bit pada arsitektur lain, atau hanya x86.

bukankah itu membuang-buang ruang?

Ini membutuhkan ruang alamat virtual, tetapi Anda seharusnya memiliki lebih dari itu daripada Anda melakukan memori fisik. Jika tidak, Anda harus membayar biaya kecepatan remapping memory lebih sering.

Inilah mengapa kami memiliki x86-64, jadi ruang alamat virtual besar sekali. 48 bit adalah 256 TiB, jadi setengahnya adalah 128 TiB dari ruang alamat. CPU masa depan dapat mengimplementasikan dukungan perangkat keras untuk alamat virtual yang lebih luas jika diperlukan / berguna. (Format tabel halaman mendukung hingga 52 bit alamat fisik.). Mungkin ini akan menjadi lebih banyak masalah dengan DIMM non-volatile yang menyediakan penyimpanan yang dipetakan memori dengan kepadatan yang lebih tinggi daripada DRAM, dan alasan untuk menggunakan banyak jenis ruang alamat.

Jika Anda membutuhkan lebih dari 2GiB ruang alamat virtual dalam satu proses, gunakan sistem 64-bit. (Atau jika Anda membutuhkan banyak sekali proses / thread, gunakan kernel 64-bit setidaknya. Sebuah kernel 32-bit dengan PAE mengalami masalah alokasi memori kadang-kadang. https://serverfault.com/ pertanyaan.)

Some one mem-posting ulang di blog mereka beberapa komentar Linus Torvalds tentang PAE (Physical Address Extensions) yang memungkinkan memiliki lebih dari 4GB memori fisik pada sistem x86 32-bit saja. Ringkasan: yuck, bahkan dengan implementasi sisi kernel yang bagus, itu pasti lebih lambat dari kernel 64-bit. Kecuali dengan penghinaan yang lebih lucu pada para insinyur Intel yang berpikir itu akan menjadi ide yang baik dan memecahkan masalah untuk OS 32-bit.


10
2017-10-20 11:34