Dalam tautan berikut saya memiliki kode berikut:

static int run_init_process(const char *init_filename)
{
    argv_init[0] = init_filename;
    return do_execve(getname_kernel(init_filename),
        (const char __user *const __user *)argv_init,
        (const char __user *const __user *)envp_init);
}

Dan dikatakan sebagai berikut:

Di sini kita dapat melihat bahwa kernel_init -> run_init_process -> do_execve, yang sama dengan syscall eksekutif biasa, argumennya adalah biner init.

Saya mencoba memahami perbedaan antara do_execve() dan execve(). Mengapa tidak menggunakan execve() saja?

1
vesii 25 Mei 2020, 19:30

1 menjawab

Jawaban Terbaik

Ruang pengguna berkomunikasi dengan ruang kernel menggunakan syscalls. Baik "spasi" - userspace dan kernelspace - dapat dianggap sebagai program terpisah yang berkomunikasi satu sama lain menggunakan register dan interupsi.

execve() adalah fungsi POSIX standar yang diekspos oleh operasi sistem ke program C. Ini harus diimplementasikan oleh implementasi library standar Anda, kemungkinan besar Anda menggunakan glibc. Di Linux sebagian besar fungsi POSIX cocok dengan nama syscalls, jadi glibc cukup menerapkan pembungkus tipis di sekitar syscall.

Ketika syscall dipanggil dari program userspace, parameter disimpan pada register dan interupsi dipicu. Itu menghentikan eksekusi program userspace dan eksekusi berlanjut di ruang kernel.

Kernel mengambil parameter dari register userspace dan menjalankan fungsi yang harus menangani syscall. Sebagian besar fungsi yang menangani syscall diberi nama do_<syscall> di kernel. Fungsi do_execve() hanyalah fungsi yang digunakan kernel untuk menangani panggilan sys execve() dari ruang pengguna.

Mengapa tidak menggunakan execve saja?

Mengapa memanggil panggilan sistem ketika Anda sudah berada di ruang kernel? Panggil saja fungsi yang akan menangani panggilan sistem.

2
red0ct 26 Mei 2020, 09:40