青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆-80  評論-24  文章-0  trackbacks-0
上一篇日志主要講解了對8259A以及中斷向量表的初始化。
下面的程序主要是時鐘中斷、硬盤中斷以及系統調用入口函數的實現。

  1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2 ; 每個進程的內核態堆棧頂部棧幀應該是這樣的
  3 ; ss
  4 ; esp
  5 ; eflags
  6 ; cs
  7 ; eip
  8 ; eax
  9 ; ecx
 10 ; edx
 11 ; ebx
 12 ; ebp
 13 ; esi
 14 ; edi
 15 ; ds
 16 ; es
 17 ; fs
 18 ; gs
 19 ; 其中ss、esp、eflags、cs、eip是在發生中斷時CPU自動壓棧的
 20 ; 而其他的是由中斷程序壓棧的,這個順序不能改變,否則后果自負
 21 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 22 
 23 CS_OFFSET    equ 0x30
 24 ESP_OFFSET    equ 0x38
 25 SS_OFFSET    equ 0x3c
 26 
 27 ; 一個宏,因為所有的irq中斷函數都是先保存現場并將數據段等堆棧段
 28 ; 切換到內核態,因此,該操作所有的irq中斷入口函數均相同
 29 ; 故寫成宏節省空間^_!
 30 %macro save_all 0
 31     push eax
 32     push ecx
 33     push edx
 34     push ebx
 35     push ebp
 36     push esi
 37     push edi
 38     push ds
 39     push es
 40     push fs
 41     push gs
 42     mov si, ss
 43     mov ds, si
 44     mov es, si
 45     mov gs, si
 46     mov fs, si
 47 %endmacro
 48 
 49 ; 一個宏,恢復現場
 50 %macro recover_all 0
 51     pop gs
 52     pop fs
 53     pop es
 54     pop ds
 55     pop edi
 56     pop esi
 57     pop ebp
 58     pop ebx
 59     pop edx
 60     pop ecx
 61     pop eax
 62 %endmacro
 63 
 64 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 65 ; 時鐘中斷處理程序
 66 ; 這是整個系統中最要求“速度快”的程序,因為時鐘中斷沒隔1/HZ(s)
 67 ; 就發生一次,大概它是整個系統調用最頻繁的函數,所以需要該函數
 68 ; 盡量短,沒有必要的函數調用盡量避免。
 69 ; 另外判斷中斷重入minix和linux采取的方法也是不一樣的,minix采用
 70 ; 一個全局變量,類似于信號量的概念;而linux的方法則比較簡單,它
 71 ; 直接獲取存儲在內核堆棧中的cs段寄存器的RPL值來判斷被中斷的程序
 72 ; 是內核態程序的還是用戶態的進程;我們打算采用linux的辦法,雖然
 73 ; minix方法更酷,但是linux的顯然更加簡單:)
 74 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 75 int_clock:
 76     save_all
 77     ; 增加心跳數
 78     inc dword [boot_heartbeat]
 79 
 80     ; 發送EOI指令結束本次中斷
 81     mov ax, 0x20
 82     out 0x20, al
 83     sti
 84     
 85     mov eax, [esp + CS_OFFSET]
 86     and eax, 0x03
 87     cmp eax, 0x0 ; 如果CS段寄存器的RPL為0,則說明是由內核態進入時鐘中斷,則是中斷重入
 88     je return
 89     call pre_schedule
 90 return:
 91     recover_all
 92     iretd
 93 
 94 int_keyboard:
 95     save_all
 96 
 97     recover_all
 98     iretd
 99 
