Rumah  >  Artikel  >  Tutorial sistem  >  Memahami tindanan kernel proses Linux

Memahami tindanan kernel proses Linux

PHPz
PHPzke hadapan
2024-02-10 18:09:411242semak imbas

Apabila saya membaca semula "LDD3", saya mendapati ayat yang saya abaikan: "Inti mempunyai susunan yang sangat kecil, ia mungkin hanya sekecil halaman 4096 bait sebagai tindak balas kepada ayat ini, saya hanya Belajar tentang "tindanan kernel" proses.

Apakah "tindanan kernel" sesuatu proses? Dalam kitaran hayat setiap proses, ia pasti akan terperangkap dalam kernel melalui panggilan sistem. Selepas melaksanakan panggilan sistem dan memerangkap dalam kernel, timbunan yang digunakan oleh kod kernel ini bukanlah timbunan asal dalam ruang pengguna, tetapi timbunan dalam ruang kernel, yang merupakan "timbunan kernel" proses.

Sebagai contoh, pemandu watak ringkas melaksanakan open()方法。在这个驱动程序挂载后,应用程序通过glib库调用Linux的open()panggilan sistem. Apabila panggilan sistem dilaksanakan dan terperangkap dalam kernel, pemproses akan beralih kepada mod istimewa (mekanisme peralihan khusus berbeza-beza bergantung pada seni bina pemproses. Contohnya, untuk ARM, penuding tindanan (SP) dalam mod biasa dan mod pengguna adalah daftar yang berbeza). Pada masa ini, penuding tindanan yang digunakan ialah penuding tindanan kernel, yang menunjuk kepada ruang tindanan kernel yang diperuntukkan oleh kernel untuk setiap proses.

Peranan tindanan kernel Pemahaman peribadi saya ialah: selepas jatuh ke dalam kernel, terdapat juga panggilan fungsi dan pembolehubah automatik dalam panggilan sistem, yang memerlukan sokongan tindanan. Tindanan ruang pengguna jelas tidak selamat dan oleh itu memerlukan sokongan tindanan kernel. Selain itu, tindanan kernel juga digunakan untuk menyimpan beberapa maklumat lapisan aplikasi sebelum panggilan sistem (contohnya, penuding tindanan ruang pengguna dan parameter panggilan sistem).

Hubungan antara tindanan kernel dan struktur proses Setiap proses akan mendapat ruang tindanan kernel apabila ia dicipta. Surat-menyurat antara tindanan kernel dan proses diselesaikan melalui ahli penunjuk dalam dua struktur: (1) struct task_struct Struktur yang mesti dipelajari semasa mempelajari pengurusan proses Linux. Ia mewakili proses dalam kernel dan merekodkan semua maklumat status proses tersebut. Struktur ini ditakrifkan dalam Sched.h (includelinux). Ada ahli void *stack,它指向下面的内核栈结构体的“栈底”。 在系统运行时,宏current获得的是当前进程的struct task_structstruktur.

(2) Kesatuan struktur tindanan kernel benang_kesatuan

1. union thread_union {
2.   struct thread_info thread_info;
3.   unsigned long stack[THREAD_SIZE/sizeof(long)];
4. };

Struktur thread_info ialah struktur yang merekodkan sebahagian daripada maklumat proses, termasuk maklumat konteks proses:

1. /*
2.  \* low level task data that entry.S needs immediate access to.
3.  \* __switch_to() assumes cpu_context follows immediately after cpu_domain.
4.  */
5. struct thread_info {
6.   unsigned long    flags;    /* low level flags */
7.   int      preempt_count;  /* 0 => preemptable,  bug */
8.   mm_segment_t    addr_limit;  /* address limit */
9.   struct task_struct  *task;    /* main task structure */
10.   struct exec_domain  *exec_domain;  /* execution domain */
11.   __u32      cpu;    /* cpu */
12.   __u32      cpu_domain;  /* cpu domain */
13.   struct cpu_context_save  cpu_context;  /* cpu context */
14.   __u32      syscall;  /* syscall number */
15.   __u8      used_cp[16];  /* thread used copro */
16.   unsigned long    tp_value;
17.   struct crunch_state  crunchstate;
18.   union fp_state    fpstate __attribute__((aligned(8)));
19.   union vfp_state    vfpstate;
20. \#ifdef CONFIG_ARM_THUMBEE
21.   unsigned long    thumbee_state;  /* ThumbEE Handler Base register */
22. \#endif
23.   struct restart_block  restart_block;
24. };

