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

posts - 2, comments - 3, trackbacks - 0, articles - 0
  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

自制os開發記(二)——內核雛形

Posted on 2009-02-25 15:54 bpt 閱讀(1213) 評論(1)  編輯 收藏 引用

其實在開學之前已經實現了簡單的進程調度,實現了4個進程輪轉。 不過一旦把進程棧調大,進程調度會不穩定,一直找不出原因,再加上代碼文件弄的很亂,干脆重寫一遍。

回到學校后就轉用ubuntu做開發環境了。

目前的代碼還是參考了《自》和部分minix的代碼,不過《自》中引用的minix代碼和《設計與實現》書中的代碼不一樣,尚不清楚是不是書的版本問題。我的內核實現上有部分細節與參考的代碼略有不同,有些地方做了一下省略。目標只是做一個內核的雛形出來。

像minix一樣,先貼出幾個比較重要的全局頭文件。

const.h
1 #ifndef _CONST_H
2 #define _CONST_H
3 
4 #define        PRIVILEGE_KERNEL    (0)
5 #define        PRIVILEGE_USER        (3)
6 
7 #endif

type.h
 1 #ifndef _TYPE_H
 2 #define _TYPE_H
 3 
 4 #define PUBLIC
 5 #define PRIVATE static
 6 
 7 typedef signed char            i8_t;
 8 typedef signed short        i16_t;
 9 typedef signed long            i32_t;
10 typedef signed long long    i64_t;
11 
12 typedef unsigned char        u8_t;
13 typedef unsigned short        u16_t;
14 typedef unsigned long        u32_t;
15 typedef unsigned long long    u64_t;
16 
17 typedef u8_t    byte_t;
18 typedef u16_t    dbyte_t;
19 typedef u32_t    qbyte_t;
20 typedef u64_t    obyte_t;
21 
22 typedef u32_t    address_t;
23 
24 #endif

上面兩個文件比較簡單,今后可以擴充。

接下來是內核用到的頭文件。

kconst.h
 1 #ifndef        _KCONST_H
 2 #define        _KCONST_H
 3 
 4 #define        KCODE_SELECTOR        8
 5 #define        KDATA_SELECTOR        16
 6 #define        TSS_SELECTOR        24
 7 #define        UCODE_SELECTOR        (32 + PRIVILEGE_USER)
 8 #define        UDATA_SELECTOR        (40 + PRIVILEGE_USER)
 9 
10 /* vectors of exception */
11 #define        VECTOR_DE            0
12 #define        VECTOR_NMI            2
13 #define        VECTOR_UD            6
14 #define        VECTOR_TS            10
15 #define        VECTOR_NP            11
16 #define        VECTOR_SS            12
17 #define        VECTOR_GP            13
18 #define        VECTOR_PF            14
19 
20 #define        NO_ERROR_CODE        0xffffffff
21 
22 /* vectors of hardware int */
23 #define        VECTOR_IRQ0            0x20
24 #define        VECTOR_IRQ8            0x28
25 
26 /* port of 8259 */
27 #define        INT_MASTER_CTL        0x20
28 #define        INT_MASTER_MASK        0x21
29 #define        INT_SLAVE_CTL        0xa0
30 #define        INT_SLAVE_MASK        0xa1
31 
32 #define        NR_TASKS            4
33 
34 #endif

global.h
 1 #ifndef _GLOBAL_H
 2 #define _GLOBAL_H
 3 
 4 #include <type.h>
 5 #include "protect.h"
 6 #include "process.h"
 7 
 8 #ifdef _GLOBAL_
 9     #define EXTERN PUBLIC
10 #else
11     #define EXTERN extern
12 #endif
13 
14 EXTERN descriptor_t gdt[8], idt[256], ldt[8];
15 
16 EXTERN u64_t gdtr, idtr;
17 
18 EXTERN tss_t tss;
19 
20 EXTERN byte_t kernel_entered;
21 
22 EXTERN process_t proc_table[32];
23 
24 EXTERN process_t * ptr_next_proc;
25 
26 extern u32_t stack_user;
27 
28 #endif
這個頭文件要說一下,其中EXTERN宏的用法是學自minix,我這里利用一個測試宏來確定是聲明還是定義。

proto.h
 1 #ifndef _PROTO_H
 2 #define _PROTO_H
 3 
 4 #include "protect.h"
 5 
 6 /* init.c */
 7 PUBLIC    void    init_kernel(void);
 8 PUBLIC    void    init_hardware(void);
 9 PUBLIC    void    fill_segdesc(descriptor_t *desc, address_t base, u32_t limit, 
10                                 dbyte_t attrib, int dpl);
11 PUBLIC    void    fill_gatedesc(descriptor_t *desc, selector_t seg_selector, address_t offset,
12                                 byte_t attrib, int dpl);
13 
14 /* kernel lib in klib.c & klib.asm */
15 PUBLIC    void    outportb(int port, byte_t value);
16 PUBLIC    void    intr_disable(void);
17 PUBLIC    void    intr_enabla(void);
18 PUBLIC    void    kputc(char c);
19 PUBLIC    void    kprintf(char *s, );
20 
21 void    default_isr(void);
22 
23 /* exception int in kernel.asm */
24 void    divide_error(void);
25 void    nmi(void);
26 void    invalid_opcode(void);
27 void    invalid_tss(void);
28 void    seg_not_present(void);
29 void    stack_fault(void);
30 void    general_protection(void);
31 void    page_fault(void);
32 
33 /* hardware int in kernel.asm */
34 void    hwint00(void);
35 void    hwint01(void);
36 void    hwint02(void);
37 void    hwint03(void);
38 void    hwint04(void);
39 void    hwint05(void);
40 void    hwint06(void);
41 void    hwint07(void);
42 void    hwint08(void);
43 void    hwint09(void);
44 void    hwint10(void);
45 void    hwint11(void);
46 void    hwint12(void);
47 void    hwint13(void);
48 void    hwint14(void);
49 void    hwint15(void);
50 
51 
52 void    clock_handler(void);
53 
54 #endif

