?? system.h
字號:
//// 切換到用戶模式運行。// 該函數利用iret 指令實現從內核模式切換到用戶模式(初始任務0)。#define move_to_user_mode() \__asm__ ( "movl %%esp,%%eax\n\t" \ /* 保存堆棧指針esp 到eax 寄存器中*/"pushl $0x17\n\t" \ /* 首先將堆棧段選擇符(SS)入棧*/"pushl %%eax\n\t" \ /* 然后將保存的堆棧指針值(esp)入棧*/"pushfl\n\t" \ /* 將標志寄存器(eflags)內容入棧*/"pushl $0x0f\n\t" \ /* 將內核代碼段選擇符(cs)入棧*/"pushl $1f\n\t" \ /* 將下面標號1 的偏移地址(eip)入棧*/"iret\n" \ /* 執行中斷返回指令,則會跳轉到下面標號1 處*/"1:\tmovl $0x17,%%eax\n\t" \ /* 此時開始執行任務0*/"movw %%ax,%%ds\n\t" \ /* 初始化段寄存器指向本局部表的數據段*/"movw %%ax,%%es\n\t" "movw %%ax,%%fs\n\t" "movw %%ax,%%gs":::"ax")#define sti() __asm__ ( "sti"::) /* 開中斷嵌入匯編宏函數*/#define cli() __asm__ ( "cli"::) /* 關中斷*/#define nop() __asm__ ( "nop"::) /* 空操作*/#define iret() __asm__ ( "iret"::) /* 中斷返回*///// 設置門描述符宏函數。// 參數:gate_addr -描述符地址;type -描述符中類型域值;dpl -描述符特權層值;addr -偏移地址。// %0 - (由dpl,type 組合成的類型標志字);%1 - (描述符低4 字節地址);// %2 - (描述符高4 字節地址);%3 - edx(程序偏移地址addr);%4 - eax(高字中含有段選擇符)。#define _set_gate(gate_addr,type,dpl,addr) \__asm__ ( "movw %%dx,%%ax\n\t" \ // 將偏移地址低字與選擇符組合成描述符低4 字節(eax)"movw %0,%%dx\n\t" \ // 將類型標志字與偏移高字組合成描述符高4 字節(edx)。"movl %%eax,%1\n\t" \ // 分別設置門描述符的低4 字節和高4 字節。"movl %%edx,%2"::"i" ((short) (0x8000 + (dpl << 13) + (type << 8))),"o" (*((char *) (gate_addr))),"o" (*(4 + (char *) (gate_addr))), "d" ((char *) (addr)), "a" (0x00080000))//// 設置中斷門函數。// 參數:n - 中斷號;addr - 中斷程序偏移地址。// &idt[n]對應中斷號在中斷描述符表中的偏移值;中斷描述符的類型是14,特權級是0。#define set_intr_gate(n,addr) \_set_gate(&idt[n],14,0,addr)//// 設置陷阱門函數。// 參數:n - 中斷號;addr - 中斷程序偏移地址。// &idt[n]對應中斷號在中斷描述符表中的偏移值;中斷描述符的類型是15,特權級是0。#define set_trap_gate(n,addr) \_set_gate(&idt[n],15,0,addr)//// 設置系統調用門函數。// 參數:n - 中斷號;addr - 中斷程序偏移地址。// &idt[n]對應中斷號在中斷描述符表中的偏移值;中斷描述符的類型是15,特權級是3。#define set_system_gate(n,addr) \_set_gate(&idt[n],15,3,addr)//// 設置段描述符函數。// 參數:gate_addr -描述符地址;type -描述符中類型域值;dpl -描述符特權層值;// base - 段的基地址;limit - 段限長。(參見段描述符的格式)#define _set_seg_desc(gate_addr,type,dpl,base,limit) {\*(gate_addr) = ((base) & 0xff000000) | \ // 描述符低4 字節。(((base) & 0x00ff0000) >> 16) |((limit) & 0xf0000) | ((dpl) << 13) | (0x00408000) | ((type) << 8);*((gate_addr) + 1) = (((base) & 0x0000ffff) << 16) | \ // 描述符高4 字節。((limit) & 0x0ffff);} //// 在全局表中設置任務狀態段/局部表描述符。 // 參數:n - 在全局表中描述符項n 所對應的地址;addr - 狀態段/局部表所在內存的基地址。 // type - 描述符中的標志類型字節。 // %0 - eax(地址addr);%1 - (描述符項n 的地址);%2 - (描述符項n 的地址偏移2 處); // %3 - (描述符項n 的地址偏移4 處);%4 - (描述符項n 的地址偏移5 處); // %5 - (描述符項n 的地址偏移6 處);%6 - (描述符項n 的地址偏移7 處); #define _set_tssldt_desc(n,addr,type) \ __asm__ ( "movw $104,%1\n\t" \ // 將TSS 長度放入描述符長度域(第0-1 字節)。 "movw %%ax,%2\n\t" \ // 將基地址的低字放入描述符第2-3 字節。 "rorl $16,%%eax\n\t" \ // 將基地址高字移入ax 中。 "movb %%al,%3\n\t" \ // 將基地址高字中低字節移入描述符第4 字節。 "movb $" type ",%4\n\t" \ // 將標志類型字節移入描述符的第5 字節。 "movb $0x00,%5\n\t" \ // 描述符的第6 字節置0。 "movb %%ah,%6\n\t" \ // 將基地址高字中高字節移入描述符第7 字節。 "rorl $16,%%eax" \ // eax 清零。 ::"a" (addr), "m" (*(n)), "m" (*(n + 2)), "m" (*(n + 4)), "m" (*(n + 5)), "m" (*(n + 6)), "m" (*(n + 7))) //// 在全局表中設置任務狀態段描述符。 // n - 是該描述符的指針;addr - 是描述符中的基地址值。任務狀態段描述符的類型是0x89。 #define set_tss_desc(n,addr) _set_tssldt_desc(((char *) (n)),addr, "0x89") //// 在全局表中設置局部表描述符。 // n - 是該描述符的指針;addr - 是描述符中的基地址值。局部表描述符的類型是0x82。 #define set_ldt_desc(n,addr) _set_tssldt_desc(((char *) (n)),addr, "0x82")
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -