⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kernel.asm

📁 MenuetOS是一个用汇编开发的32/64位PC操作系统
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;   MenuetOS Copyright 2000-2007 Ville Turjanmaa
;;
;;   See file COPYING for details with these additional details:
;;     - All code written in 32 bit x86 assembly language
;;     - No external code (eg. bios) at process execution time
;;
;;     Ville Turjanmaa, vmt@menuetos.net
;;      - main os coding/design
;;     Jan-Michael Brummer, BUZZ2@gmx.de
;;      - bugfixes in mouse & display drivers
;;      - code for cd-player
;;     Felix Kaiser, info@felix-kaiser.de
;;      - AMD K6-II compatible IRQ's
;;      - APM management
;;     Paolo Minazzi, paolo.minazzi@inwind.it
;;      - Sound Blaster
;;      - Fat32 write
;;     quickcode@mail.ru
;;      - 320x200 palette & convert
;;      - Vesa 1.2 bankswitch for S3 cards
;;     Alexey, kgaz@crosswinds.net
;;      - Voodoo compatible graphics
;;     Juan M. Caravaca, bitrider@wanadoo.es
;;      - Graphics optimizations
;;     kristol@nic.fi
;;      - Bootfix for some Pentium models
;;     Mike Hibbett, mikeh@oceanfree.net
;;      - SLIP driver and TCPIP stack (skeleton)
;;     Lasse Kuusijarvi, kuusijar@lut.fi
;;      - jumptable and modifications for syscalls
;;     Jarek Pelczar, jarekp3@wp.pl
;;      - AMD compatible MTRR's
;;
;;   Compile with FASM 1.50+
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

max_processes      equ   255

window_data        equ   0x0000
tss_data           equ   0x9A0000
tss_step           equ   (128+8192) ; tss & i/o - 65536 ports, * 256=2129920
draw_data          equ   0xC00000
sysint_stack_data  equ   0xC03000

twdw               equ   (0x3000-window_data)

fat_base           equ   0x100000       ; ramdisk base
fat_table          equ   0x280000       ; 0xD80000

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;   Included files:
;;
;;   Kernel16.inc
;;    - Booteng.inc   English text for bootup
;;    - Bootcode.inc  Hardware setup
;;    - Pci16.inc     PCI functions
;;
;;   Kernel32.inc
;;    - Sys32.inc     Process management
;;    - Shutdown.inc  Shutdown and restart
;;    - Fat32.inc     Read / write hd
;;    - Vesa12.inc    Vesa 1.2 driver
;;    - Vesa20.inc    Vesa 2.0 driver
;;    - Vga.inc       VGA driver
;;    - Stack.inc     Network interface
;;    - Mouse.inc     Mouse pointer
;;    - Scincode.inc  Window skinning
;;    - Pci32.inc     PCI functions
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                      ;;
;;                  16 BIT ENTRY FROM BOOTSECTOR                        ;;
;;                                                                      ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

use16

                  org   0x0 ; For 16 bit code

kernel_start:

                  jmp   start_of_code

version           db    'Menuet32 0.84 (c) Ville Turjanmaa',13,10,13,10,0
                  dd    endofcode-0x10000

                  db   'Boot02'

display_modechg   db    0  ; display mode change for text, yes/no (0 or 2)
                           ;
                           ; Important!!
                           ; Must be set to 2, to avoid two screenmode
                           ; changes within a very short period of time.

display_atboot    db    0  ; display text, yes/no (0 or 2)
preboot_graph     db    0  ; graphics mode
preboot_mouse     db    0  ; mouse port
preboot_mtrr      db    0  ; mtrr graphics acceleration
preboot_lfb       db    0  ; linear frame buffer
preboot_blogesc   db    0  ; start immediately after bootlog
preboot_device    db    0  ; load ramdisk from floppy/hd/kernelrestart
preboot_memory    db    0  ; amount of memory
preboot_gprobe    db    0  ; probe with vesa 2.0+



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                      ;;
;;                      16 BIT INCLUDED FILES                           ;;
;;                                                                      ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

include "KERNEL16.INC"

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                      ;;
;;                  SWITCH TO 32 BIT PROTECTED MODE                     ;;
;;                                                                      ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

os_data        equ  os_data_l-gdts    ; GDTs
os_code        equ  os_code_l-gdts
int_code       equ  int_code_l-gdts
int_data       equ  int_data_l-gdts
tss0sys        equ  tss0sys_l-gdts
graph_data     equ  3+graph_data_l-gdts
tss0           equ  tss0_l-gdts
tss0i          equ  tss0i_l-gdts
tss0t          equ  tss0t_l-gdts
app_code       equ  3+app_code_l-gdts
app_data       equ  3+app_data_l-gdts
ring3_data     equ  3+ring3_data_l-gdts
ring3_code     equ  3+ring3_code_l-gdts
ring2_data     equ  2+ring2_data_l-gdts
ring2_code     equ  2+ring2_code_l-gdts
ring1_data     equ  1+ring1_data_l-gdts
ring1_code     equ  1+ring1_code_l-gdts