全局頭文件的引用,以及這三個頭文件的引用按順序放在kernel.h中。這樣寫源文件時引用kernel.h即可。
 1 #ifndef _KERNEL_H
 2 #define _KERNEL_H
 3 
 4 #include <ansi.h>
 5 #include <type.h>
 6 #include <const.h>
 7 
 8 #include "kconst.h"
 9 #include "global.h"
10 #include "proto.h"
11 
12 #endif

接下來是兩個比較重要的頭文件,一個主要包含保護模式需要的類型和常量,另一個主要包含進程調度的類型和常量。

protect.h
 1 #ifndef _PROTECT_H
 2 #define _PROTECT_H
 3 
 4 #include <type.h>
 5 
 6 typedef        u64_t        descriptor_t;
 7 typedef        u16_t        selector_t;
 8 
 9 #define        DA_CODE32    (0xc098)
10 #define        DA_DATA32    (0xc092)
11 #define        DA_TSS        (0x89)
12 #define        DA_LDT        (0x82)
13 
14 #define        GA_INT32    (0x8e)
15 
16 typedef struct tss_t {
17     u32_t        backlink;
18     u32_t        esp0;
19     u32_t        ss0;
20     u32_t        esp1;
21     u32_t        ss1;
22     u32_t        esp2;
23     u32_t        ss2;
24     u32_t        ecr3;
25     u32_t        eip;
26     u32_t        eflags;
27     u32_t        eax;
28     u32_t        ecx;
29     u32_t        edx;
30     u32_t        ebx;
31     u32_t        esp;
32     u32_t        ebp;
33     u32_t        esi;
34     u32_t        edi;
35     u32_t        es;
36     u32_t        cs;
37     u32_t        ss;
38     u32_t        ds;
39     u32_t        fs;
40     u32_t        gs;
41     u32_t        ldt;
42     u32_t        trap;
43     u32_t        iobase;
44 } tss_t;
45 
46 #endif
東西不多,但都是精心構造好的。

process.h
 1 #ifndef _PROCESS_H
 2 #define _PROCESS_H
 3 
 4 #include <type.h>
 5 
 6 typedef struct process_t {
 7     u32_t            gs;
 8     u32_t            fs;
 9     u32_t            es;
10     u32_t            ds;
11     u32_t            edi;
12     u32_t            esi;
13     u32_t            ebp;
14     u32_t            kernel_esp;
15     u32_t            ebx;
16     u32_t            edx;
17     u32_t            ecx;
18     u32_t            eax;
19     u32_t            ret;
20     u32_t            eip;
21     u32_t            cs;
22     u32_t            eflags;
23     u32_t            esp;
24     u32_t            ss;
25     u32_t            pid;
26 } process_t;
27 
28 typedef struct task_t {
29     address_t         entry;
30     //u32_t            stack_size;
31     //char            name[16];
32 } task_t;
33 
34 #endif
其中的process_t是進程表項的類型,其中元素的順序是精心安排好的。ret元素可以說是minix中的一個不錯的trick,借助他可以實現不用ret的調用返回。

最后一個頭文件是kconst.inc,其中的部分內容要于kconst.h和process.h中的內容同步。
 1 %ifndef _KCONST_INC
 2 %define _KCONST_INC
 3 
 4 
 5 %define        KCODE_SELECTOR        8
 6 %define        KDATA_SELECTOR        16
 7 %define        TSS_SELECTOR        24
 8 
 9 ;vectors of exception
10 %define        VECTOR_DE            0
11 %define        VECTOR_NMI            2
12 %define        VECTOR_UD            6
13 %define        VECTOR_TS            10
14 %define        VECTOR_NP            11
15 %define        VECTOR_SS            12
16 %define        VECTOR_GP            13
17 %define        VECTOR_PF            14
18 
19 %define        NO_ERROR_CODE        0xffffffff
20 
21 ;vectors of hardware int
22 %define        VECTOR_IRQ0            0x20
23 %define        VECTOR_IRQ8            0x28
24 
25 ;port of 8259
26 %define        INT_MASTER_CTL        0x20
27 %define        INT_MASTER_MASK        0x21
28 %define        INT_SLAVE_CTL        0xa0
29 %define        INT_SLAVE_MASK        0xa1
30 
31 %define        END_OF_INT            0x20
32 
33 
34 ;process.h
35 PT_GS        EQU        0
36 PT_FS        EQU        PT_GS        +4
37 PT_ES        EQU        PT_FS        +4
38 PT_DS        EQU        PT_ES        +4
39 PT_EDI        EQU        PT_DS        +4
40 PT_ESI        EQU        PT_EDI        +4
41 PT_EBP        EQU        PT_ESI        +4
42 PT_KESP        EQU        PT_EBP        +4
43 PT_EBX        EQU        PT_KESP        +4
44 PT_EDX        EQU        PT_EBX        +4
45 PT_ECX        EQU        PT_EDX        +4
46 PT_EAX        EQU        PT_ECX        +4
47 PT_RET        EQU        PT_EAX        +4
48 PT_EIP        EQU        PT_RET        +4
49 PT_CS        EQU        PT_EIP        +4
50 PT_EFLAGS    EQU        PT_CS        +4
51 PT_ESP        EQU        PT_EFLAGS    +4
52 PT_SS        EQU        PT_ESP        +4
53 
54 PT_STACK_TOP        EQU        PT_SS+4
55 TSS_ESP0            EQU        4
56 
57 %endif