100 int_serial_port2:
101     save_all
102 
103     recover_all
104     iretd
105 
106 int_serial_port1:
107     save_all
108 
109     recover_all
110     iretd
111 
112 int_lpt2:
113     save_all
114 
115     recover_all
116     iretd
117 
118 int_floppy:
119     save_all
120 
121     recover_all
122     iretd
123 
124 int_lpt1:
125     save_all
126 
127     recover_all
128     iretd
129 
130 int_rtc:
131     save_all
132 
133     recover_all
134     iretd
135 
136 int_ps_2_mouse:
137     save_all
138 
139     recover_all
140     iretd
141 
142 int_fpu_fault:
143     save_all
144 
145     recover_all
146     iretd
147 
148 ;硬盤中斷處理程序
149 int_at_win:
150     save_all
151 
152     mov byte [gs:0xb8006], 'e'; 試驗硬盤中斷是否成功:)
153 
154     ; 發送EOI指令給從8259A結束本次中斷
155     mov ax, 0x20
156     out 0xa0, al
157     nop
158     nop
159     ; 發送EOI指令給主8259A結束本次中斷
160     out 0x20, al
161     nop
162     nop
163 
164     ; 調用該函數使buf_info緩沖區生效
165     call validate_buffer
166 
167     recover_all
168     iretd
169 
170 ; 默認的中斷處理函數,所有的未定義中斷都會調用此函數
171 int_default:
172     save_all
173     recover_all
174     iretd
175 
176 ; 注意從系統調用返回時不需要從棧中彈出eax的值,因為eax保存著調用
177 ; 對應系統調用之后的返回值
178 %macro recover_from_sys_call 0
179     pop gs
180     pop fs
181     pop es
182     pop ds
183     pop edi
184     pop esi
185     pop ebp
186     pop ebx
187     pop edx
188     pop ecx
189     add esp, 4 * 1
190 %endmacro
191 
192 ; 系統調用框架,系統調用采用0x30號中斷向量,利用int 0x30指令產
193 ; 生一個軟中斷,之后便進入sys_call函數,該函數先調用save_all框
194 ; 架保存所有寄存器值,然后調用對應系統調用號的入口函數完成系統調用
195 ; 注意!!!!!系統調用默認有三個參數,分別利用ebx、ecx、edx來
196 ; 傳遞,其中eax保存系統調用號
197 sys_call:
198     save_all
199 
200     sti
201 
202     push ebx
203     push ecx
204     push edx
205     call [sys_call_table + eax * 4]
206     add esp, 4 * 3
207 
208     recover_from_sys_call
209 
210     cli
211 
212     iretd
213 

目前不打算對時鐘中斷處理函數、硬盤中斷處理函數以及系統調用入口框架做解釋,因為后序部分將會專門分章節進行講解。這里只說在發生類似時鐘中斷、硬盤中斷以及軟中斷int X的系統調用時,CPU如何處理的。
初始情況下假設CPU正在用戶態執行某一個進程a,此時的CS、DS、ES、FS、SS均指向用戶態進程a的段基地址。
當時鐘中斷等中斷抑或int X的系統調用到來的時候,CPU會自動從TSS中尋找用戶態進程a預先保存的ring0下的SS0和ESP0,然后將SS和ESP寄存器值轉換成SS0和ESP0,即切換到核心態堆棧段(注意,每個進程都可能會有一個自己獨立的ring0堆棧段,這樣可以更好的實現進程切換時對內核態的保護,linux對此的做法是在創建一個進程的時候在進程頁的末尾申請一塊空間作為該進程對應的ring0堆棧段),然后將用戶態下的SS、ESP、EFLAGS、CS、EIP的值保存在新的SS0:ESP0堆棧段中。注意以上過程都是CPU自動完成的,然后再通過save_all宏手工將eax、ecx、edx、ebx、ebp、esi、edi、ds、es、fs、gs壓入堆棧,然后再執行相應的中斷處理程序。完成之后會通過recover_all再按序恢復所有的常規寄存器。然后調用iretd命令從堆棧中彈出EIP、CS、EFLAGS、ESP、SS寄存器,然后再重新恢復進程a的運行。這一過程需要對GDT、IDT、TSS以及保護模式下的中斷門、陷阱門有所了解才可以。
不過還有一種情況此處沒有涉及:當發生進程切換的時候現場保護與恢復的過程如何呢?這一過程將在后面敘述。

  1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2 ; 以下為庫函數
  3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  4 
  5 ; 對端口進行寫操作
  6 void out_byte(unsigned short port, unsigned char value);
  7 out_byte:
  8     mov edx, [esp + 4 * 1]
  9     mov al, [esp + 4 * 2]
 10     out dx, al
 11     nop
 12     nop
 13     ret
 14 
 15 ; 對端口進行讀操作
 16 ; uint8 in_byte(unsigned short port);
 17 in_byte:
 18     mov edx, [esp + 4 * 1]
 19     xor eax, eax
 20     in al, dx
 21     nop
 22     nop
 23     ret
 24 
 25 ; 對從指定端口進行讀操作,讀出的n個字節數據放入buf緩沖區中
 26 void read_port(uint16 port, void* buf, int n);
 27 read_port:
 28     mov    edx, [esp + 4 * 1]    ; port
 29     mov    edi, [esp + 4 * 2]    ; buf
 30     mov    ecx, [esp + 4 * 3]    ; n
 31     shr    ecx, 1
 32     cld
 33     rep    insw
 34     ret
 35 
 36 ; 對從指定端口進行寫操作,數據源在buf緩沖區中,寫n個字節
 37 void write_port(uint16 port, void* buf, int n);
 38 write_port:
 39     mov    edx, [esp + 4 * 1]    ; port
 40     mov    edi, [esp + 4 * 2]    ; buf
 41     mov    ecx, [esp + 4 * 3]    ; n
 42     shr    ecx, 1
 43     cld
 44     rep    outsw
 45     ret
 46 
 47 ; 安裝指定中斷號的中斷處理程序
 48 extern int install_int_handler(uint8 INT_IV, void* handler);
 49 install_int_handler:
 50     mov eax, [esp + 4 * 1] ; 中斷向量號
 51     mov ebx, [esp + 4 * 2] ; 中斷程序入口
 52     cmp eax, 256
 53     jae failed
 54     cmp eax, 0
 55     jbe failed
 56     push PRIVILEGE_KERNEL
 57     push ebx
 58     push INT_GATE_386
 59     push eax
 60     call init_idt
 61     add esp, 4 * 4
 62 failed:
 63     ret
 64     
 65 ; 卸載指定中斷號的中斷處理程序
 66 extern int uninstall_int_handler(uint8 INT_IV);
 67 uninstall_int_handler:
 68     mov eax, [esp + 4 * 1] ; 中斷向量號
 69     cmp eax, 256
 70     jae failed
 71     cmp eax, 0
 72     jbe failed
 73     push PRIVILEGE_KERNEL
 74     push int_default
 75     push INT_GATE_386
 76     push eax
 77     call init_idt
 78     add esp, 4 * 4
 79     ret
 80     
 81 ; 安裝指定中斷號的系統調用入口
 82 extern int install_sys_call_handler(uint8 INT_IV, void* handler);
 83 install_sys_call_handler:
 84     mov eax, [esp + 4 * 1] ; 中斷向量號
 85     mov ebx, [esp + 4 * 2] ; 中斷程序入口
 86     cmp eax, 256
 87     jae failed_inst_sys
 88     cmp eax, 0
 89     jbe failed_inst_sys
 90     push PRIVILEGE_USER
 91     push ebx
 92     push INT_TRAP_386
 93     push eax
 94     call init_idt
 95     add esp, 4 * 4
 96 failed_inst_sys:
 97     ret
 98 
 99 ; 打開對應向量號的硬件中斷