; CR0 Flags - Protected mode and Paging

        mov     ecx,0x00000001
        and     ebx,65535
        cmp     ebx,00100000000000000b ; lfb -> paging
        jb      no_paging
        mov     ax,0x0000
        mov     es,ax
        mov     al,[es:0x901E]
        cmp     al,1
        je      no_paging
        or      ecx, 0x80000000
       no_paging:

; Enabling 32 bit protected mode

 ;;       sidt    [cs:old_ints_h-0x10000]

        cli                             ; disable all irqs
        cld
        mov     al,255                  ; mask all irqs
        out     0xa1,al
        out     0x21,al
   l.5: in      al, 0x64                ; Enable A20
        test    al, 2
        jnz     l.5
        mov     al, 0xD1
        out     0x64, al
   l.6: in      al, 0x64
        test    al, 2
        jnz     l.6
        mov     al, 0xDF
        out     0x60, al
        lgdt    [cs:gdts-0x10000]       ; Load GDT
        mov     eax, cr0                ; Turn on paging // protected mode
        or      eax, ecx
        and     eax, 10011111b *65536*256 + 0xffffff ; caching enabled
        mov     cr0, eax
        jmp     shortjmp
      shortjmp:
        mov     ax,os_data              ; Selector for os
        mov     ds,ax
        mov     es,ax
        mov     fs,ax
        mov     gs,ax
        mov     ss,ax
        mov     esp,0x2FFFF             ; Set stack
        jmp     pword os_code:B32       ; jmp to enable 32 bit mode

use32

kernel_32bit:

org ( 0x10000 + ( kernel_32bit - kernel_start ) ) 

macro align value { rb (value-1) - ($ + value-1) mod value }

boot_fonts        db   'Fonts loaded',0
boot_tss          db   'Setting TSSs',0
boot_cpuid        db   'Reading CPUIDs',0
boot_devices      db   'Detecting devices',0
boot_timer        db   'Setting timer',0
boot_irqs         db   'Reprogramming IRQs',0
boot_setmouse     db   'Setting mouse',0
boot_windefs      db   'Setting window defaults',0
boot_bgr          db   'Calculating background',0
boot_resirqports  db   'Reserving IRQs & ports',0
boot_setrports    db   'Setting addresses for IRQs',0
boot_setostask    db   'Setting OS task',0
boot_allirqs      db   'Unmasking all IRQs',0
boot_tsc          db   'Reading TSC',0
boot_pal_ega      db   'Setting EGA/CGA 320x200 palette',0
boot_pal_vga      db   'Setting VGA 640x480 palette',0
boot_mtrr         db   'Setting MTRR',0
boot_tasking      db   'All set - press ESC to start',0

boot_y dd 10

boot_log:

         ret

         pusha

         mov   edx,esi
.bll3:   inc   edx
         cmp   [edx],byte 0
         jne   .bll3
         sub   edx,esi
         mov   eax,10*65536
         mov   ax,word [boot_y]
         add   [boot_y],dword 10
         mov   ebx,0xffffff
         mov   ecx,esi
         mov   edi,1
         call  dtext

         mov   [novesachecksum],1000
         call  checkEgaCga

         cmp   [preboot_blogesc],byte 1
         je    .bll2

         cmp   esi,boot_tasking
         jne   .bll2

.bll1:   in    al,0x64
         in    al,0x60
         cmp   al,129
         jne   .bll1

.bll2:   popa

         ret

cpuid_0    dd  0,0,0,0
cpuid_1    dd  0,0,0,0
cpuid_2    dd  0,0,0,0
cpuid_3    dd  0,0,0,0

firstapp   db  'L','A','U','N','C','H','E','R',' ',' ',' '
char       db  'C','H','A','R',' ',' ',' ',' ','M','T',' '
char2      db  'C','H','A','R','2',' ',' ',' ','M','T',' '
hdsysimage db  'M','S','E','T','U','P',' ',' ','E','X','E'
bootpath   db  0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                      ;;
;;                          32 BIT ENTRY                                ;;
;;                                                                      ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

align 4

B32:

; CLEAR 0x280000-0xF00000

        xor   eax,eax
        mov   edi,0x280000
        mov   ecx,(0x100000*0xF-0x280000) / 4
        cld
        rep   stosd

; SAVE & CLEAR 0-0xffff

        mov   esi,0x0000
        mov   edi,0x2F0000
        mov   ecx,0x10000 / 4
        cld
        rep   movsd
        xor   eax,eax
        mov   edi,0
        mov   ecx,0x10000 / 4
        cld
        rep   stosd

