• <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>
            posts - 2, comments - 3, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

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

            Posted on 2009-02-25 15:54 bpt 閱讀(1197) 評論(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 消滅零回復
            任務如題
            色偷偷偷久久伊人大杳蕉| 东方aⅴ免费观看久久av| 亚洲中文久久精品无码| 久久精品人妻一区二区三区| 久久香蕉一级毛片| 97久久精品人妻人人搡人人玩| 香蕉久久av一区二区三区| 久久久黄色大片| 久久久精品久久久久影院| 久久久国产视频| 思思久久99热只有频精品66| 九九久久精品无码专区| 国产午夜电影久久| 久久一本综合| 欧美日韩精品久久免费| 亚洲综合伊人久久大杳蕉| 嫩草伊人久久精品少妇AV| 国内精品久久久久久99| 久久久久久免费一区二区三区| 久久夜色精品国产亚洲| 精品久久久久久无码免费| 欧美粉嫩小泬久久久久久久| 色综合久久88色综合天天 | 久久精品亚洲AV久久久无码| 日本人妻丰满熟妇久久久久久| 国产69精品久久久久777| 国内精品久久久久久久涩爱| 中文字幕久久亚洲一区| 伊人久久精品无码av一区| 久久精品国产99国产精偷| 久久精品国产只有精品66| 久久精品免费全国观看国产| 国产综合久久久久| 久久99久久无码毛片一区二区| 亚洲伊人久久综合影院| 99麻豆久久久国产精品免费| 久久天天躁狠狠躁夜夜av浪潮| 久久亚洲精品无码VA大香大香| 国产精品视频久久| 亚洲国产视频久久| 一本久久久久久久|