當前位置:首頁 » 操作系統 » linux內核棧

linux內核棧

發布時間: 2023-05-25 16:21:16

linux為什麼需要內核棧,系統調用時直接使用用戶棧不行嗎

在空氣中噴出

❷ Linux內核中用戶空間棧和內核棧的區別

您好,很高興為您解答。

1.進程的堆棧

內核在創建進程的時候,在創建task_struct的同事,會為進程創建相應的堆棧。每個進程會有兩個棧,一個用戶棧,存在於用戶空間,一個內核棧,存在於內核空間。當進程在用戶空間運行時,cpu堆棧指針寄存器裡面的內容是用戶堆棧地址,使用用戶棧;當進程在內核空間時,cpu堆棧指針寄存器裡面的內容是內核棧空間地址,使用內核棧。

2.進程用戶棧和內核棧的切換

當進程因為中斷或者系統調用而陷入內核態之行時,進程所使用的堆棧也要從用戶棧轉到內核棧。

進程陷入內核態後,先把用戶態堆棧的地址保存在內核棧之中,然後設置堆棧指針寄存器的內容為內核棧的地址,這樣就完成了用戶棧向內核棧的轉換;當進程從內核態恢復到用戶態之行時,在內核態之行的最後將保存在內核棧裡面的用戶棧的地址恢復到堆棧指針寄存器即可。這樣就實現了內核棧和用戶棧的互轉。

那麼,我們知道從內核轉到用戶態時用戶棧的地址是在陷入內核的時候保存在內核棧裡面的,但是在陷入內核的時候,我們是如何知道內核棧的地址的呢?

關鍵在進程從用戶態轉到內核態的時候,進程的內核棧總是空的。這是因為,當進程在用戶態運行時,使用的是用戶棧,當進程陷入到內核態時,內核棧保存進程在內核態運行的相關信心,但是一旦進程返回到用戶態後,內核棧中保存的信息無效,會全部恢復,因此每次進程從用戶態陷入內核的時候得到的內核棧都是空的。所以在進程陷入內核的時候,直接把內核棧的棧頂地址給堆棧指針寄存器就可以了。

3.內核棧的實現

內核棧在kernel-2.4和kernel-2.6裡面的實現方式是不一樣的。

在kernel-2.4內核裡面,內核棧的實現是:

Uniontask_union{
Structtask_structtask;
Unsignedlongstack[INIT_STACK_SIZE/sizeof(long)];
};

其中,INIT_STACK_SIZE的大小隻能是8K。

內核為每個進程分配task_struct結構體的時候,實際上分配兩個連續的物理頁面,底部用作task_struct結構體,結構上面的用作堆棧。使用current()宏能夠訪問當前正在運行的進程描述符。

注意:這個時候task_struct結構是在內核棧裡面的,內核棧的實際能用大小大概有7K。

內核棧在kernel-2.6裡面的實現是(kernel-2.6.32):

Unionthread_union{
Structthread_infothread_info;
Unsignedlongstack[THREAD_SIZE/sizeof(long)];
};

其中THREAD_SIZE的大小可以是4K,也可以是8K,thread_info佔52bytes。

當內核棧為8K時,Thread_info在這塊內存的起始地址,內核棧從堆棧末端向下增長。所以此時,kernel-2.6中的current宏是需要更改的。要通過thread_info結構體中的task_struct域來獲得於thread_info相關聯的task。更詳細的參考相應的current宏的實現。

structthread_info{
structtask_struct*task;
structexec_domain*exec_domain;
__u32flags;
__u32status;
__u32cpu;
…..
};

注意:此時的task_struct結構體已經不在內核棧空間裡面了。


如若滿意,請點擊右側【採納答案】,如若還有問題,請點擊【追問】

希望我的回答對您有所幫助,望採納!

~ O(∩_∩)O~

❸ 請問linux內核的netfilter與內核的網路協議棧(我們網路編程經常用到的sock_packet)有什麼區別何聯系

看看相關書籍,查一下用戶手冊就行了。

❹ linux內核中內核局部變數過大不會導致棧溢出嗎

不會首先全局變數是不佔堆棧空間的
全局全量編譯的時侯是放在.data段的
只有沒有static修飾的局部變含空量在程序運行的時侯臨時分配在棧上,new,或malloc等定義的變數分配在堆上
如果想讓棧溢出也很容易,棧也有其極談猛瞎限的,只要定義一個無限遞歸函數,讓它沒完沒了的遞歸就行了,一會就崩了知改。
建議學一下編譯原理

❺ 進程內核棧,用戶棧及 Linux 進程棧和線程棧的區別

內核棧、用戶棧

32位Linux系統上,進程的地址空間為4G,包括1G的內核地址空間-----內核棧,和3G的用戶地址空間-----用戶棧。

內核棧,是各個進程在剛開始建立的時候通過內存映射共享的,但是每個進程擁有獨立的4G的虛擬內存空間從這一點看又是獨立的,互不幹擾的(只是剛開始大家都是映射的同一份內存拷貝)
用戶棧就是大家所熟悉的內存四區,包括:代碼區、全局數據區、堆區、棧區
用戶棧中的堆區、棧區即為進程堆、進程棧