; SAVE REAL MODE VARIABLES

        movzx eax,byte [0x2f0000+0x9010]  ; mouse port
        mov   [0xF604],al
        mov   al,[0x2f0000+0x9000]        ; bpp
        mov   [0xFBF1],al
        movzx eax,word [0x2f0000+0x900A]  ; X max
        sub   eax,1
        mov   [0xfe00],eax
        movzx eax,word [0x2f0000+0x900C]  ; Y max
        sub   eax,1
        mov   [0xfe04],eax
        movzx eax,word [0x2f0000+0x9008]  ; screen mode
        mov   [0xFE0C],eax
        mov   eax,[0x2f0000+0x9014]       ; Vesa 1.2 bnk sw add
        mov   [0xE030],eax
        mov   [0xfe08],word 640*4         ; Bytes PerScanLine
        cmp   [0xFE0C],word 0x13          ; 320x200
        je    srmvl1
        cmp   [0xFE0C],word 0x12          ; VGA 640x480
        je    srmvl1
        mov   ax,[0x2f0000+0x9001]        ; for other modes
        mov   [0xfe08],ax
      srmvl1:

; GRAPHICS ADDRESSES

        mov     eax,0x100000*8                    ; LFB address
        cmp     [0xfe0c],word 0x13
        je      no_d_lfb
        cmp     [0xfe0c],word 0x12
        je      no_d_lfb
        cmp     [0x2f0000+0x901e],byte 1
        jne     no_d_lfb
        mov     eax,[0x2f0000+0x9018]
      no_d_lfb:
        mov     [0xfe80],eax

        cmp     [0xfe0c],word 0100000000000000b
        jge     setvesa20
        cmp     [0xfe0c],word 0x13
        je      v20ga32
        mov     [0xe020],dword Vesa12_putpixel24  ; Vesa 1.2
        mov     [0xe024],dword Vesa12_getpixel24
        cmp     [0xfbf1],byte 24
        jz      ga24
        mov     [0xe020],dword Vesa12_putpixel32
        mov     [0xe024],dword Vesa12_getpixel32
      ga24:
        jmp     v20ga24
      setvesa20:
        mov     [0xe020],dword Vesa20_putpixel24  ; Vesa 2.0
        mov     [0xe024],dword Vesa20_getpixel24
        cmp     [0xfbf1],byte 24
        jz      v20ga24
      v20ga32:
        mov     [0xe020],dword Vesa20_putpixel32
        mov     [0xe024],dword Vesa20_getpixel32
      v20ga24:
        cmp     [0xfe0c],word 0x12                ; 16 C VGA 640x480
        jne     no_mode_0x12
        mov     [0xe020],dword VGA_putpixel
        mov     [0xe024],dword Vesa20_getpixel32
      no_mode_0x12:

        mov     eax,[0xfe80]                      ; set for gs
        mov     [graph_data_l+2],ax
        shr     eax,16
        mov     [graph_data_l+4],al
        mov     [graph_data_l+7],ah

; MEMORY MODEL

        mov     [0xfe84],dword 0x100000*18      ; apps mem base address
        movzx   ecx,byte [0x2f0000+0x9030]
        dec     ecx
        mov     eax,32*0x100000
        shl     eax,cl
        mov     [0xfe8c],eax      ; memory for use
        cmp     eax,16*0x100000
        jne     no16mb
        mov     [0xfe84],dword 0x100000*10
      no16mb:

; READ RAMDISK IMAGE FROM HD

        cmp   [boot_dev],byte 1
        jne   no_sys_on_hd

        mov   [fat32part],1       ; Partition
        mov   [hdbase],0x1f0      ; Controller base
        mov   [hdpos],1           ;
        mov   [hdid],0x0          ;
        mov   [0xfe10],dword 0    ; entries in hd cache
        call  set_FAT32_variables

        mov   esi,40
        mov   ecx,fat_base ; 0x100000
      hdbootl1:
        mov   eax,hdsysimage
        mov   edi,12
        mov   ebx,18*2*5
        mov   edx,bootpath

        pusha
        call  file_read
        cmp   eax,0               ; image not found
        jne   $
        popa

        add   ecx,512*18*2*5
        add   esi,18*2*5
        cmp   esi,1474560/512+41-1
        jb    hdbootl1
      no_sys_on_hd:


; CALCULATE FAT CHAIN FOR RAMDISK

        call  calculatefatchain

; LOAD FONTS I and II

        mov   [0x3000],dword 1
        mov   [0x3004],dword 1
        mov   [0x3010],dword 0x3020

        mov   eax,char
        mov   esi,12
        mov   ebx,0
        mov   ecx,26000
        mov   edx,0x37000
        call  fileread

        mov   eax,char2
        mov   esi,12
        mov   ebx,0
        mov   ecx,26000
        mov   edx,0x30000
        call  fileread

        mov   esi,boot_fonts
        call  boot_log