引用的頭文件告一段落,可以看到可執行代碼了。現從kernel的入口點開始。

kernel.asm
  1 %include "kconst.inc"
  2 
  3 ;=====================================================================
  4 ;                   kernel stack
  5 ;=====================================================================
  6 
  7 SECTION .bss
  8 
  9         resb    4 * 1024    ;4KB
 10 stack_kernel:
 11 
 12 global stack_user
 13         resb    10 * 1024    ;10KB
 14 stack_user:
 15 
 16 ;=====================================================================
 17 ;                   kernel
 18 ;=====================================================================
 19 
 20 SECTION .text
 21 
 22 extern init_kernel, init_hardware, main
 23 extern gdtr, idtr
 24 global _start
 25 _start:
 26         cli
 27         mov        esp, stack_kernel
 28 
 29         call    init_kernel
 30         call    init_hardware
 31 
 32         cli
 33         lgdt    [gdtr]
 34         lidt    [idtr]
 35 
 36         jmp        KCODE_SELECTOR:.1
 37 .1:
 38         mov        ax,    KDATA_SELECTOR
 39         mov        ds, ax
 40         mov        es, ax
 41         mov        fs, ax
 42         mov        gs, ax
 43         mov        ss, ax
 44         push    0
 45         popf
 46 
 47         mov        ax, TSS_SELECTOR
 48         ltr        ax
 49 
 50         mov        al, 0xfe
 51         out        0x21, al
 52         nop
 53         nop
 54 
 55         jmp        main
 56 
 57 ;=====================================================================
 58 ;                       default isr
 59 ;=====================================================================
 60 
 61 ALIGN 16
 62 global default_isr
 63 default_isr:
 64         cli
 65         call    save
 66         sti
 67         call    default_handler
 68         cli
 69         ret
 70 
 71 ;=====================================================================
 72 ;                        exception
 73 ;=====================================================================
 74 
 75 ;+++++++++++++++++++++++++++++++++++++++++++++++++
 76 ;    EH_ERR        label, vector, error
 77 ;+++++++++++++++++++++++++++++++++++++++++++++++++
 78 
 79 %macro    EH_ERR    2
 80 ALIGN 16
 81 global %1
 82 %1:
 83         push    %2
 84         jmp        exception
 85 %endmacro
 86 
 87 ;+++++++++++++++++++++++++++++++++++++++++++++++++
 88 ;    EH_NOERR    lable, vector
 89 ;+++++++++++++++++++++++++++++++++++++++++++++++++
 90 
 91 %macro    EH_NOERR    2
 92 ALIGN 16
 93 global %1
 94 %1:
 95         push    NO_ERROR_CODE
 96         push    %2
 97         jmp        exception
 98 %endmacro
 99 
100 ;+++++++++++++++++++++++++++++++++++++++++++++++++
101 ;+++++++++++++++++++++++++++++++++++++++++++++++++
102 
103 EH_NOERR    divide_error,        VECTOR_DE
104 EH_NOERR    nmi,                VECTOR_NMI
105 EH_NOERR    invalid_opcode,        VECTOR_UD
106 EH_ERR        invalid_tss,        VECTOR_TS
107 EH_ERR        seg_not_present,    VECTOR_NP
108 EH_ERR        stack_fault,        VECTOR_SS
109 EH_ERR        general_protection,    VECTOR_GP
110 EH_ERR        page_fault,            VECTOR_PF
111 
112 ALIGN 16
113 exception:
114 extern exception_handler
115         call    exception_handler
116         add        esp, 8
117         hlt
118         jmp $
119         iretd
120 
121 ;%unmacro    EH_NOERR    2
122 ;%unmacro    EH_ERR        2
123 
124 
125 ;=====================================================================
126 ;                         hardware int
127 ;=====================================================================
128 
129 ;+++++++++++++++++++++++++++++++++++++++++++++++++
130 ;    HWINT_MASTER    label, irq, handler
131 ;+++++++++++++++++++++++++++++++++++++++++++++++++
132 
133 %macro    HWINT_MASTER    3
134 ALIGN 16
135 global %1
136 %1:
137         call    save
138         in        al, INT_MASTER_MASK
139         or        al, (1 << %2)
140         out        INT_MASTER_MASK, al
141         mov        al, END_OF_INT
142         out        INT_MASTER_CTL, al
143         sti
144         call    %3
145         cli
146         in        al, INT_MASTER_MASK
147         and        al, ~(1 << %2)
148         out        INT_MASTER_MASK, al
149         ret
150 %endmacro
151 
152 ;+++++++++++++++++++++++++++++++++++++++++++++++++
153 ;    HWINT_SLAVE        label, irq, handler
154 ;+++++++++++++++++++++++++++++++++++++++++++++++++
155 
156 %macro    HWINT_SLAVE        3
157 ALIGN 16
158 global %1
159 %1:
160         call    save
161         in        al, INT_SLAVE_MASK
162         or        al, (1 << (%2 - 8))
163         out        INT_SLAVE_MASK, al
164         mov        al, END_OF_INT
165         out        INT_SLAVE_CTL, al
166         sti
167         call    %3
168         cli
169         in        al, INT_SLAVE_MASK
170         and        al, ~(1 << (%2 - 8))
171         out        INT_SLAVE_MASK, al
172         ret
173 %endmacro
174 
175 ;+++++++++++++++++++++++++++++++++++++++++++++++++
176 ;+++++++++++++++++++++++++++++++++++++++++++++++++
177 
178 extern clock_handler
179 
180 HWINT_MASTER    hwint00,    0,        clock_handler
181 HWINT_MASTER    hwint01,    1,        default_handler
182 HWINT_MASTER    hwint02,    2,        default_handler
183 HWINT_MASTER    hwint03,    3,        default_handler
184 HWINT_MASTER    hwint04,    4,        default_handler
185 HWINT_MASTER    hwint05,    5,        default_handler
186 HWINT_MASTER    hwint06,    6,        default_handler
187 HWINT_MASTER    hwint07,    7,        default_handler
188 
189 HWINT_SLAVE        hwint08,    8,        default_handler
190 HWINT_SLAVE        hwint09,    9,        default_handler
191 HWINT_SLAVE        hwint10,    10,        default_handler
192 HWINT_SLAVE        hwint11,    11,        default_handler
193 HWINT_SLAVE        hwint12,    12,        default_handler
194 HWINT_SLAVE        hwint13,    13,        default_handler
195 HWINT_SLAVE        hwint14,    14,        default_handler
196 HWINT_SLAVE        hwint15,    15,        default_handler
197 
198 
199 ;=====================================================================
200 ;                         save
201 ;=====================================================================
202 
203 ALIGN 16
204 extern kernel_entered
205 save:
206         pushad
207         push    ds
208         push    es
209         push    fs
210         push    gs
211         mov        ebp, esp
212         cmp        byte [kernel_entered], 0
213         jne        .reenter
214         inc        byte [kernel_entered]
215         mov        esp, stack_kernel
216         push    restart
217         inc        byte [0xb8002]
218         jmp        [ebp + PT_RET]
219 ALIGN 16
220 .reenter:
221         push    restart.1
222         inc        byte [0xb8004]
223         jmp        [ebp + PT_RET]
224 
225 ;=====================================================================
226 ;                        restart
227 ;=====================================================================
228 
229 ALIGN 16
230 extern ptr_next_proc, tss
231 global restart:
232 restart:
233         mov        esp, dword [ptr_next_proc]
234         lea        eax, [esp + PT_STACK_TOP]
235         mov        dword [tss + TSS_ESP0], eax
236         dec        byte [kernel_entered]
237 .1:
238         pop        gs
239         pop        fs
240         pop        es
241         pop        ds
242         popad
243         add        esp, 4
244         iretd
245 
246 
247 
248 
249 ALIGN 16
250 extern kprintf
251 default_handler:
252         push    .msg
253         call    kprintf
254         add        esp, 4
255         hlt
256         jmp        $
257         ret
258 
259 ALIGN 4
260 .msg    DB        `int handler not completed yet!\n`, 0
261 
事實上這個kernel還很粗糙,比如save為了調試而改變顯存的值,以及那個default_handler。IRQ0打開的也很粗暴。好在架構已經成形,剩下的是細節部分的打磨。