進程堆、進程棧與線程棧

1.線程棧的空間開辟在所屬進程的堆區與共享內存區之間,線程與其所屬的進程共享進程的用戶空間,所以線程棧之間可以互訪。線程棧的起始地址和大小存放在pthread_attr_t 中,棧的大小並不是用來判斷棧是否越界,而是用來初始化避免棧溢出的緩沖區的大小(或者說安全間隙的大小)

2.進程初始化的時候,系統會在進程的地址空間中創建一個堆,叫進程默認堆。進程中所有的線程共用這一個堆。當然,可以增加1個或幾個堆,給不同的線程共同使用或單獨使用。----一個進程可以多個堆
3、創建線程的時候,系統會在進程的地址空間中分配1塊內存給線程棧,通常是1MB或4MB或8MB。線程棧是獨立的,但是還是可以互訪,因為線程共享內存空間

4.堆的分配:從操作系統角度來看,進程分配內存有兩種方式,分別由兩個系統調用完成:brk()和mmap(),glibc中malloc封裝了
5.線程棧位置-內存分布測試代碼

[cpp] view plain
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <malloc.h>
#include <sys/syscall.h>

void* func(void* arg)
{
long int tid = (long int)syscall(SYS_gettid);
printf("The ID of this thread is: %ld\n", tid );
static int a=10;
int b=11;
int* c=(int *)malloc(sizeof(int));
printf("in thread id:%u a:%p b:%p c:%p\n",tid,&a,&b,c);
printf("leave thread id:%ld\n",tid);
sleep(20);
free((void *)c);
}

void main()
{
pthread_t th1,th2;
printf("pid=%u\n",(int)getpid());
func(NULL);
int ret=pthread_create(&th1,NULL,func,NULL);
if(ret!=0)
{
printf("thread1[%d]:%s\n",th1,strerror(errno));
}
ret=pthread_create(&th2,NULL,func,NULL);
if(ret!=0)
{
printf("thread2[%d]:%s\n",th2,strerror(errno));
}
pthread_join(th1,NULL);
pthread_join(th2,NULL);
}
輸出:

[le@localhost threadStack]$ ./threadStack_main pid=16433
The ID of this thread is: 16433
in thread id:16433 a:0x60107c b:0x7fffc89ce7ac c:0x1b54010
leave thread id:16433
The ID of this thread is: 16461
The ID of this thread is: 16460
in thread id:16461 a:0x60107c b:0x7f6abb096efc c:0x7f6ab40008c0
leave thread id:16461
in thread id:16460 a:0x60107c b:0x7f6abb897efc c:0x7f6aac0008c0
leave thread id:16460
主線程調用func後
[le@localhost threadStack]$ sudo cat /proc/16433/maps
00400000-00401000 r-xp 00000000 fd:02 11666 /home/le/code/threadStack/threadStack_main
00600000-00601000 r--p 00000000 fd:02 11666 /home/le/code/threadStack/threadStack_main
00601000-00602000 rw-p 00001000 fd:02 11666 /home/le/code/threadStack/threadStack_main
01b54000-01b75000 rw-p 00000000 00:00 0 [heap]
7f6abb899000-7f6abba4f000 r-xp 00000000 fd:00 100678959 /usr/lib64/libc-2.17.so
7f6abba4f000-7f6abbc4f000 ---p 001b6000 fd:00 100678959 /usr/lib64/libc-2.17.so
7f6abbc4f000-7f6abbc53000 r--p 001b6000 fd:00 100678959 /usr/lib64/libc-2.17.so
7f6abbc53000-7f6abbc55000 rw-p 001ba000 fd:00 100678959 /usr/lib64/libc-2.17.so
7f6abbc55000-7f6abbc5a000 rw-p 00000000 00:00 0
7f6abbc5a000-7f6abbc70000 r-xp 00000000 fd:00 105796566 /usr/lib64/libpthread-2.17.so
7f6abbc70000-7f6abbe70000 ---p 00016000 fd:00 105796566 /usr/lib64/libpthread-2.17.so
7f6abbe70000-7f6abbe71000 r--p 00016000 fd:00 105796566 /usr/lib64/libpthread-2.17.so
7f6abbe71000-7f6abbe72000 rw-p 00017000 fd:00 105796566 /usr/lib64/libpthread-2.17.so
7f6abbe72000-7f6abbe76000 rw-p 00000000 00:00 0
7f6abbe76000-7f6abbe97000 r-xp 00000000 fd:00 105796545 /usr/lib64/ld-2.17.so
7f6abc073000-7f6abc076000 rw-p 00000000 00:00 0
7f6abc095000-7f6abc097000 rw-p 00000000 00:00 0
7f6abc097000-7f6abc098000 r--p 00021000 fd:00 105796545 /usr/lib64/ld-2.17.so
7f6abc098000-7f6abc099000 rw-p 00022000 fd:00 105796545 /usr/lib64/ld-2.17.so
7f6abc099000-7f6abc09a000 rw-p 00000000 00:00 0
7fffc89b0000-7fffc89d1000 rw-p 00000000 00:00 0 [stack]
7fffc89fe000-7fffc8a00000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]