; REDIRECT ALL IRQ'S TO INT'S 0x20-0x2f

        mov   esi,boot_irqs
        call  boot_log
        call  rerouteirqs

        mov    esi,boot_tss
        call   boot_log

; BUILD SCHEDULER

        call   build_scheduler ; sys32.inc

; LOAD IDT

         lidt  [cs:idts]

; READ CPUID RESULT

        mov     esi,boot_cpuid
        call    boot_log
        pushfd                  ; get current flags
        pop     eax
        mov     ecx,eax
        xor     eax,0x00200000  ; attempt to toggle ID bit
        push    eax
        popfd
        pushfd                  ; get new EFLAGS
        pop     eax
        push    ecx             ; restore original flags
        popfd
        and     eax,0x00200000  ; if we couldn't toggle ID,
        and     ecx,0x00200000  ; then this is i486
        cmp     eax,ecx
        jz      nopentium
        ; It's Pentium or later. Use CPUID
        mov     edi,cpuid_0
        mov     esi,0
      cpuid_new_read:
        mov     eax,esi
        cpuid
        call    cpuid_save
        add     edi,4*4
        cmp     esi,3
        jge     cpuid_done
        cmp     esi,[cpuid_0]
        jge     cpuid_done
        inc     esi
        jmp     cpuid_new_read
      cpuid_save:
        mov     [edi+00],eax
        mov     [edi+04],ebx
        mov     [edi+8],ecx
        mov     [edi+12],edx
        ret
      cpuid_done:
      nopentium:

; CR4 flags - enable fxsave / fxrstore
;
;        finit
;        mov     eax,1
;        cpuid
;        test    edx,1000000h
;        jz      fail_fpu
;        mov     eax,cr4
;        or      eax,200h        ; Enable fxsave/fxstor
;        mov     cr4,eax
;     fail_fpu:

; DETECT DEVICES

        mov    esi,boot_devices
        call   boot_log
        call   detect_devices

 ; TIMER SET TO 1/100 S

        mov   esi,boot_timer
        call  boot_log
        mov   al,0x34              ; set to 100Hz
        out   0x43,al
        mov   al,0x9b              ; lsb    1193180 / 1193
        out   0x40,al
        mov   al,0x2e              ; msb
        out   0x40,al

; SET MOUSE

        mov   esi,boot_setmouse
        call  boot_log

        call  setmouse

; SET PRELIMINARY WINDOW STACK AND POSITIONS

        mov   esi,boot_windefs
        call  boot_log
        call  setwindowdefaults

; SET BACKGROUND DEFAULTS

        mov   esi,boot_bgr
        call  boot_log
        call  calculatebackground

; RESERVE SYSTEM IRQ'S JA PORT'S

        mov   esi,boot_resirqports
        call  boot_log
        call  reserve_irqs_ports

; SET PORTS FOR IRQ HANDLERS

        mov  esi,boot_setrports
        call boot_log
        call setirqreadports

; SET UP OS TASK

        mov  esi,boot_setostask
        call boot_log
        ; name for OS/IDLE process
        mov  [0x80000+256+0],dword 'OS/I'
        mov  [0x80000+256+4],dword 'DLE '
        ; task list
        mov  [0x3004],dword 2         ; number of processes
        mov  [0x3000],dword 0         ; process count - start with os task
        mov  [0x3020+0xE],byte  1     ; on screen number
        mov  [0x3020+0x4],dword 1     ; process id number

        ; set default flags & stacks
        mov  [l.eflags],dword 0x11202 ; sti and resume
        mov  [l.ss0], os_data
        mov  [l.ss1], ring1_data
        mov  [l.ss2], ring2_data
        mov  [l.esp0], 0x52000
        mov  [l.esp1], 0x53000
        mov  [l.esp2], 0x54000
        ; osloop - TSS
        mov  eax,cr3
        mov  [l.cr3],eax
        mov  [l.eip],osloop
        mov  [l.esp],0x2ffff
        mov  [l.cs],os_code
        mov  [l.ss],os_data
        mov  [l.ds],os_data
        mov  [l.es],os_data
        mov  [l.fs],os_data
        mov  [l.gs],os_data
        ; move tss to tss_data+tss_step
        mov  esi,tss_sceleton
        mov  edi,tss_data+tss_step
        mov  ecx,120/4
        cld
        rep  movsd

        mov  ax,tss0
        ltr  ax

; READ TSC / SECOND

        mov   esi,boot_tsc
        call  boot_log
        call  _rdtsc
        mov   ecx,eax
        mov   esi,250               ; wait 1/4 a second
        call  delay_ms
        call  _rdtsc
        sub   eax,ecx
        shl   eax,2
        mov   [0xf600],eax          ; save tsc / sec

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -