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

隨筆-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>
            久久免费高清视频| 国产精品高潮久久| 麻豆av福利av久久av| 欧美日韩黄视频| 亚洲激情不卡| 亚洲精品欧美| 欧美激情网友自拍| 91久久精品一区| 一区二区久久| 欧美日一区二区在线观看 | 国产一区在线视频| 新67194成人永久网站| 欧美一区二区三区四区在线观看地址 | 欧美大片第1页| 欧美www在线| 国产综合在线视频| 欧美一区二区三区四区在线| 久久成人免费网| 国产一区二区视频在线观看 | 亚洲激情在线激情| 99re6这里只有精品视频在线观看| 免费亚洲婷婷| 亚洲精品一区二区三区福利| 宅男在线国产精品| 国产精品欧美日韩一区二区| 99re热精品| 欧美影院视频| 在线观看成人一级片| 欧美大尺度在线| 亚洲精品国产精品国产自| 亚洲一区二区在线免费观看| 国产美女精品一区二区三区| 久久福利视频导航| 欧美大香线蕉线伊人久久国产精品| 最新国产の精品合集bt伙计| 欧美区在线播放| 亚洲一区二区精品在线观看| 久久亚洲春色中文字幕久久久| 亚洲国产成人久久综合一区| 另类av一区二区| 亚洲黄色av| 欧美影片第一页| 亚洲日本在线观看| 国产精品色婷婷久久58| 久久男人资源视频| 一本久久综合| 欧美暴力喷水在线| 亚洲自拍偷拍福利| 狠狠色狠色综合曰曰| 欧美精品一区二区三区很污很色的 | 韩国精品在线观看| 欧美美女视频| 久久精品成人| 亚洲三级观看| 久久综合图片| 亚洲女爱视频在线| 在线观看欧美日韩国产| 国产精品久久7| 欧美大片免费观看| 性欧美videos另类喷潮| 亚洲毛片av在线| 免播放器亚洲一区| 小黄鸭精品aⅴ导航网站入口| 亚洲人成网站在线观看播放| 国产亚洲午夜| 欧美涩涩网站| 欧美国产精品久久| 欧美在线视频一区| 亚洲一级高清| 亚洲美女中文字幕| 欧美国产欧美亚州国产日韩mv天天看完整| 亚洲欧美国产高清| 99热这里只有成人精品国产| 韩国成人福利片在线播放| 国产精品成人aaaaa网站| 亚洲一区欧美激情| 一区二区不卡在线视频 午夜欧美不卡在 | 欧美在线黄色| aa级大片欧美三级| 亚洲日本一区二区三区| 欧美不卡福利| 欧美va天堂在线| 免费久久99精品国产自| 久久久www成人免费毛片麻豆| 中文精品视频| 在线视频日本亚洲性| 亚洲人成人一区二区三区| 在线不卡中文字幕| 欲色影视综合吧| 99热精品在线| 亚洲激情网站免费观看| 欧美成人亚洲成人| 欧美一区二区| 亚洲欧美亚洲| 欧美国产视频在线观看| 亚洲人成网站777色婷婷| 一区二区三区日韩欧美精品| 欧美一级久久久| 欧美成人有码| 国产精品区一区二区三| 亚洲国产日韩欧美一区二区三区| 亚洲网站视频福利| 久久在线免费观看视频| 亚洲激情视频在线| 亚洲天堂av在线免费| 久久人91精品久久久久久不卡| 欧美日韩国产在线播放网站| 国产日韩精品综合网站| 99精品国产一区二区青青牛奶| 午夜欧美精品| 亚洲国产精品久久久久秋霞影院 | 蜜臀99久久精品久久久久久软件 | 久久青草久久| 欧美三级在线视频| 极品裸体白嫩激情啪啪国产精品| 亚洲无限av看| 欧美xxx成人| 亚洲欧美制服另类日韩| 欧美性jizz18性欧美| 亚洲日本视频| 欧美激情网友自拍| 久热综合在线亚洲精品| 玉米视频成人免费看| 久久中文久久字幕| 久久九九精品| 在线看欧美视频| 麻豆亚洲精品| 久久综合999| 91久久中文| 亚洲国产成人精品久久久国产成人一区| 久久久久久久波多野高潮日日| 国产一区二区三区网站| 久久―日本道色综合久久| 久久精品91| 在线观看亚洲精品| 欧美国内亚洲| 欧美激情精品久久久久久大尺度| 亚洲三级电影在线观看| 亚洲欧洲免费视频| 欧美三日本三级少妇三2023 | 欧美三级电影精品| 亚洲视频在线一区| 亚洲精品麻豆| 国产精品草莓在线免费观看| 性一交一乱一区二区洋洋av| 亚洲欧美一区二区原创| 国产自产高清不卡| 欧美h视频在线| 欧美日韩国产va另类| 亚洲欧美电影院| 欧美一区二区三区视频免费播放| 在线观看三级视频欧美| 亚洲国产日韩欧美综合久久| 欧美日韩一区二区在线观看 | 国产精品影视天天线| 久久久噜噜噜久久| 美女国产一区| 亚洲无毛电影| 欧美在线观看一区| 亚洲久久一区二区| 亚洲综合大片69999| 激情欧美丁香| 亚洲精品亚洲人成人网| 国产女主播在线一区二区| 欧美1区2区视频| 欧美日韩在线播放一区| 久久久久久午夜| 欧美剧在线免费观看网站| 午夜精品视频网站| 美国成人毛片| 午夜精品成人在线| 久热re这里精品视频在线6| 亚洲一级影院| 裸体女人亚洲精品一区| 亚洲小视频在线观看| 久久九九久精品国产免费直播| 这里是久久伊人| 久久精品二区| 亚洲欧美激情视频| 男人的天堂亚洲| 久久激情网站| 欧美日韩成人激情| 麻豆成人综合网| 国产精品免费看久久久香蕉| 欧美激情视频一区二区三区不卡| 国产精品视频在线观看| 亚洲国产裸拍裸体视频在线观看乱了| 国产精品呻吟| 91久久精品国产91久久| 韩国av一区| 亚洲在线视频网站| 亚洲蜜桃精久久久久久久| 久久se精品一区精品二区| 亚洲一级在线观看| 欧美激情女人20p| 老司机一区二区| 国产日韩欧美a| 中文国产亚洲喷潮| 99精品国产在热久久| 久久一日本道色综合久久|