核心版本:linux 0.11
函式呼叫:main.c第137行
函式定義:system.h第1到14行
#define move_to_user_mode() \
__asm__ ("movl %%esp,%%eax\n\t" \
"pushl $0x17\n\t" \
"pushl %%eax\n\t" \
"pushfl\n\t" \
"pushl $0x0f\n\t" \
"pushl $1f\n\t" \
"iret\n" \
"1:\tmovl $0x17,%%eax\n\t" \
"movw %%ax,%%ds\n\t" \
"movw %%ax,%%es\n\t" \
"movw %%ax,%%fs\n\t" \
"movw %%ax,%%gs" \
:::"ax")
由x86中斷和異常處理過程可知,特權級改變的中斷和異常呼叫,涉及堆疊切換,在當前堆疊中構建好中斷入棧時的資料:ss、esp、eflags、cs、eip。然後通過iret指令,就會自動彈出這些資料到各自位置,造成堆疊切換並且轉到我們定義的位置執行程式。
在linux裡面,涉及從特權級0轉到特權級3上面執行**,但是x86的設計不允許直接從特權級0跳轉到特權級3執行。就只能通過這種方式來實現我們的目的。
"pushl $0x17\n\t"
0x17=0b00010111,rpl=3,index=2,ti=1,從ldt表中取得第3項描述符,是乙個使用者資料段,ss指向這個段。
"pushl %%eax\n\t"
此時eax裡面存放當前的esp值,將之入棧
"pushfl\n\t"
將eflags入棧
"pushl $0x0f\n\t"
0x0f=0b00001111,rpl=3,index=1,ti=1,從ldt表中取得第2項描述符,是乙個使用者**段,cs指向這個段。
"pushl $1f\n\t" \
"iret\n" \
"1:\tmovl $0x17,%%eax\n\t" \
"movw %%ax,%%ds\n\t" \
"movw %%ax,%%es\n\t" \
"movw %%ax,%%fs\n\t" \
"movw %%ax,%%gs" \
將1位置的**指標入棧,自此,當執行iret之後,就會返回到cs和eip指定的**執行,其堆疊段ss和棧指標esp是上面手動構造的值。 linux核心研究2
獲取核心原始碼 www.kernel.org 核心原始碼樹 編譯與安裝核心 make xconfig make gconfig make make modules install 核心開發注意點 不能訪問c庫,只能訪問核心標頭檔案定義的函式,比如沒有printf,可以使用printk,使用方法差不多...
Linux核心學習筆記(3) 排程
排程 通過一系列排程策略,最大限度地利用處理器時間。1.什麼是處理器?cpu 2.什麼是時間片?分配給每個可執行程序的處理器時間段。3.程序排程程式 程序排程程式負責選擇下乙個要執行的程序,可看作在可執行態程序間分配有限的處理器時間資源的核心子系統。4.預設時間片設定 預設時間片的設定是一場博弈。若...
linux 核心 筆記
1 在i2c驅動模組中定義實際呼叫的函式 void read i2cinfo from proc void 2 在i2c模組 如i2c演算法驅動模組 初始化時建立乙個proc entry create proc read entry readi2cinfo 0,0,read i2cinfo from...