Kuncinya ialah ahli tugas, yang menunjuk kepada struktur struktur_struktur bagi proses yang dibuat

Ahli tindanan ialah tindanan kernel. Ia boleh dilihat dari sini bahawa ruang tindanan kernel dan thread_info berkongsi ruang. Jika timbunan kernel melimpah, thread_info akan musnah dan sistem akan ranap~~~

Hubungan antara tindanan kernel—struct thread_info—struct task_struct ditunjukkan dalam rajah di bawah:

Memahami tindanan kernel proses Linux

Penjanaan tindanan kernel
Apabila proses dibuat, panggilan sistem keluarga fork akan memperuntukkan ruang untuk timbunan kernel dan struct task_struct masing-masing Proses panggilan ialah:

Fork panggilan sistem keluarga—>do_fork—>copy_process—>dup_task_struct

Dalam fungsi dup_task_struct:

1. static struct task_struct *dup_task_struct(struct task_struct *orig)
2. {
3.   struct task_struct *tsk;
4.   struct thread_info *ti;
5.   unsigned long *stackend;
6.  
7.   int err;
8.  
9.   prepare_to_copy(orig);
10.  
11.   **tsk = alloc_task_struct();**
12.   if (!tsk)
13. ​    return NULL;
14.  
15.   **ti = alloc_thread_info(tsk);**
16.   if (!ti) {
17. ​    free_task_struct(tsk);
18. ​    return NULL;
19.   }
20.  
21.    err = arch_dup_task_struct(tsk, orig);
22.   if (err)
23. ​    goto out;
24.  
25.   **tsk->stack = ti;**
26.  
27.   err = prop_local_init_single(&tsk->dirties);
28.   if (err)
29. ​    goto out;
30.  
31.   **setup_thread_stack(tsk, orig);**
32. ......

 

Alloc_task_struct menggunakan pengalokasi papak kernel untuk memperuntukkan ruang struct task_struct untuk proses yang akan dibuat
Alloc_thread_info menggunakan sistem rakan kongsi kernel untuk memperuntukkan ruang tindanan kernel (union thread_union) untuk proses yang akan dibuat

Nota: Pernyataan tsk->stack = ti; selepas
berkaitan dengan struct task_struct dan kernel stack
Dalam setup_thread_stack(tsk, orig);, susunan kernel dan struct task_struct dikaitkan:

1. static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
2. {
3.   *task_thread_info(p) = *task_thread_info(org);
4.   task_thread_info(p)->task = p;
5. }

Saiz tindanan kernel
Oleh kerana setiap proses diperuntukkan ruang tindanan kernel, adalah mustahil untuk memperuntukkan jumlah yang besar. Saiz ini bergantung kepada seni bina dan biasanya diukur dalam halaman. Sebenarnya, ini ialah THREAD_SIZE yang kita lihat di atas nilai ini biasanya 4K atau 8K. Untuk seni bina ARM, ini ditakrifkan dalam Thread_info.h (archarmincludeasm),

1. \#define THREAD_SIZE_ORDER  1
2. \#define THREAD_SIZE   8192
3. \#define THREAD_START_SP   (THREAD_SIZE - 8)

Jadi tindanan kernel ARM ialah 8KB

Perkara yang perlu diberi perhatian apabila pengaturcaraan (kernel) pemacu:
Disebabkan oleh had ruang tindanan, apabila menulis pemacu (terutamanya fungsi peringkat rendah yang digunakan oleh panggilan sistem), perhatian harus diberikan untuk mengelakkan kod yang menggunakan sejumlah besar ruang tindanan, seperti algoritma rekursif, saiz pembolehubah automatik setempat. definisi, dsb.

Atas ialah kandungan terperinci Memahami tindanan kernel proses Linux. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:lxlinux.net. Jika ada pelanggaran, sila hubungi admin@php.cn Padam