global.c是全局變量的所在地。呵呵,真是脫了global.h的福。
1 #define _GLOBAL_
2 #include "global.h"

再有就是一個簡單的庫,klib.c和klib.asm里面有個非常簡陋的輸出函數,主要拿來調試用的。
  1 #include "kernel.h"
  2 
  3 PUBLIC void kputc(char c)
  4 {
  5     static int pos = 160, row = 1, col = 0;
  6     int i;
  7 
  8     if (24 == row) {
  9 
 10         for (i = 0xb8000; i < 0xb8000 + 24 * 160; i += 2) {
 11             *(dbyte_t *)i = *(dbyte_t *)(i + 160);
 12         }
 13         --row;
 14         pos -= 160;
 15         /*
 16         --row;
 17         start += 80;
 18         outportb(0x3d4, 0xc);
 19         outportb(0x3d5, (start >> 8) & 0xff);
 20         outportb(0x3d4, 0xd);
 21         outportb(0x3d5, start & 0xff);
 22         */
 23     }
 24     switch (c) {
 25     case '\n':
 26         ++row;
 27         col = 0;
 28         pos = row * 160;
 29         break;
 30     default:
 31         *(dbyte_t *)(0xb8000 + pos) = (dbyte_t)0x700 | c;
 32         pos += 2;
 33         ++col;
 34         if (80 == col) {
 35             ++row;
 36             col = 0;
 37         }
 38     }
 39     i = (pos >> 1);
 40     outportb(0x3d40xe);
 41     outportb(0x3d5, (i >> 8& 0xff);
 42     outportb(0x3d40xf);
 43     outportb(0x3d5, i & 0xff);
 44     return;
 45 }
 46 
 47 PRIVATE void kprint_hex(unsigned int x);
 48 PRIVATE void kprint_int(int x);
 49 
 50 PUBLIC void kprintf(char * s, )
 51 {
 52     u32_t * ptr_arg = (u32_t *)(&s);
 53 
 54     while (*s) {
 55         if ('%' == *s) {
 56             ++s;
 57             switch (*s) {
 58             case 'x':
 59                 ++s;
 60                 ++ptr_arg;
 61                 kputc('0');
 62                 kputc('x');
 63                 kprint_hex(*ptr_arg);
 64                 break;
 65             case 'd':
 66                 ++s;
 67                 ++ptr_arg;
 68                 kprint_int(*ptr_arg);
 69                 break;
 70             default:
 71                 kputc('%');
 72             }
 73         } else {
 74             kputc(*s);
 75             ++s;
 76         }
 77     }
 78     return;
 79 }
 80 
 81 PRIVATE void kprint_hex(unsigned int x)
 82 {
 83     int i;
 84 
 85     if (0 == x) {
 86         kputc('0');
 87         return;
 88     }
 89     for (i = 4; i < 32; i += 4) {
 90         if ((x >> i) == 0) {
 91             break;
 92         }
 93     }
 94     for (i -= 4; i >= 0; i -= 4) {
 95         kputc("0123456789abcdef"[(x >> i) & 0xf]);
 96     }
 97     return;
 98 }
 99 
100 PRIVATE void _kprint_int(int x);
101 
102 PRIVATE void kprint_int(int x)
103 {
104     if (0 == x) {
105         kputc('0');
106     } else if (x > 0) {
107         _kprint_int(x);
108     } else {
109         kputc('-');
110         _kprint_int(-x);
111     }
112     return;
113 }
114 
115 PRIVATE void _kprint_int(int x)
116 {
117     if (x) {
118         _kprint_int(x /10);
119         kputc("01234567890"[x % 10]);
120     }
121     return;
122 }
 1 SECTION .text
 2 
 3 ;=====================================================================
 4 ;                void outportb(dbyte_t port, byte_t value)
 5 ;=====================================================================
 6 
 7 global outportb
 8 outportb:
 9         push    edx
10 
11         mov        dx, word [esp + 8]
12         mov        al, byte [esp + 12]
13         out        dx, al
14         nop
15         nop
16 
17         pop        edx
18         ret
19 
20 ;=====================================================================
21 ;                     void intr_disable(void)
22 ;=====================================================================
23 
24 global intr_disable
25 intr_disable:
26         cli
27         ret
28 
29 ;=====================================================================
30 ;                     void intr_enable(void)
31 ;=====================================================================
32 
33 global intr_enable
34 intr_enable:
35         sti
36         ret

繼續,下面是init.c。
  1 #include "kernel.h"
  2 #include "protect.h"
  3 #include "process.h"
  4 
  5 /*====================================================================*
  6  *                     init_kernel                                    *
  7  *====================================================================*/
  8 
  9 PUBLIC void init_kernel(void)
 10 {
 11     int i;
 12 
 13     byte_t *= (byte_t *)(&gdtr);
 14     *(u16_t *)(p + 0= (u16_t)(sizeof(gdt) - 1);
 15     *(u32_t *)(p + 2= (u32_t)(&gdt);
 16 
 17     p = (byte_t *)(&idtr);
 18     *(u16_t *)(p + 0= (u16_t)(sizeof(idt) - 1);
 19     *(u32_t *)(p + 2= (u32_t)(&idt);
 20     
 21     fill_segdesc(&gdt[KCODE_SELECTOR >> 3], 00xfffff, DA_CODE32, PRIVILEGE_KERNEL);
 22     fill_segdesc(&gdt[KDATA_SELECTOR >> 3], 00xfffff, DA_DATA32, PRIVILEGE_KERNEL);
 23     fill_segdesc(&gdt[UCODE_SELECTOR >> 3], 00xfffff, DA_CODE32, PRIVILEGE_USER);
 24     fill_segdesc(&gdt[UDATA_SELECTOR >> 3], 00xfffff, DA_DATA32, PRIVILEGE_USER);
 25 
 26     tss.ss0 = KDATA_SELECTOR;
 27     tss.iobase = sizeof(tss);
 28     fill_segdesc(&gdt[TSS_SELECTOR >> 3], (address_t)(&tss), sizeof(tss) - 1,
 29                     DA_TSS, PRIVILEGE_KERNEL);
 30 
 31     struct isr_table_t {
 32         address_t    entry;
 33         int            privilege;
 34     } isr_table[256];
 35 
 36     #define ISR_TABLE(V,E,P)    {isr_table[V].entry = (address_t)(E); \
 37                                 isr_table[V].privilege = (P);}
 38 
 39     for (i = 0; i < 256++i) {
 40         ISR_TABLE(i, default_isr, PRIVILEGE_USER);
 41     }
 42 
 43     ISR_TABLE(VECTOR_DE,    divide_error,        PRIVILEGE_KERNEL);
 44     ISR_TABLE(VECTOR_NMI,    nmi,                PRIVILEGE_KERNEL);
 45     ISR_TABLE(VECTOR_UD,    invalid_opcode,        PRIVILEGE_KERNEL);
 46     ISR_TABLE(VECTOR_TS,     invalid_tss,        PRIVILEGE_KERNEL);
 47     ISR_TABLE(VECTOR_NP,    seg_not_present,     PRIVILEGE_KERNEL);
 48     ISR_TABLE(VECTOR_SS,     stack_fault,        PRIVILEGE_KERNEL);
 49     ISR_TABLE(VECTOR_GP,    general_protection,    PRIVILEGE_KERNEL);
 50     ISR_TABLE(VECTOR_PF,    page_fault,            PRIVILEGE_KERNEL);
 51 
 52     ISR_TABLE(VECTOR_IRQ0,        hwint00,    PRIVILEGE_KERNEL);
 53     ISR_TABLE(VECTOR_IRQ0 + 1,    hwint01,    PRIVILEGE_KERNEL);
 54     ISR_TABLE(VECTOR_IRQ0 + 2,    hwint02,    PRIVILEGE_KERNEL);
 55     ISR_TABLE(VECTOR_IRQ0 + 3,    hwint03,    PRIVILEGE_KERNEL);
 56     ISR_TABLE(VECTOR_IRQ0 + 4,    hwint04,    PRIVILEGE_KERNEL);
 57     ISR_TABLE(VECTOR_IRQ0 + 5,    hwint05,    PRIVILEGE_KERNEL);
 58     ISR_TABLE(VECTOR_IRQ0 + 6,    hwint06,    PRIVILEGE_KERNEL);
 59     ISR_TABLE(VECTOR_IRQ0 + 7,    hwint07,    PRIVILEGE_KERNEL);
 60     ISR_TABLE(VECTOR_IRQ8,        hwint08,    PRIVILEGE_KERNEL);
 61     ISR_TABLE(VECTOR_IRQ8 + 1,    hwint09,    PRIVILEGE_KERNEL);
 62     ISR_TABLE(VECTOR_IRQ8 + 2,    hwint10,    PRIVILEGE_KERNEL);
 63     ISR_TABLE(VECTOR_IRQ8 + 3,    hwint11,    PRIVILEGE_KERNEL);
 64     ISR_TABLE(VECTOR_IRQ8 + 4,    hwint12,    PRIVILEGE_KERNEL);
 65     ISR_TABLE(VECTOR_IRQ8 + 5,    hwint13,    PRIVILEGE_KERNEL);
 66     ISR_TABLE(VECTOR_IRQ8 + 6,    hwint14,    PRIVILEGE_KERNEL);
 67     ISR_TABLE(VECTOR_IRQ8 + 7,    hwint15,    PRIVILEGE_KERNEL);
 68 
 69     for (i = 0; i < 256++i) {
 70         fill_gatedesc(&idt[i], KCODE_SELECTOR, isr_table[i].entry, 
 71                         GA_INT32, isr_table[i].privilege);
 72     }
 73     
 74     return;
 75 }
 76 
 77 
 78 /*====================================================================*
 79  *                      fill_segdesc                                  *
 80  *====================================================================*/
 81 
 82 PUBLIC void fill_segdesc(descriptor_t *desc, address_t base, u32_t limit, 
 83                             dbyte_t attrib, int dpl)
 84 {
 85     address_t p = (address_t)desc;
 86 
 87     *(dbyte_t *)(p + 0= limit & 0xffff;
 88     *(dbyte_t *)(p + 2= base & 0xffff;
 89     *(byte_t  *)(p + 4= (base >> 16& 0xff;
 90     *(dbyte_t *)(p + 5= attrib | ((limit >> 8& 0xf00| (dpl << 5);
 91     *(byte_t  *)(p + 7= (base >> 24& 0xff;
 92     return;
 93 }
 94 
 95 /*====================================================================*
 96  *                       fill_gatedesc                                *
 97  *====================================================================*/
 98 
 99 PUBLIC void fill_gatedesc(descriptor_t *desc, selector_t seg_selector, 
100                             address_t offset, byte_t attrib, int dpl)
101 {
102     address_t p = (address_t)desc;
103 
104     *(dbyte_t *)(p + 0= offset & 0xffff;
105     *(dbyte_t *)(p + 2= seg_selector;
106     *(byte_t  *)(p + 4= 0;
107     *(byte_t  *)(p + 5= attrib | (dpl << 5);
108     *(dbyte_t *)(p + 6= (offset >> 16& 0xffff;
109     return;
110 }
111 
112 /*====================================================================*
113  *                       init_hardware                                *
114  *====================================================================*/
115 
116 PUBLIC void init_hardware(void)
117 {
118     //init_8253();
119     init_8259();
120     return;
121 }
其中對8253的初始化尚未實現,留作下一個目標。

8259.c
 1 #include "kernel.h"
 2 
 3 /*====================================================================*
 4  *                     init_8259                                      *
 5  *====================================================================*/
 6 
 7  PUBLIC void init_8259(void)
 8 {
 9     intr_disable();
10 
11     /* master ICW1 */
12     outportb(INT_MASTER_CTL, 0x11);
13 
14     /* master ICW2 */
15     outportb(INT_MASTER_MASK, VECTOR_IRQ0);
16 
17     /* master ICW3 */
18     outportb(INT_MASTER_MASK, (1 << 2));
19 
20     /* master ICW4 */
21     outportb(INT_MASTER_MASK, 0x1);
22 
23     /* master OCW1 , IRQ0 ~ IRQ7 mask */
24     outportb(INT_MASTER_MASK, ~(1 << 2));
25 
26     /* slave ICW1 */
27     outportb(INT_SLAVE_CTL, 0x11);
28 
29     /* slave ICW2 */
30     outportb(INT_SLAVE_MASK, VECTOR_IRQ8);
31 
32     /* slave ICW3 */
33     outportb(INT_SLAVE_MASK, 2);
34 
35     /* slave ICW4 */
36     outportb(INT_SLAVE_MASK, 0x1);
37 
38     /* slave OCW1 , IRQ8 ~ IRQ15 mask */
39     outportb(INT_SLAVE_MASK, ~0);
40 
41     return;
42 }

exception.c,異常處理函數
 1 #include "kernel.h"
 2 
 3 void exception_handler(int vector, int err_code)
 4 {
 5     u32_t * p;
 6 
 7     static char msg[20][50= {
 8         "Divide 0",
 9         "",
10         "",
11         "",
12         "",
13         "",
14         "Undefined Opcode",
15         "",
16         "",
17         "",
18         "Invalid TTS",
19         "Segment Not Present",
20         "Stack-Segment Fault",
21         "General Protection",
22         "Page Fault",
23         "",
24         "",
25         "Alignment Check",
26     };
27 
28     kprintf("\n\n====================================================\n\n");
29     kprintf("An exception here!\n");
30     kprintf(msg[vector]);
31     kprintf(", error code is %x\n", err_code);
32 
33     if (err_code & 0x2) {
34         p = (u32_t *)(&idt[(err_code & 0xffff>> 3]);
35         kprintf("vector of this gate is %x\n", (err_code & 0xffff>> 3);
36         kprintf("gate decriptor in ldt is %x(high) %x(low)\n\n"*(p + 1), *p);
37     } else {
38         p = (u32_t *)(&gdt[(err_code & 0xffff>> 3]);
39         kprintf("seg decriptor in gdt is %x(high) %x(low)\n\n"*(p + 1), *p);
40     }
41     return;
42 }

clock.c,時鐘任務,僅僅作輪轉調度,有待擴充
 1 #include "kernel.h"
 2 
 3 PUBLIC void clock_handler(void)
 4 {
 5     //++(*(byte_t *)0xb8000);
 6     
 7     ++ptr_next_proc;
 8     if (proc_table + NR_TASKS == ptr_next_proc) {
 9         ptr_next_proc = &proc_table[0];
10     }
11     return;
12 }

main.c,由內核級下降到用戶級,啟動第一個進程
 1 #include "kernel.h"
 2 
 3 void TestA(void);
 4 void TestB(void);
 5 void TestC(void);
 6 void TestD(void);
 7 
 8 int main(void)
 9 {
10     static task_t task_table[NR_TASKS] = {
11         { (address_t)TestA },
12         { (address_t)TestB },
13         { (address_t)TestC },
14         { (address_t)TestD },
15     };
16     address_t stack_top = (address_t)&stack_user;
17     process_t *p;
18     int i;
19 
20     for (i = 0; i < NR_TASKS; ++i) {
21         p = &proc_table[i];
22         p->cs = UCODE_SELECTOR;
23         p->ds =
24         p->es =
25         p->fs =
26         p->gs =
27         p->ss = UDATA_SELECTOR;
28         p->esp = (u32_t)stack_top;
29         p->eip = (u32_t)task_table[i].entry;
30         p->eflags = 0x3202;
31 
32         stack_top -= 2048;
33     }
34 
35     kernel_entered = 1;
36     ptr_next_proc = &proc_table[0];
37     kprintf("start first process\n");
38     restart();
39     return 0;
40 }
41 

test.c,其中有四個測試進程
 1 #include "kernel.h"
 2 
 3 PRIVATE void delay(void);
 4 
 5 void TestA(void)
 6 {
 7     int i;
 8 
 9     for (i = 01++i) {
10         kprintf("A%d ", i);
11         delay();
12     }
13     return;
14 }
15 
16 void TestB(void)
17 {
18     int i;
19 
20     for (i = 01++i) {
21         kprintf("B%d ", i);
22         delay();
23     }
24     return;
25 }
26 
27 void TestC(void)
28 {
29     int i;
30 
31     for (i = 01++i) {
32         kprintf("C%d ", i);
33         delay();
34     }
35     return;
36 }
37 
38 void TestD(void)
39 {
40     int i;
41 
42     for (i = 01++i) {
43         kprintf("D%d ", i);
44         delay();
45     }
46     return;
47 }
48 
49 PRIVATE void delay(void)
50 {
51     int i, j;
52 
53     for (i = 0; i < 1000000++i) {
54         ++j;
55     }
56 }

好,最后貼上編譯用的Makefile,編譯后就可以在virtualbox上看到結果了。
 1 ENTRYPOINT    =    0x30400
 2 HEADERS        =    kernel.h global.h kconst.h proto.h protect.h process.h
 3 
 4 AS            =    nasm
 5 ASFLAGS        =    -f elf
 6 CC            =    gcc
 7 CFLAGS        =    -c -I ../include
 8 LD            =    ld
 9 LDFLAGS        =    -s -Ttext $(ENTRYPOINT)
10 
11 OBJS        =    kernel.o global.o init.o 8259.o main.o klib1.o klib2.o exception.o clock.o test.o
12 
13 kernel.bin: $(OBJS)
14     $(LD) $(LDFLAGS) -o $@ $(OBJS)
15     rm -f $(OBJS)
16     sudo mount ../TINIX.IMG /mnt/TINIX -o loop
17     sudo cp -f $@ /mnt/TINIX
18     sudo umount /mnt/TINIX
19     rm $@
20 
21 kernel.o: kernel.asm kconst.inc
22     $(AS) $(ASFLAGS) -o $@ $<
23 
24 global.o: global.c $(HEADERS)
25     $(CC) $(CFLAGS) -o $@ $<
26 
27 init.o: init.c $(HEADERS)
28     $(CC) $(CFLAGS) -o $@ $<
29 
30 8259.o: 8259.c $(HEADERS)
31     $(CC) $(CFLAGS) -o $@ $<
32 
33 main.o: main.c $(HEADERS)
34     $(CC) $(CFLAGS) -o $@ $<
35 
36 klib1.o: klib.c $(HEADERS)
37     $(CC) $(CFLAGS) -o $@ $<
38 
39 klib2.o: klib.asm kconst.inc
40     $(AS) $(ASFLAGS) -o $@ $<
41 
42 exception.o: exception.c $(HEADERS)
43     $(CC) $(CFLAGS) -o $@ $<
44 
45 clock.o: clock.c $(HEADERS)
46     $(CC) $(CFLAGS) -o $@ $<
47 
48 test.o: test.c $(HEADERS)
49     $(CC) $(CFLAGS) -o $@ $<
50 
51 unmount:
52     sudo umount /mnt/TINIX

show一下運行的結果:



自己感覺還不錯。
目前的kernel仍然很簡陋,硬件的初始化尚未完成。異常處理也很簡陋,甚至沒有考慮到棧的問題。硬件中斷也沒有完成。
進程調度也沒有實現。這些都是下一步的目標。



Feedback

# re: 自制os開發記(二)——內核雛形  回復  更多評論   

2009-02-25 16:08 by 消滅零回復
任務如題
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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| 亚洲欧美不卡| 久久gogo国模啪啪人体图| 久久www成人_看片免费不卡| 国产精品视频成人| 国产情侣久久| 一区国产精品| 99riav久久精品riav| 香港久久久电影| 毛片基地黄久久久久久天堂| 亚洲国产免费| 亚洲欧美国产高清| 嫩草成人www欧美| 国产精品看片你懂得| 国产欧美一区二区三区国产幕精品 | 欧美精品在线看| 欧美午夜精品理论片a级按摩| 欧美午夜视频网站| 永久久久久久| 亚洲欧美日韩一区在线| 久久久久久久精| 亚洲精选大片| 久久久夜精品| 国产伦精品一区二区三区视频孕妇 | 久久久九九九九| 欧美日韩国产成人高清视频| 国产精品综合网站| 亚洲欧洲精品一区二区三区波多野1战4 | 国产精品私房写真福利视频| 亚洲成色777777女色窝| 亚洲免费视频成人| 欧美岛国激情| 久久精品女人的天堂av| 国产精品国产精品| 亚洲精品国产系列| 久久久久久穴| 午夜精品久久久久久久99热浪潮| 久久综合激情| 国语自产偷拍精品视频偷| 日韩亚洲一区二区| 亚洲第一成人在线| 另类尿喷潮videofree| 国产日韩精品一区二区浪潮av| 欧美一区二区三区在线播放| 久久婷婷人人澡人人喊人人爽| 国产精品福利网站| 一本一本久久a久久精品综合麻豆| 欧美国产精品专区| 噜噜噜在线观看免费视频日韩| 国产精品人人做人人爽人人添| 99re8这里有精品热视频免费| 久热综合在线亚洲精品| 亚洲欧美日韩一区二区三区在线| 欧美精品久久久久久久久久| 日韩午夜高潮| 亚洲欧洲一区二区三区| 欧美大成色www永久网站婷| 亚洲韩国日本中文字幕| 免费在线观看一区二区| 久久精品在这里| 在线观看成人av| 亚洲电影免费在线| 欧美电影在线| 一区二区三区精品视频| 一本综合久久| 国产精品爽黄69| 欧美在线影院在线视频| 久久精品噜噜噜成人av农村| 亚洲国产视频一区二区| 亚洲大胆av| 欧美日韩国产小视频| 亚洲欧美日韩国产一区二区三区 | 亚洲第一毛片| 亚洲第一在线| 欧美日韩亚洲综合一区| 先锋影音国产一区| 久久国产福利国产秒拍| 亚洲第一福利视频| 亚洲三级国产| 国产精品国产亚洲精品看不卡15| 午夜久久久久久| 久久久久久久一区| 亚洲免费观看高清完整版在线观看熊| 日韩视频一区二区三区在线播放免费观看| 欧美午夜宅男影院在线观看| 久久激情五月丁香伊人| 蜜臀久久99精品久久久久久9| 在线亚洲一区观看| 欧美专区在线观看一区| 一本色道久久综合亚洲精品不卡| 亚洲一区二区三区久久| 亚洲第一色在线| 一区二区三区视频在线看| 黄色一区三区| 亚洲伦理中文字幕| 国产一区清纯| 一区二区激情| **欧美日韩vr在线| 亚洲一区二区精品在线观看| 亚洲国产黄色片| 亚洲午夜久久久久久久久电影网| 亚洲大胆视频| 欧美在线一二三四区| 正在播放日韩| 蜜臀久久99精品久久久画质超高清 | 日韩亚洲欧美高清| 国产日韩综合| 一区二区三区久久久| 亚洲国产一区二区三区a毛片| 亚洲视频网站在线观看| 最新国产の精品合集bt伙计| 亚洲主播在线观看| 99视频有精品| 美女诱惑黄网站一区| 久久看片网站| 国产精品久久二区| 91久久精品www人人做人人爽| 国产一区日韩一区| 亚洲综合视频一区| 亚洲一区二区三| 欧美激情aⅴ一区二区三区| 能在线观看的日韩av| 国产一区二区三区黄| 亚洲在线视频网站| 亚洲性视频h| 欧美激情视频网站| 欧美激情亚洲国产| 亚洲电影免费观看高清| 久久久久久久尹人综合网亚洲| 久久精品成人欧美大片古装| 国产精品国产三级国产aⅴ9色| 亚洲精品视频二区| 一区二区高清视频在线观看| 欧美片第1页综合| 亚洲精品久久久久久久久久久| 亚洲精品一区二区三区福利| 欧美成人影音| 亚洲乱码国产乱码精品精天堂| 亚洲日韩欧美一区二区在线| 欧美国产亚洲精品久久久8v| 欧美成人综合网站| 亚洲精品一区二区在线观看| 欧美日韩日本视频| 一区二区三区四区五区精品视频| 宅男在线国产精品| 欧美视频免费在线| 亚洲视频1区| 欧美一区二区三区在线看| 国产农村妇女精品一区二区| 久久黄色小说| 亚洲人成人99网站| 亚洲欧美日韩精品一区二区| 国产日韩av高清| 久久久久国产免费免费| 亚洲黄色成人| 午夜精品福利电影| 国产一级揄自揄精品视频| 欧美一区二区在线视频| 欧美激情按摩在线| 亚洲欧美日本精品| 在线观看福利一区| 欧美日韩中文字幕在线| 亚洲男同1069视频| 欧美a级大片| 亚洲一区二区3| 国内综合精品午夜久久资源| 欧美精品免费播放| 性欧美8khd高清极品| 欧美黄色影院| 欧美在线播放| 一本色道久久88精品综合| 国产视频在线观看一区 | 亚洲一区二区三区四区视频| 国内偷自视频区视频综合| 蜜桃av噜噜一区二区三区| 一区二区高清视频在线观看| 久久综合色一综合色88| 亚洲夜间福利| 亚洲国产三级在线| 国产精品自拍在线| 欧美精品成人91久久久久久久| 午夜精品美女自拍福到在线 | 欧美精品一区视频| 欧美在线日韩在线| 一区二区三区四区五区精品视频 | 欧美日韩在线视频一区二区| 久久精品夜色噜噜亚洲a∨| 夜夜嗨av一区二区三区四季av| 久久精品国产99| 亚洲摸下面视频| av成人动漫| 尤物在线精品| 国内精品亚洲| 国产一区二区精品| 国产精品一区二区你懂得 | 亚洲精品自在久久|