Apakah kernel memiliki fungsi main ()? [Tutup]


52

Saya belajar driver perangkat dan pemrograman Kernel. Menurut buku Jonathan Corbet, tidak ada main()fungsi di driver perangkat.

Jadi saya dua pertanyaan:

  • Mengapa kita tidak memerlukan main()fungsi di driver perangkat?
  • Apakah kernel itu sendiri memiliki main()fungsi?

Adakah yang bisa menjelaskan hal ini kepada saya?


1
Juga ditanya oleh pengguna yang sama di sini: stackoverflow.com/q/18266063/827263
Keith Thompson

@KeithThompson ... Ya ... Hanya karena saya tidak mendapatkan jawaban apa yang saya inginkan, maka saya bertanya di sini.
seseorang

@ Safad ... lagi pula sekarang hampir ditutup ... Dan saya tidak memiliki hak istimewa untuk memigrasikannya ...
seseorang

Ini seharusnya ditutup sebaliknya, yang ini memiliki lebih banyak pandangan :-)
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Jawaban:


82

Dalam program ruang pengguna, main()adalah titik masuk ke program yang dipanggil oleh kode inisialisasi libc ketika biner dijalankan. Kode kernel tidak memiliki kemewahan untuk bergantung pada libc, karena libc sendiri bergantung pada antarmuka syscall kernel untuk alokasi memori, I / O, manajemen proses dll.

Yang mengatakan, setara dengan main()dalam kode kernel adalah start_kernel(), yang dipanggil oleh bootloader setelah memuat gambar kernel, mendekompresinya ke dalam memori dan mengatur perangkat keras penting dan paging memori. start_kernel()melakukan sebagian besar pengaturan sistem dan akhirnya memunculkan proses init.

Titik masuk ke modul kernel Linux adalah fungsi init yang terdaftar dengan kernel dengan memanggil module_init()makro. Fungsi init modul terdaftar kemudian dipanggil oleh kode kernel melalui do_initcalls()fungsi tersebut saat startup kernel.


11
Terima kasih telah mengenali tujuan sebenarnya dari mainmetode dalam C. (Ini adalah kesalahpahaman yang terlalu umum bahwa OS membuat panggilan langsung ke main, yang bukan kasusnya dan bahkan lebih sedikit kasus dalam misalnya C ++.) I ' Aku akan memberimu upvote lagi jika aku bisa melakukannya.
CVn

1
@ Thomas ... Terima kasih atas jawaban yang luar biasa ini ....
seseorang

17

Kernel tidak memiliki mainfungsi. mainadalah konsep bahasa C. Kernel ditulis dalam C dan assembly. Kode entri kernel ditulis oleh majelis.

Urutan boot diatur sebagai berikut:

  1. BIOS biasanya memuat boot loader dari perangkat blok boot. Boot loader yang populer saat ini adalah grub.
  2. Grub memuat imej kernel ke dalam ram, dimungkinkan dengan perangkat root awal ( initrd). Kemudian kode di beberapa alamat dieksekusi.
  3. Citra kernel memiliki beberapa modul kernel, misalnya: modul sistem file, driver perangkat. Gambar kernel menggunakan modul sistem file untuk me-mount sistem file root. Sekarang kernel dapat memuat dan menjalankan semua modul kernel dari disk.
  4. Kernel menjalankan tugas inisialisasi. Misalnya: lintasi bus PCI dan temukan semua perangkat PCI, inisialisasi semua driver perangkat.
  5. Akhirnya kernel menciptakan proses 0 dan proses 1 ( initproses), mengalihkan konteks CPU dari dering 0 ke dering 3, dan memulai proses init (id proses adalah 1). Sekarang boot kernel sudah selesai!
  6. The initProgram berjalan semua skrip init. Semua layanan dimulai. Shell disebut. Pengguna bisa masuk.

The mainfungsi adalah fungsi C. Sebenarnya metode utama bukanlah titik masuk dari program C. C runtime memanggil banyak fungsi sebelumnya main. GCC memiliki fitur perluasan: konstruktor. Fungsi yang dinyatakan "konstruktor" dipanggil sebelumnya main.

Sebagai contoh:

/* This should not be used directly. Use block_init etc. instead. */ 
#define module_init(function, type) \
    static void _attribute__((constructor)) do_qemu_init ## function(void) { \
    register_module_init(function, type); \
} 

Makro ini dari proyek qemu.


Metode utama adalah metode ac. Sebenarnya metode utama bukanlah entri dari program c. Runtime C telah memanggil banyak metode sebelum metode utama.
Edward Shen

well, bios biasanya memuat bootloader, dan bootloader itu memuat image kernel (dan mungkin initrd). Kode kernel ada di dalam gambar kernel, bukan initrd
Stéphane Chazelas

GCC memiliki fitur perluasan: konstruktor. Deklarasi metode "konstruktor" dipanggil sebelum metode utama. Misalnya: / * Ini tidak boleh digunakan secara langsung. Gunakan block_init dll. Sebagai gantinya. * / #define module_init (fungsi, tipe) \ static void _attribute __ ((konstruktor)) do_qemu_init fungsi ## (void) {\ register_module_init (function, type); \}
Edward Shen

1
initrd.img BUKAN gambar kernel. Ini adalah satu set modul yang dimuat oleh kernel saat boot. Gambar kernel biasanya memiliki nama yang dimulai dengan "vmlinuz" tetapi berbeda dari distro ke distro.
goldilocks

3
Jawaban ini penuh dengan "semuanya adalah PC / Linux / i86" dan boot seperti itu dan kernel seperti itu ... Mengapa semua orang berpikir itu satu-satunya cara yang mungkin di dunia?
Jens

9

Ada misalnya fungsi utama () di arch / x86 / boot / main.c untuk mempersiapkan sistem untuk beralih dari mode real ke mode yang dilindungi tetapi arsitektur lain tidak memiliki kode seperti itu. Ada gambaran bagus tentang cara mem-boot kernel Linux 2.6.x pada platform x86. Sangat berharga untuk membacanya.

Menurut dokumen HOWTO melakukan pengembangan kernel Linux , kernel Linux adalah

lingkungan C yang berdiri sendiri, tanpa bergantung pada pustaka C standar, sehingga beberapa bagian dari standar C tidak didukung.

apa yang menurut standar C BTW artinya

Ini adalah implementasi-ditentukan apakah suatu program dalam lingkungan berdiri bebas diperlukan untuk mendefinisikan fungsi 'utama'.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.