兩個子線程啟動後
[le@localhost threadStack]$ sudo cat /proc/16433/maps
00400000-00401000 r-xp 00000000 fd:02 11666 /home/le/code/threadStack/threadStack_main
00600000-00601000 r--p 00000000 fd:02 11666 /home/le/code/threadStack/threadStack_main
00601000-00602000 rw-p 00001000 fd:02 11666 /home/le/code/threadStack/threadStack_main
01b54000-01b75000 rw-p 00000000 00:00 0 [heap]
7f6aac000000-7f6aac021000 rw-p 00000000 00:00 0
7f6aac021000-7f6ab0000000 ---p 00000000 00:00 0
7f6ab4000000-7f6ab4021000 rw-p 00000000 00:00 0
7f6ab4021000-7f6ab8000000 ---p 00000000 00:00 0
7f6aba897000-7f6aba898000 ---p 00000000 00:00 0
7f6aba898000-7f6abb098000 rw-p 00000000 00:00 0 [stack:16461]
7f6abb098000-7f6abb099000 ---p 00000000 00:00 0
7f6abb099000-7f6abb899000 rw-p 00000000 00:00 0 [stack:16460]
7f6abb899000-7f6abba4f000 r-xp 00000000 fd:00 100678959 /usr/lib64/libc-2.17.so
7f6abba4f000-7f6abbc4f000 ---p 001b6000 fd:00 100678959 /usr/lib64/libc-2.17.so
7f6abbc4f000-7f6abbc53000 r--p 001b6000 fd:00 100678959 /usr/lib64/libc-2.17.so
7f6abbc53000-7f6abbc55000 rw-p 001ba000 fd:00 100678959 /usr/lib64/libc-2.17.so
7f6abbc55000-7f6abbc5a000 rw-p 00000000 00:00 0
7f6abbc5a000-7f6abbc70000 r-xp 00000000 fd:00 105796566 /usr/lib64/libpthread-2.17.so
7f6abbc70000-7f6abbe70000 ---p 00016000 fd:00 105796566 /usr/lib64/libpthread-2.17.so
7f6abbe70000-7f6abbe71000 r--p 00016000 fd:00 105796566 /usr/lib64/libpthread-2.17.so
7f6abbe71000-7f6abbe72000 rw-p 00017000 fd:00 105796566 /usr/lib64/libpthread-2.17.so
7f6abbe72000-7f6abbe76000 rw-p 00000000 00:00 0
7f6abbe76000-7f6abbe97000 r-xp 00000000 fd:00 105796545 /usr/lib64/ld-2.17.so
7f6abc073000-7f6abc076000 rw-p 00000000 00:00 0
7f6abc095000-7f6abc097000 rw-p 00000000 00:00 0
7f6abc097000-7f6abc098000 r--p 00021000 fd:00 105796545 /usr/lib64/ld-2.17.so
7f6abc098000-7f6abc099000 rw-p 00022000 fd:00 105796545 /usr/lib64/ld-2.17.so
7f6abc099000-7f6abc09a000 rw-p 00000000 00:00 0
7fffc89b0000-7fffc89d1000 rw-p 00000000 00:00 0 [stack]
7fffc89fe000-7fffc8a00000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]

❻ linux進程為什麼有用戶棧和內核棧,

linux下的cpu有兩個狀態:內核態和用戶態,內核態的cpu的許可權高於用戶態下的cpu。
linux下的內存分為用戶態內存和內核態內存,一般4個G內存,3個G的分給用戶態,1個G分給內核態。
linux進程有時需要調用內核資源時,如讀寫文件,io讀寫等,這時候是通過系統調用實現對內核資源的訪問的,在訪問內核資源前是用戶棧,經過系統調用進入到內核態時,cpu的狀態也由用戶態變為內核態,訪問的內存就是內核態下管理的內存了-內核棧,對內核里的資源訪問完返回,內存又回到了用戶棧,cpu也回到用戶態。

❼ linux 線程默認棧多大

linux的線程棧大小可以使用ulimit -s查看,對於ubuntu 2.6的內核線程棧的默認大小為8M

熱點內容
scratch少兒編程課程 發布:2025-04-16 17:11:44 瀏覽:642
榮耀x10從哪裡設置密碼 發布:2025-04-16 17:11:43 瀏覽:368
java從入門到精通視頻 發布:2025-04-16 17:11:43 瀏覽:88
php微信介面教程 發布:2025-04-16 17:07:30 瀏覽:310
android實現陰影 發布:2025-04-16 16:50:08 瀏覽:794
粉筆直播課緩存 發布:2025-04-16 16:31:21 瀏覽:346
機頂盒都有什麼配置 發布:2025-04-16 16:24:37 瀏覽:213
編寫手游反編譯都需要學習什麼 發布:2025-04-16 16:19:36 瀏覽:818
proteus編譯文件位置 發布:2025-04-16 16:18:44 瀏覽:367
土壓縮的本質 發布:2025-04-16 16:13:21 瀏覽:594