100 ; 注意,這里傳入的參數是硬件中斷對應的中斷向量號
101 ; 需要將該中斷向量號轉化為在8259A上的索引號
102 void enable_hwint(uint8 IV);
103 enable_hwint:
104     mov ecx, [esp + 4 * 1]
105     cmp cl, IRQ0_IV
106     jae master_1
107     jmp ret_1
108 master_1:
109     cmp cl, IRQ8_IV
110     jae slave_1
111     push MASTER_CTL_MASK_8259
112     call in_byte
113     add esp, 4 * 1
114     sub cl, IRQ0_IV
115     mov bl, 1
116     shl bl, cl
117     xor bl, 0xff
118     and al, bl
119     push eax
120     push MASTER_CTL_MASK_8259
121     call out_byte
122     add esp, 4 * 2
123     jmp ret_1
124 slave_1:
125     cmp cl, IRQ15_IV
126     ja ret_1
127     push SLAVE_CTL_MASK_8259
128     call in_byte
129     add esp, 4 * 1
130     sub cl, IRQ8_IV
131     mov bl, 1
132     shl bl, cl
133     xor bl, 0xff
134     and al, bl
135     push eax
136     push SLAVE_CTL_MASK_8259
137     call out_byte
138     add esp, 4 * 2
139 ret_1:
140     ret
141 
142 ; 關閉對應向量號的硬件中斷
143 ; 注意,這里傳入的參數是硬件中斷對應的中斷向量號
144 ; 需要將該中斷向量號轉化為在8259A上的索引號
145 void disable_hwint(uint8 IV);
146 disable_hwint:
147     mov ecx, [esp + 4 * 1]
148     cmp cl, IRQ0_IV
149     jae master_2
150     jmp ret_2
151 master_2:
152     cmp cl, IRQ8_IV
153     jae slave_2
154     push MASTER_CTL_MASK_8259
155     call in_byte
156     add esp, 4 * 1
157     sub cl, IRQ0_IV
158     mov bl, 1
159     shl bl, cl
160     or al, bl
161     push eax
162     push MASTER_CTL_MASK_8259
163     call out_byte
164     add esp, 4 * 2
165     jmp ret_2
166 slave_2:
167     cmp cl, IRQ15_IV
168     ja ret_2
169     push SLAVE_CTL_MASK_8259
170     call in_byte
171     add esp, 4 * 1
172     sub cl, IRQ8_IV
173     mov bl, 1
174     shl bl, cl
175     or al, bl
176     push eax
177     push SLAVE_CTL_MASK_8259
178     call out_byte
179     add esp, 4 * 2
180 ret_2:
181     ret
182 
183 [SECTION .data]
184 idt:
185         ; idt表共可存放256個中斷門描述符
186         times 256 * 8 db 0
187 
188 idtr:    dw $ - idt - 1
189         dd idt
190 

上面這段函數比較簡單,是一些庫函數,主要包括對端口進行讀、寫操作;以及安裝或者卸載中斷處理程序,方法就是通過接受中斷號,將IDT中對應的中斷描述符置空或初始化;還有安裝系統調用,安裝系統調用和安裝中斷處理程序幾乎相同,唯一的區別就是門描述符的類型以及門描述符的特權級不同,中斷處理程序是中斷門,對應的門描述符DPL為0,系統調用是陷阱門,對應的DPL為3,這是因為中斷門只需要檢查CPL>=處理程序的DPL,而陷阱門除了檢查該條件以外還檢查CPL<=陷阱門描述符的DPL。這樣做的原因是陷阱門是由程序引起的,諸如系統調用之類的,需要從程序中跳入;而中斷是硬件引起的。
再后面函數就是打開或關閉8259A上的硬件中斷。

關于init.s文件的描述就到此為止。之后還會對進程切換做進一步的闡釋。
posted on 2012-02-14 01:06 myjfm 閱讀(543) 評論(0)  編輯 收藏 引用 所屬分類: 操作系統
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲欧洲在线看| 欧美精品免费在线观看| 一本色道久久综合一区| 久久精品免费电影| 亚洲欧美国产毛片在线| 免费观看在线综合| 久久综合亚州| 国产欧美视频一区二区| 中文精品一区二区三区| 亚洲日韩第九十九页| 久久久久久电影| 久久久久一区| 国产人妖伪娘一区91| 亚洲图片欧美午夜| 亚洲少妇最新在线视频| 欧美美女操人视频| 亚洲国产欧美精品| 亚洲国产成人一区| 久久亚洲欧美| 欧美成人r级一区二区三区| 国产一区二区成人久久免费影院| 一区二区高清在线观看| 在线亚洲电影| 欧美性一区二区| 一本大道久久a久久综合婷婷| 在线视频免费在线观看一区二区| 欧美精品免费看| 99国产精品视频免费观看一公开| 一区二区三区久久精品| 欧美性一区二区| 亚洲欧美成人网| 久久久精品国产一区二区三区| 国产欧美日韩另类视频免费观看| 亚洲综合色在线| 久久久久久久久久久一区| 狠狠色狠狠色综合日日91app| 久久狠狠婷婷| 欧美激情视频网站| 在线视频你懂得一区| 国产精品成人av性教育| 亚洲欧美国产77777| 久久综合精品一区| 亚洲国语精品自产拍在线观看| 欧美国产精品人人做人人爱| 亚洲美女啪啪| 久久国产欧美精品| 亚洲第一福利视频| 欧美精品在线观看91| 亚洲一区二区av电影| 久久免费精品日本久久中文字幕| 亚洲黄色小视频| 国产精品久久久久久超碰| 午夜欧美不卡精品aaaaa| 欧美丰满少妇xxxbbb| 在线视频欧美精品| 国产在线欧美| 欧美日韩黄色一区二区| 亚洲欧美另类久久久精品2019| 欧美va天堂va视频va在线| 9i看片成人免费高清| 国产日韩精品久久| 欧美成人中文字幕| 亚洲影视在线播放| 亚洲高清一区二| 欧美一区二区高清| 亚洲精品一区二| 国产在线精品一区二区中文| 欧美精品一区二区三区久久久竹菊 | 国产精品人成在线观看免费| 久久嫩草精品久久久精品| 亚洲免费av网站| 免费人成网站在线观看欧美高清| 在线综合亚洲欧美在线视频| 伊人春色精品| 国产精品劲爆视频| 欧美第一黄色网| 久久激情视频免费观看| 一本色道久久综合亚洲精品不卡| 免费日韩成人| 久久精品亚洲一区二区三区浴池| 一本色道**综合亚洲精品蜜桃冫| 黄色日韩在线| 国产日韩亚洲| 国产精品电影网站| 欧美精品一区二区三区视频| 久久夜色精品国产| 欧美一级理论性理论a| 一区二区日韩精品| 日韩一区二区精品| 亚洲经典三级| 亚洲国产高清高潮精品美女| 巨乳诱惑日韩免费av| 久久国产主播| 欧美在线观看一区| 亚洲欧美一区二区在线观看| 亚洲视频一二三| 99在线热播精品免费| 亚洲精品一区二区三区樱花| 亚洲国产老妈| 亚洲国产视频一区二区| 韩日精品在线| 狠狠网亚洲精品| 精品成人国产在线观看男人呻吟| 国产欧美日韩视频| 国产日韩精品电影| 国产色产综合色产在线视频| 国产美女搞久久| 国产免费一区二区三区香蕉精| 国产精品亚洲综合一区在线观看| 国产精品青草久久久久福利99| 国产精品福利网站| 国产精品一区亚洲| 国产性天天综合网| 伊人成年综合电影网| 依依成人综合视频| 亚洲国产小视频在线观看| 亚洲激情二区| 一区二区三区www| 亚洲图片在线| 久久国内精品自在自线400部| 久久久精品一区| 欧美a级一区| 亚洲精品乱码| 亚洲天堂免费在线观看视频| 午夜在线观看免费一区| 欧美在线视频在线播放完整版免费观看 | 欧美小视频在线观看| 国产精品久久一卡二卡| 国产精品一区在线观看你懂的| 国产日韩综合| 亚洲人在线视频| 亚洲女同性videos| 久久久久久久久久久久久女国产乱 | 欧美专区福利在线| 乱码第一页成人| 欧美性猛交xxxx乱大交退制版 | 国内精品模特av私拍在线观看| 亚洲第一福利视频| 亚洲午夜久久久久久久久电影网| 欧美一级欧美一级在线播放| 美女国产一区| 一区二区三区四区国产| 久久精品盗摄| 国产精品mm| 亚洲高清免费视频| 亚洲男人的天堂在线| 欧美sm重口味系列视频在线观看| 亚洲精品午夜精品| 香蕉国产精品偷在线观看不卡| 牛牛精品成人免费视频| 国产精品久久久久毛片大屁完整版 | 国产精品一区久久久久| 亚洲国产精品成人精品| 亚洲欧美日韩专区| 欧美电影在线观看完整版| 亚洲小说春色综合另类电影| 老妇喷水一区二区三区| 国产精品免费一区二区三区在线观看| 在线免费日韩片| 欧美一区二区久久久| 亚洲日本精品国产第一区| 欧美在线播放视频| 欧美性感一类影片在线播放| 亚洲人成亚洲人成在线观看图片| 久久精品成人| 一区二区三区产品免费精品久久75| 久久婷婷国产综合精品青草| 国产精品蜜臀在线观看| 一区二区欧美在线观看| 免费久久精品视频| 午夜精品久久久| 国产精品久久久久久户外露出| 最新日韩欧美| 牛牛影视久久网| 欧美一区二区在线播放| 国产精品久久久久影院色老大| aaa亚洲精品一二三区| 美女精品在线| 久久岛国电影| 国外成人网址| 久久久噜噜噜久久中文字幕色伊伊 | 蜜桃视频一区| 欧美主播一区二区三区美女 久久精品人 | 欧美激情在线免费观看| 亚洲电影在线免费观看| 久久人人97超碰国产公开结果| 午夜欧美大片免费观看| 国产精品一区二区你懂的| 亚洲欧美春色| 一区二区三区欧美激情| 欧美日韩在线高清| 亚洲小说欧美另类社区| 日韩亚洲欧美精品| 欧美日韩国产一区二区三区| 99精品免费视频| 亚洲免费高清| 欧美天天影院| 欧美一区二区三区四区夜夜大片| 亚洲伊人一本大道中文字幕| 国产日本欧美在线观看|