├── .gitignore ├── compiler ├── compile.sh ├── arch │ ├── arch.ss │ └── x86-os.ss └── compile.ss ├── tests └── test-libs.ss ├── libs ├── math.ss ├── logic.ss ├── mem.ss ├── string.ss ├── bits.ss └── print.ss ├── kernel ├── kalloc.ss ├── task.ss ├── main.ss └── asm.ss ├── LICENSE ├── Makefile ├── bochsrc ├── start ├── boot.ss └── init.ss └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.ss~ 2 | *.ss#* 3 | .#*.ss 4 | 5 | *.scm~ 6 | *.scm#* 7 | .#*.scm 8 | 9 | build/** 10 | 11 | *.log -------------------------------------------------------------------------------- /compiler/compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export CHEZSCHEMELIBDIRS=.:../compiler:../../duck-compiler/ 3 | cd build && scheme --script ../compiler/$1 $2 $3 -------------------------------------------------------------------------------- /tests/test-libs.ss: -------------------------------------------------------------------------------- 1 | ($include "../libs/string.ss") 2 | ($include "../libs/math.ss") 3 | ($include "../libs/logic.ss") 4 | ($include "../libs/print.ss") 5 | 6 | 7 | -------------------------------------------------------------------------------- /libs/math.ss: -------------------------------------------------------------------------------- 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2 | ;Copyright 2016-2080 evilbinary. 3 | ;作者:evilbinary on 12/24/16. 4 | ;邮箱:rootdebug@163.com 5 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 6 | 7 | (define (mod a b) 8 | (begin 9 | (/ a b) ;;dx 10 | ($asm 11 | (set reg0 reg3) 12 | )) 13 | ) 14 | -------------------------------------------------------------------------------- /libs/logic.ss: -------------------------------------------------------------------------------- 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2 | ;Copyright 2016-2080 evilbinary. 3 | ;作者:evilbinary on 12/24/16. 4 | ;邮箱:rootdebug@163.com 5 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 6 | 7 | (define (and a b) 8 | (if a (if b #t #f) #f)) 9 | 10 | (define (or a b) 11 | (if a #t (if b #t #f))) 12 | 13 | (define (not a) 14 | (if a #f #t) 15 | ) -------------------------------------------------------------------------------- /kernel/kalloc.ss: -------------------------------------------------------------------------------- 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2 | ;Copyright 2016-2080 evilbinary. 3 | ;作者:evilbinary on 12/24/16. 4 | ;邮箱:rootdebug@163.com 5 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 6 | 7 | ;;内存分配 8 | (define (kalloc-frame-int) 9 | 1 10 | ) 11 | 12 | (define (kalloc-frame) 13 | 1 14 | ) 15 | 16 | (define (kfree-frame a) 17 | 1 18 | ) 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /kernel/task.ss: -------------------------------------------------------------------------------- 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2 | ;Copyright 2016-2080 evilbinary. 3 | ;作者:evilbinary on 12/24/16. 4 | ;邮箱:rootdebug@163.com 5 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 6 | ;;任务 7 | (define (kernel-idle-task) 8 | (loop-forever) 9 | ) 10 | ;;当前任务ptr 11 | ;;task 0 ip 12 | ;;task 1 esp 13 | ;;task 2 id 14 | (define current-taskp 0) 15 | (define next-taskp 0) -------------------------------------------------------------------------------- /libs/mem.ss: -------------------------------------------------------------------------------- 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2 | ;Copyright 2016-2080 evilbinary. 3 | ;作者:evilbinary on 12/24/16. 4 | ;邮箱:rootdebug@163.com 5 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 6 | ;;mem set value 4byte 7 | (define (mem-set addr value) 8 | ($asm 9 | (set reg0 (local 0)) 10 | (set reg1 (local 1)) 11 | (sar reg0 3) 12 | (sar reg1 3) 13 | (mset reg0 reg1))) 14 | 15 | ;;mem get value 16 | (define (mem-ref addr) 17 | ($asm 18 | (set reg0 (local 0)) 19 | (sar reg0 3) 20 | (mref reg0 reg0) 21 | (sal reg0 3) 22 | (add reg0 #b000) 23 | )) 24 | -------------------------------------------------------------------------------- /compiler/arch/arch.ss: -------------------------------------------------------------------------------- 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2 | ;Copyright 2016-2080 evilbinary. 3 | ;作者:evilbinary on 12/24/16. 4 | ;邮箱:rootdebug@163.com 5 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 6 | 7 | (library (arch arch) 8 | (export 9 | ;;regs 10 | reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 regs regs-map 11 | ;;instruct 12 | asm set mref mset note 13 | add label sar sal mul sub div 14 | shl shr ret 15 | call jmp cmp-jmp cmp 16 | land lor xor save restore 17 | nop local proc lproc lret pret 18 | fcall ccall 19 | stext sexit 20 | data sdata 21 | asm-compile-exp 22 | arch-bits 23 | ) 24 | 25 | (import 26 | (common common) 27 | (common match) 28 | (common trace) 29 | (arch x86-os) 30 | ) 31 | ) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 evilbinary 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ########################################################################################## 2 | # Project: Duck OS 3 | # Makefile evilbinary 4 | # Mail:rootntsd@gmail.com 5 | ########################################################################################## 6 | 7 | .PHONY: build 8 | 9 | build: start main 10 | @echo "build success" 11 | test: 12 | ./compiler/compile.sh compile.ss tests/test-libs 13 | 14 | 15 | main: kernel/main.ss kernel/asm.ss kernel/kalloc.ss kernel/task.ss 16 | ./compiler/compile.sh compile.ss kernel/main 17 | 18 | start: boot init 19 | @echo build start success 20 | 21 | boot: start/boot.ss 22 | ./compiler/compile.sh compile.ss start/boot 23 | 24 | init: start/init.ss 25 | ./compiler/compile.sh compile.ss start/init 26 | 27 | run: image 28 | bochs -q -f ./bochsrc 29 | 30 | runq: image 31 | qemu-system-i386 -fda build/duck.img 32 | 33 | image: build 34 | dd if=build/start/boot bs=512 count=1 conv=notrunc of=build/duck.img 35 | dd if=build/start/init bs=512 count=10 seek=1 conv=notrunc of=build/duck.img 36 | dd if=build/kernel/main bs=512 count=10 seek=9 conv=notrunc of=build/duck.img 37 | 38 | 39 | clean: 40 | rm -rf build/start/* 41 | rm -rf build/kernel/* 42 | -------------------------------------------------------------------------------- /libs/string.ss: -------------------------------------------------------------------------------- 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2 | ;Copyright 2016-2080 evilbinary. 3 | ;作者:evilbinary on 12/24/16. 4 | ;邮箱:rootdebug@163.com 5 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 6 | 7 | ;;字符串长度 8 | (define (string-length str) 9 | (let loop3 ([x 0]) 10 | (if (= (string-ref str x) 0) 11 | x 12 | (loop3 (+ x 1) )) 13 | ) 14 | ) 15 | 16 | ;;字符串获取 17 | (define (string-ref str i) 18 | ($asm 19 | (set reg0 (local 0)) 20 | (set reg1 (local 1)) 21 | (sar reg0 3);;cast to raw type 22 | (sar reg1 3) 23 | (+ reg0 reg1) 24 | (mref reg0 reg0) 25 | (land reg0 #xff) 26 | (sal reg0 3) 27 | (add reg0 #b000) 28 | ) 29 | ) 30 | 31 | ;;字符串设置 32 | (define (string-set! str i val) 33 | ($asm 34 | (set reg0 (local 0)) 35 | (set reg1 (local 1)) 36 | (sar reg0 3);;cast to raw type 37 | (sar reg1 3) 38 | (+ reg0 reg1) 39 | (set reg1 (local 2)) 40 | (sar reg1 3) 41 | (mset reg0 reg1 byte) 42 | ) 43 | ) -------------------------------------------------------------------------------- /libs/bits.ss: -------------------------------------------------------------------------------- 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2 | ;Copyright 2016-2080 evilbinary. 3 | ;作者:evilbinary on 12/24/16. 4 | ;邮箱:rootdebug@163.com 5 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 6 | ;;bit opts 7 | (define (bit-shift-left x bit) 8 | ($asm 9 | (set reg0 (local 0)) 10 | (set reg1 (local 1)) 11 | (sar reg0 3);;cast to raw type 12 | (sar reg1 3) 13 | (sal reg0 reg1) 14 | (sal reg0 3) 15 | (add reg0 #b000) 16 | ) 17 | ) 18 | 19 | (define (bit-shift-right x bit) 20 | ($asm 21 | (set reg0 (local 0)) 22 | (set reg1 (local 1)) 23 | (sar reg0 3);;cast to raw type 24 | (sar reg1 3) 25 | (sar reg0 reg1) 26 | (sal reg0 3) 27 | (add reg0 #b000) 28 | ) 29 | ) 30 | 31 | (define (bit-and x y) 32 | ($asm 33 | (set reg0 (local 0)) 34 | (set reg1 (local 1)) 35 | (sar reg0 3);;cast to raw type 36 | (sar reg1 3) 37 | (land reg0 reg1) 38 | (sal reg0 3) 39 | (add reg0 #b000) 40 | ) 41 | ) 42 | 43 | (define (bit-or x y) 44 | ($asm 45 | (set reg0 (local 0)) 46 | (set reg1 (local 1)) 47 | (sar reg0 3);;cast to raw type 48 | (sar reg1 3) 49 | (lor reg0 reg1) 50 | (sal reg0 3) 51 | (add reg0 #b000) 52 | ) 53 | ) -------------------------------------------------------------------------------- /compiler/compile.ss: -------------------------------------------------------------------------------- 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2 | ;Copyright 2016-2080 evilbinary. 3 | ;作者:evilbinary on 12/24/16. 4 | ;邮箱:rootdebug@163.com 5 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 6 | (import (scheme) (duck duck) 7 | (duck options) 8 | (arch x86-os)) 9 | 10 | (define (read-file name) 11 | (let ((p (open-input-file name))) 12 | (let f ((x (read p))) 13 | (if (eof-object? x) 14 | (begin 15 | (close-input-port p) 16 | '()) 17 | (cons x (f (read p))))))) 18 | 19 | (define (compile-file name) 20 | (let ((code (read-file (format "../~a.ss" name)))) 21 | (printf "compile ~a\n ===>" name) 22 | (pretty-print code ) 23 | (duck-compile-exp `(begin ,@code ) name) 24 | )) 25 | 26 | (define (compile-files names) 27 | (let loop ([name names]) 28 | (if (pair? name) 29 | (begin 30 | (printf "file-name=>~a\n" (car name) ) 31 | (if (equal? (car name) "start/boot") 32 | (begin 33 | (option-set 'need-boot #t) 34 | (compile-file (car name)) 35 | ) 36 | (begin 37 | (option-set 'need-boot #f) 38 | (compile-file (car name)) 39 | ) 40 | ) 41 | (loop (cdr name)) 42 | )))) 43 | 44 | (define file-names '()) 45 | 46 | (define (process-args) 47 | (if (>= (length (command-line)) 1) 48 | (set! file-names (list-tail (command-line) 1)) 49 | )) 50 | 51 | (process-args) 52 | (option-set 'need-primitive #f) 53 | (compile-files file-names) 54 | 55 | 56 | -------------------------------------------------------------------------------- /bochsrc: -------------------------------------------------------------------------------- 1 | ############################################################### 2 | # bochsrc.txt file for DLX Linux disk image. 3 | ############################################################### 4 | 5 | # how much memory the emulated machine will have 6 | megs: 32 7 | magic_break: enabled=1 8 | 9 | # filename of ROM images 10 | romimage: file=$BXSHARE/BIOS-bochs-latest 11 | vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest 12 | 13 | # what disk images will be used 14 | floppya: 1_44=build/duck.img, status=inserted 15 | #floppyb: 1_44=floppyb.img, status=inserted 16 | 17 | # hard disk 18 | #ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 19 | #ata0-master: type=disk, path="hd10meg.img", cylinder#s=306, heads=4, spt=17 20 | 21 | # choose the boot disk. 22 | boot: a 23 | 24 | # default config interface is textconfig. 25 | #config_interface: textconfig 26 | #config_interface: wx 27 | 28 | display_library: sdl 29 | #display_library: x, options="gui_debug" 30 | 31 | #display_library: x 32 | # other choices: win32 sdl wx carbon amigaos beos macintosh nogui rfb term svga 33 | 34 | # where do we send log messages? 35 | log: build/bochsout.log 36 | 37 | # disable the mouse, since DLX is text only 38 | mouse: enabled=0 39 | 40 | #gdbstub: enabled=1, port=1234, text_base=0, data_base=0, bss_base=0 41 | # enable key mapping, using US layout as default. 42 | # 43 | # NOTE: In Bochs 1.4, keyboard mapping is only 100% implemented on X windows. 44 | # However, the key mapping tables are used in the paste function, so 45 | # in the DLX Linux example I'm enabling keyboard_mapping so that paste 46 | # will work. Cut&Paste is currently implemented on win32 and X windows only. 47 | 48 | #keyboard_mapping: enabled=1, map=$BXSHARE/keymaps/x11-pc-fr.map 49 | #keyboard_mapping: enabled=1, map=$BXSHARE/keymaps/x11-pc-de.map 50 | #keyboard_mapping: enabled=1, map=$BXSHARE/keymaps/x11-pc-es.map 51 | -------------------------------------------------------------------------------- /libs/print.ss: -------------------------------------------------------------------------------- 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2 | ;Copyright 2016-2080 evilbinary. 3 | ;作者:evilbinary on 12/24/16. 4 | ;邮箱:rootdebug@163.com 5 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 6 | ;;打印一个字符 7 | (define (print-char ch x y) 8 | ($asm 9 | (save reg0) 10 | (save reg5) 11 | (set reg5 #xb8000) 12 | (set reg0 (local 1)) ;;x 13 | (sar reg0 2) ;;cast to raw type 14 | (add reg0 reg5) 15 | (set reg5 reg0) 16 | 17 | (set reg0 (local 2)) ;;y 18 | (sar reg0 3) ;;cast to raw type 19 | (mul reg0 1280) 20 | (add reg0 reg5) 21 | (set reg5 reg0) 22 | 23 | (set reg0 (local 0)) ;;ch 24 | (sar reg0 3);;cast to raw type 25 | (mset reg5 r0) 26 | (restore reg5) 27 | (restore reg0) 28 | )) 29 | 30 | (define cursor-y 0) 31 | (define cursor-x 0) 32 | 33 | ;;打印字符串 34 | (define (print-string str) 35 | (let loop2 ([x 0] [len (string-length str)]) 36 | (if (< x len) 37 | (begin 38 | (print-char (+ #x4f00 (string-ref str x)) (+ x cursor-x) cursor-y ) 39 | (loop2 (+ x 1) len ))) 40 | ) 41 | ) 42 | 43 | (define (print-string-len str l sx sy) 44 | (let print-string-len-loop ([x 0] [len l]) 45 | (if (< x len) 46 | (begin 47 | (print-char (+ #x4f00 (string-ref str x)) (+ x sx) sy ) 48 | (print-string-len-loop (+ x 1) len ))) 49 | ) 50 | ) 51 | 52 | ;;打印十六进制 53 | (define (print-hex val x y) 54 | (print-base val 16 x y)) 55 | 56 | (define (print-base val base x y) 57 | (let print-loop ([i 8] [v val] [buf "0000000000000000000000000000000000"]) 58 | (if (and (> i 0) (> val 0)) 59 | (begin 60 | (string-set! buf i (string-ref "0123456789abcdef" (mod v base) )) 61 | (print-loop (- i 1) (/ v base) buf) 62 | ) 63 | (print-string-len buf 9 x y) 64 | ))) 65 | 66 | -------------------------------------------------------------------------------- /kernel/main.ss: -------------------------------------------------------------------------------- 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2 | ;Copyright 2016-2080 evilbinary. 3 | ;作者:evilbinary on 12/24/16. 4 | ;邮箱:rootdebug@163.com 5 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 6 | 7 | ($asm 8 | (asm "org 0x8000") 9 | (asm "bits 32") 10 | ) 11 | 12 | ;;运行 13 | ;;(print-char #x4f61 2 2) 14 | ; (print-string "hello,world" 0 0) 15 | ; (print-string "gaga" 0 1) 16 | 17 | ;;打印 18 | ;;(print-char (+ #x4f00 #x60 (mod 8 3)) 0 6) 19 | ;;(print-hex (mem-ref #x3000) 6 2) 20 | ; (print-base 1234 10 0 6) 21 | ;;(print-mem-info) 22 | 23 | 24 | ;;任务 25 | (gdt-set-base-limit #x3400 #xffffff #x89) 26 | 27 | ($data tcb-task0 0 32) 28 | ($data tcb-task1 0 32) 29 | ($data tcb-task2 0 32) 30 | 31 | (mem-set &tcb-task0 &tt0) 32 | (mem-set &tcb-task1 &tt1) 33 | (mem-set &tcb-task2 &tt2) 34 | 35 | (task-init &tcb-task0) 36 | 37 | ;; loop forever 38 | (loop-forever) 39 | 40 | ;;内存分配 41 | (define mem-info #x3000) 42 | (define alloc-frame-start #x9000) 43 | (define gdt-info #x3200) 44 | 45 | ;;print mem info 46 | (define (print-mem-info) 47 | (let print-mem-info-loop ([i 0] [count (mem-ref #x3000)]) 48 | (if (< i count) 49 | (begin 50 | (print-hex (mem-ref (+ #x3004 (* i 4 6))) 0 i ) ;;BaseL 51 | ; (print-hex (mem-ref (+ #x3012 (* i 4 6))) 18 i ) ;;Length 52 | ; (print-hex (mem-ref (+ #x3020 (* i 4 6))) 40 i ) ;;Type 53 | (print-mem-info-loop (+ i 1) count) 54 | ) 55 | ) 56 | ) 57 | ) 58 | 59 | 60 | ;;task define 61 | (define (task0) 62 | (begin 63 | ($asm (label tt0)) 64 | (print-string "task0" 0 5) 65 | (mem-set &next-taskp &tcb-task1) 66 | ($asm (jmp switch-to)) 67 | )) 68 | 69 | (define (task1) 70 | (begin 71 | ($asm (label tt1)) 72 | (print-string "task1" 0 10) 73 | (mem-set &next-taskp &tcb-task2) 74 | ($asm (jmp switch-to)) 75 | )) 76 | 77 | (define (task2) 78 | (begin 79 | ($asm (label tt2)) 80 | (print-string "task2" 0 10) 81 | (mem-set &next-taskp &tcb-task0) 82 | ($asm (jmp switch-to)) 83 | )) 84 | 85 | 86 | ;;libs 87 | ($include "../libs/bits.ss") 88 | ($include "../libs/mem.ss") 89 | ($include "../libs/print.ss") 90 | ($include "../libs/string.ss") 91 | ($include "../libs/math.ss") 92 | ($include "../libs/logic.ss") 93 | 94 | ;;kernel 95 | ($include "../kernel/asm.ss") 96 | ($include "../kernel/kalloc.ss") 97 | ($include "../kernel/task.ss") 98 | 99 | -------------------------------------------------------------------------------- /start/boot.ss: -------------------------------------------------------------------------------- 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2 | ;Copyright 2016-2080 evilbinary. 3 | ;作者:evilbinary on 12/24/16. 4 | ;邮箱:rootdebug@163.com 5 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 6 | (begin 7 | ; (define add 8 | ; (lambda (a b) 9 | ; (+ a b))) 10 | ($asm 11 | (asm "%define init_base 0x0500") 12 | (asm "bits 16") 13 | (call cli) 14 | (call cls) 15 | 16 | (asm "mov dx,0x0000") 17 | (call set-cursor) 18 | 19 | (asm "mov si,boot") 20 | (asm "call print.string") 21 | 22 | (asm "mov bx,init_base") 23 | (call disk-load) 24 | 25 | ; (asm "mov ax,0x0000") 26 | ; (asm "mov es,ax") 27 | (asm "mov si,0x200") 28 | (asm "call print.string") 29 | 30 | ;;跳转loader地址 31 | (asm "jmp init_base") 32 | 33 | (asm "jmp $") 34 | 35 | ;;磁盘读取到内存 es:bx 地址 36 | (label disk-load) 37 | (asm "mov ah,0x02 ;读取功能") 38 | (asm "mov al,0x01 ;读取几个扇区") 39 | (asm "mov cl,0x02 ;0x01 boot sector, 0x02 is first sector") 40 | (asm "mov ch,0x00") 41 | (asm "mov dh,0x00") 42 | (asm "mov dl,0x00 ;软盘0") 43 | (asm "int 0x13") 44 | (asm "jc disk.error") 45 | (asm "jmp dend") 46 | (label disk-error) 47 | (asm "mov si,disk.erro") 48 | (asm "call print.string") 49 | (label dend) 50 | (asm "ret") 51 | 52 | ;;设置光标位置 DH=列,DL=行 53 | (label set-cursor) 54 | (asm "mov ah,0x02 ;光标位置初始化") 55 | (asm "mov bh,0") 56 | (asm "int 0x10") 57 | (asm "ret") 58 | 59 | ;;清除屏幕 60 | (label cls) 61 | (asm "mov ah,0x06 ;清除屏幕 ") 62 | (asm "mov al,0") 63 | (asm "mov cx,0 ") 64 | (asm "mov dx,0xffff ") 65 | (asm "mov bh,0x0f ;属性为白字") 66 | (asm "int 0x10") 67 | (asm "ret") 68 | 69 | ;;打印一个字符 al=ascii值 70 | (label print-char) 71 | (asm "mov ah,0eh") 72 | (asm "mov bx,0007h") 73 | (asm "int 0x10") 74 | (asm "ret") 75 | 76 | ;;打印字符串 si=字符地址 77 | (label print-string) 78 | (label ps) 79 | (asm "mov al,[si]") 80 | (asm "inc si") 81 | (asm "or al,al") 82 | (asm "jz pend") 83 | (asm "call print.char") 84 | (asm "jmp ps") 85 | (label pend) 86 | (asm "ret") 87 | 88 | ;;关中断 89 | (label cli) 90 | (asm "cli") 91 | (asm "ret") 92 | 93 | (data boot "boot hello") 94 | (data disk.erro "read disk erro") 95 | 96 | ) 97 | 98 | ) 99 | 100 | -------------------------------------------------------------------------------- /compiler/arch/x86-os.ss: -------------------------------------------------------------------------------- 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2 | ;Copyright 2016-2080 evilbinary. 3 | ;作者:evilbinary on 12/24/16. 4 | ;邮箱:rootdebug@163.com 5 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 6 | (library (arch x86-os) 7 | (export 8 | reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 regs regs-map 9 | 10 | asm set mref mset note 11 | add label sar sal mul sub div 12 | shl shr ret 13 | call jmp cmp-jmp cmp 14 | land lor xor save restore 15 | nop local proc lproc lret pret 16 | 17 | fcall ccall 18 | stext sexit 19 | asm-compile-exp 20 | data sdata 21 | arch-bits 22 | 23 | ) 24 | 25 | (import 26 | (rename (scheme) (div div2) ) 27 | (common common) 28 | (common trace) 29 | (duck type) 30 | (duck options) 31 | (common logger) 32 | (rename (arch x86) 33 | (asm $asm) 34 | (stext $stext) 35 | (sdata $sdata) 36 | (asm-compile-exp $asm-comile-exp) 37 | ) 38 | ) 39 | 40 | (define (stext arg) 41 | (if (equal? arg 'start) 42 | (begin 43 | (if (option-get 'need-boot) 44 | (asm "org 7c00h") 45 | 46 | ) 47 | ; (asm "section .text") 48 | (asm "_start:") 49 | ) 50 | (asm "") 51 | ) 52 | ) 53 | 54 | (define (asm-compile-exp exp name) 55 | (let ((asm (format "`which nasm` ~a.s -f bin -o ~a #-l ~a.lst" name name name))) 56 | ;;(printf "~a\n" asm) 57 | (system asm) 58 | ) 59 | ) 60 | 61 | (define (gen-define) 62 | (let-values ([(keyvec valvec) (hashtable-entries (get-asm-data-define))]) 63 | (vector-for-each 64 | (lambda (key val) 65 | (data key val)) 66 | keyvec valvec)) 67 | ) 68 | 69 | (define (sdata arg) 70 | (if (equal? arg 'end) 71 | (begin 72 | (if (option-get 'need-boot) 73 | (begin 74 | (asm "times 510-($-$$) db 0") 75 | (asm "dw 0xaa55")) 76 | 77 | )) 78 | (if (option-get 'need-boot) 79 | (gen-define) 80 | ($sdata arg) 81 | )) 82 | ) 83 | 84 | (define (asm . args) 85 | (note "asm args =~a" args) 86 | (cond 87 | [(string? (car args)) 88 | (begin 89 | (apply printf args) 90 | (newline )) 91 | ] 92 | [(pair? (car args)) 93 | (cond 94 | [(= (length (car args)) 1) 95 | (asm "~a" (caar args)) 96 | ] 97 | [(= (length (car args)) 2) 98 | (asm "~a ~a" (caar args) (operands-rep (cadar args))) 99 | ] 100 | [(= (length (car args)) 3) 101 | (asm "~a ~a,~a" (caar args) (operands-rep (cadar args)) (operands-rep (caddar args)) ) 102 | ] 103 | [else 104 | (error 'x86-os "not support" args) 105 | ] 106 | ) 107 | ] 108 | [else 109 | (error 'x86-os "not support" args) 110 | ] 111 | ) 112 | ) 113 | 114 | 115 | ) -------------------------------------------------------------------------------- /kernel/asm.ss: -------------------------------------------------------------------------------- 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2 | ;Copyright 2016-2080 evilbinary. 3 | ;作者:evilbinary on 12/24/16. 4 | ;邮箱:rootdebug@163.com 5 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 6 | 7 | 8 | (define (magic-break) 9 | ($asm (asm "xchg bx,bx")) 10 | ) 11 | 12 | (define (loop-forever) 13 | ($asm 14 | (label forever) 15 | (asm (nop)) 16 | (asm (hlt)) 17 | (jmp forever)) 18 | ) 19 | 20 | 21 | (define (task-init tcb) 22 | ($asm 23 | (asm "cli") 24 | (asm "mov ebx,0x4000") 25 | (asm "mov esi,0x3400") 26 | (asm "mov [esi+0x1c],ebx");;cr3 27 | (asm "mov word [esi+0x50],0x10");;ss 28 | (asm "mov word [esi+0x4c],0x08");;cs 29 | (asm "mov word [esi+0x54],0x10");;ds 30 | (asm "mov word [esi+0x38],0x3800");;esp 31 | (asm "mov word [esi+0x3c],0x3800");;ebp 32 | 33 | (asm "mov word [esi+0x00],0x3400");;link 34 | 35 | (set reg0 (local 0)) 36 | (sar reg0 3) 37 | ;;(asm "xchg bx,bx") 38 | 39 | (asm "mov [current.taskp],eax");;set current task ptr 40 | (asm "mov edi,eax") 41 | (asm "mov eax,[edi]") ;;get tcb eip 42 | (asm "mov [esi+0x20],eax");;eip 43 | ;;(asm "sti") 44 | ;;(asm "xchg bx,bx") 45 | (asm "jmp 0x20:0") 46 | 47 | ) 48 | ) 49 | 50 | ($asm 51 | (label switch-to) 52 | 53 | ;;(asm "cli") 54 | (asm "mov esi,0x3400") 55 | (asm "mov edi,[current.taskp]");;get current task info 56 | (asm "mov eax,[esi+0x20]");;get eip 57 | (asm "mov [edi],eax");;save eip into current task 58 | (asm "mov eax,[esi+0x38]") ;;get esp 59 | (asm "mov [edi+4],eax") ;;save esp into current task 60 | 61 | 62 | (asm "mov edi,[next.taskp]") 63 | (asm "mov [current.taskp],edi");;set current task ptr 64 | 65 | (asm "mov eax,[edi+4]") ;;get new esp 66 | (asm "mov [esi+0x38],eax") 67 | 68 | (asm "mov eax,[edi]") ;;get new eip 69 | (asm "mov [esi+0x20],eax") 70 | 71 | ;;(asm "sti") 72 | 73 | ;;(asm "xchg bx,bx") 74 | (asm "jmp eax") 75 | ) 76 | 77 | 78 | ;;gdt u32 base u32 limit u16 type 79 | (define (gdt-set-base-limit base limit type) 80 | ($asm 81 | (set reg3 #x3200) 82 | (mref reg3 reg3) 83 | 84 | (set reg0 (local 0));;base 85 | (set reg1 (local 1));;limit 86 | (sar reg0 3);;cast to val 87 | (sar reg1 3);;cast to val 88 | (sal reg0 16);;basel 89 | (land reg1 #x0000FFFF);;limitl 90 | (lor reg0 reg1);;low 91 | 92 | (add reg3 #x20) 93 | (mset reg3 reg0);;set low 94 | 95 | (set reg1 (local 1)) 96 | (sar reg1 3);;cast to val 97 | (land reg1 #x000F0000) 98 | (sal reg2 8) 99 | (land reg2 #x00F0FF00) 100 | (lor reg1 reg2) 101 | 102 | (set reg0 (local 0)) 103 | (sar reg0 3);;cast to val 104 | (sar reg0 16) 105 | (land reg0 #x000000FF);;limit 106 | 107 | (set reg2 (local 0)) 108 | (sar reg2 3);;cast to val 109 | (land reg2 #xFF000000) 110 | (lor reg0 reg2);;hi 111 | 112 | (add reg3 #x20) 113 | (mset reg3 reg0);;set hi 114 | 115 | ) 116 | ; (let ([gdt-addr (+ (mem-ref #x3200) #x20)]) 117 | ; (let ([low (bit-or (bit-shift-left base 16) 118 | ; (bit-and limit #x0000FFFF))] 119 | ; [hi (bit-or (bit-or (bit-and limit #x000F0000) 120 | ; (bit-and (bit-shift-left type 8) #x00F0FF00)) 121 | ; (bit-or (bit-and (bit-shift-right base 16) #x000000FF) 122 | ; (bit-and base #xFF000000)) 123 | ; ) ]) 124 | 125 | ; (mem-set gdt-addr low) 126 | ; (mem-set (+ gdt-addr 1) hi) 127 | ; ) 128 | ; ) 129 | ) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # duck-os 2 | 基于scheme写的os 3 | 4 | ## 使用 5 | 6 | ### 编译 7 | 提前安装 bochs 8 | ``` 9 | ./configure --with-sdl --enable-disasm --enable-all-optimizations --enable-readline --disable-debugger-gui --enable-x86-debugger --enable-a20-pin --enable-fast-function-calls --enable-debugger 10 | 11 | ``` 12 | 13 | 编译 14 | 15 | ``` 16 | mkdir build 17 | make 18 | ``` 19 | 20 | ### 运行镜像 21 | 22 | ``` 23 | make run 24 | ``` 25 | 26 | ## 文档 27 | 28 | ### 目录结构 29 | ``` 30 | boot.ss 加载loader到内存中,跳转到init 31 | init.ss 加载内核到内存中,进入保护模式,跳转到内核 32 | kernel.ss 内核文件 33 | ``` 34 | 35 | ### BIOS 基本功能 36 | 37 | #### 显示相关 38 | INT 10h 39 | 1. 设置光标位置 40 | AH=02H BH=页码,DH=列,DL=行 41 | 42 | 2. 清除屏幕 43 | AH=06H AL=滚动的行(0=清除,被用于CH,CL,DH,DL), 44 | BH=背景颜色和前景颜色,BH=43H,意义为背景颜色为红色,前景颜色为青色。请参考BIOS颜色属性。 45 | CH=高行数,CL=左列数,DH=低行数,DL=右列数 46 | 47 | ``` 48 | 颜色显示 49 | 二进制数 颜色 例子 二进制数 颜色 例子 50 | 0000 黑色 black 1000 灰色 gray 51 | 0001 蓝色 blue 1001 淡蓝色 light blue 52 | 0010 绿色 green 1010 淡绿色 light green 53 | 0011 青色 cyan 1000 淡青色 light cyan 54 | 0100 红色 red 1100 淡红色 light red 55 | 0101 紫红色 magenta 1101 淡紫红色 light magenta 56 | 0110 棕色 brown 1110 黄色 yellow 57 | 0111 银色 light gray 1111 白色 white 58 | ``` 59 | 60 | #### 磁盘相关 61 | INT 13h 62 | 63 | 1. 复位 64 | AH 00h 65 | DL Drive (bit 7 set means reset both hard and floppy disks) 66 | 67 | ``` 68 | DL = 00h 1st floppy disk ( "drive A:" ) 69 | DL = 01h 2nd floppy disk ( "drive B:" ) 70 | DL = 02h 3rd floppy disk ( "drive B:" ) 71 | . . . 72 | DL = 7Fh 128th floppy disk) 73 | DL = 80h 1st hard disk 74 | DL = 81h 2nd hard disk 75 | DL = 82h 3rd hard disk 76 | . . . 77 | DL = E0h CD/DVD[citation needed], or 97th hard disk 78 | . . . 79 | DL = FFh 128th hard disk 80 | ``` 81 | 82 | 2. 读取一个扇区 83 | AH=02h: Read Sectors From Drive 84 | ``` 85 | AH 02h 86 | AL Sectors To Read Count 87 | CH Cylinder 88 | CL Sector 89 | DH Head 90 | DL Drive 91 | ES:BX Buffer Address Pointer 92 | Results 93 | CF Set On Error, Clear If No Error 94 | AH Return Code 95 | AL Actual Sectors Read Count 96 | ``` 97 | 98 | 99 | ## 保护模式 100 | 101 | GDT(Global Descriptor Table,全局描述符表) 102 | LDT (Local Descriptor Table,局部描述符表) 103 | ``` 104 | GDT的每个表项,抽象地可以看成包含四个字段的数据结构:基地址(Base),大小(Limit),标志(Flag),访问信息(Access Byte)。 105 | ``` 106 | 107 | ``` 108 | GDT 109 | 1st Double word: 110 | Bits Function Description 111 | 0-15 Limit 0:15 First 16 bits in the segment limiter 112 | 16-31 Base 0:15 First 16 bits in the base address 113 | 114 | 2nd Double word: 115 | Bits Function Description 116 | 0-7 Base 16:23 Bits 16-23 in the base address 117 | 8-12 Type Segment type and attributes 118 | 13-14 Privilege Level 0 = Highest privilege (OS), 3 = Lowest privilege (User applications) 119 | 15 Present flag Set to 1 if segment is present 120 | 16-19 Limit 16:19 Bits 16-19 in the segment limiter 121 | 20-22 Attributes Different attributes, depending on the segment type 122 | 23 Granularity Used together with the limiter, to determine the size of the segment 123 | 24-31 Base 24:31 The last 24-31 bits in the base address 124 | 125 | 126 | The GDT Descriptor 127 | Bits Function Description 128 | 0-15 Limit Size of GDT in bytes 129 | 16-47 Address GDT's memory address 130 | 131 | ``` 132 | 133 | ## 分页 134 | 无分页模式 135 | 136 | ``` 137 | 线性地址等于物理地址 138 | CR0.PG = 0 139 | 140 | ``` 141 | 142 | 32bit模式 143 | ``` 144 | CR0.PG = 1 and CR4.PAE = 0 145 | 0-11: 页内偏移 146 | 12-21: 页表 (Page Table) 147 | 22-31: 页表目录表(Page Table Directory 148 | ``` 149 | PAE模式 150 | 151 | ``` 152 | CR0.PG = 1, CR4.PAE = 1, and IA32_EFER.LME = 0 153 | 0-11:页内偏移 154 | 12-20:页表(Page Table) PT PTE 512个 155 | 21-29:页表目录表(Page Table Directory) PTD PDE 512个 156 | 30-31:页目录指针表(Page Directory Pointer Table) PDPT PDPTE 4个 157 | 158 | CR3=>31:30 159 | PDPTE=>29:21 160 | PDE=> 20:12 161 | 162 | 163 | ``` 164 | 165 | 内存地址 166 | ``` 167 | 0x0500 init 168 | 0x4000 page entry 169 | 0x7c00 boot 170 | 0x8000 kernel 171 | 172 | ``` 173 | 174 | 175 | 176 | ## 任务切换 177 | TSS 任务状态段 178 | 179 | ``` 180 | x86 Structure 181 | offset 0 - 15 16 - 31 182 | 0x00 LINK reserved 183 | 0x04 ESP0 184 | 0x08 SS0 reserved 185 | 0x0C ESP1 186 | 0x10 SS1 reserved 187 | 0x14 ESP2 188 | 0x18 SS2 reserved 189 | 0x1C CR3 190 | 0x20 EIP 191 | 0x24 EFLAGS 192 | 0x28 EAX 193 | 0x2C ECX 194 | 0x30 EDX 195 | 0x34 EBX 196 | 0x38 ESP 197 | 0x3C EBP 198 | 0x40 ESI 199 | 0x44 EDI 200 | 0x48 ES reserved 201 | 0x4C CS reserved 202 | 0x50 SS reserved 203 | 0x54 DS reserved 204 | 0x58 FS reserved 205 | 0x5C GS reserved 206 | 0x60 LDTR reserved 207 | 0x64 reserved IOPB offset 208 | ``` 209 | 210 | save esp ,eip 211 | restore esp ,eip 212 | 213 | 214 | 215 | # 参考 216 | https://en.wikipedia.org/wiki/INT_10H 217 | https://en.wikipedia.org/wiki/INT_13H 218 | https://stanislavs.org/helppc/int_13-1.html 219 | https://baike.baidu.com/item/INT10H/22788179?fr=aladdin 220 | https://wiki.osdev.org/GDT_Tutorial 221 | http://www.osdever.net/tutorials/view/the-world-of-protected-mode 222 | https://files.osdev.org/mirrors/geezer/os/pm.htm 223 | https://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-vol-3a-part-1-manual.html 224 | https://wiki.osdev.org/Task_State_Segment 225 | https://wiki.osdev.org/Memory_Map_(x86) 226 | http://www.uruk.org/orig-grub/mem64mb.html 227 | https://wiki.osdev.org/Detecting_Memory_(x86) 228 | https://zh.wikipedia.org/wiki/%E5%85%A8%E5%B1%80%E6%8F%8F%E8%BF%B0%E7%AC%A6%E8%A1%A8 229 | 230 | 231 | -------------------------------------------------------------------------------- /start/init.ss: -------------------------------------------------------------------------------- 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2 | ;Copyright 2016-2080 evilbinary. 3 | ;作者:evilbinary on 12/24/16. 4 | ;邮箱:rootdebug@163.com 5 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 6 | (begin 7 | ; (define add 8 | ; (lambda (a b) 9 | ; (+ a b))) 10 | ($asm 11 | (asm "bits 16") 12 | (asm "org 0x0500") 13 | (asm "%define page_dir_ptr_base 0x4000") ;;4k aligned 0x4000-0x7000 14 | (asm "%define mem_info 0x3000") 15 | (asm "%define gdt_info 0x3200") 16 | (asm "%define kernel_base 0x8000") 17 | 18 | 19 | (call cls) 20 | 21 | (asm "mov dx,0x0000") 22 | (call set-cursor) 23 | 24 | (asm "mov si,boot") 25 | (asm "call print.string") 26 | 27 | ;;load kernel 28 | (asm "mov bx,kernel_base") 29 | (call disk-load) 30 | 31 | (asm "mov si,load.success") 32 | (asm "call print.string") 33 | 34 | ;;(asm "xchg bx,bx") 35 | 36 | ;;内存获取 37 | (asm "call probe.memory") 38 | 39 | ;;开启A20,才能访问1M以外的地址 40 | (call enable-a20) 41 | 42 | ;;加载 gdt info 43 | (asm "lgdt [gdtinfo]") 44 | (asm "cli") 45 | (asm "mov dword [gdt_info],gdt") 46 | ;;切换到保护模式 47 | (asm "mov eax ,cr0") 48 | (asm "mov [pcr0],eax") 49 | (asm "or al ,1") 50 | (asm "mov cr0,eax") 51 | (asm "jmp 0x08:protect") ;;code selector 跳转保护模式 52 | 53 | 54 | ;;内存信息获取 =>mem_info 55 | ; size 56 | ; uint32_t BaseL; // base address uint64_t 57 | ; uint32_t BaseH; 58 | ; uint32_t LengthL; // length uint64_t 59 | ; uint32_t LengthH; 60 | ; uint32_t Type; // entry Type 61 | ; uint32_t ACPI; // extended 62 | (label probe-memory) 63 | (asm "mov di,mem_info+4") 64 | (asm "xor bp, bp") 65 | (asm "mov dword[di],0") 66 | (asm "xor ebx,ebx") 67 | (label probe-start) 68 | (asm "mov eax,0xE820") 69 | (asm "mov ecx,24") 70 | (asm "mov edx,0x0534D4150") ;;'SMAP' 71 | (asm "int 0x15") 72 | (asm "jnc probe.cont") 73 | ;;failed 74 | (asm "mov dword[di],0x12345") 75 | (asm "mov si,prob.failed") 76 | (asm "call print.string") 77 | (asm "jmp probe.end") 78 | 79 | (label probe-cont) 80 | (asm "inc bp") 81 | (asm "add di,24") 82 | (asm "cmp ebx,0") 83 | (asm "jnz probe.start") 84 | (label probe-end) 85 | (asm "mov [mem_info], bp") 86 | (asm "ret") 87 | 88 | ;;磁盘读取到内存 es:bx 地址 89 | (label disk-load) 90 | (asm "mov ah,0x02 ;读取功能") 91 | (asm "mov al,0x09 ;读取几个扇区") 92 | (asm "mov cl,0x0a ;0x01 boot sector, 0x02 is first sector") 93 | (asm "mov ch,0x00") 94 | (asm "mov dh,0x00") 95 | (asm "mov dl,0x00 ;软盘0") 96 | (asm "int 0x13") 97 | (asm "jc disk.error") 98 | (asm "jmp dend") 99 | (label disk-error) 100 | (asm "mov si,disk.erro") 101 | (asm "call print.string") 102 | (label dend) 103 | (asm "ret") 104 | 105 | ;;设置光标位置 DH=列,DL=行 106 | (label set-cursor) 107 | (asm "mov ah,0x02 ;光标位置初始化") 108 | (asm "mov bh,0") 109 | (asm "int 0x10") 110 | (asm "ret") 111 | 112 | ;;清除屏幕 113 | (label cls) 114 | (asm "mov ah,0x06 ;清除屏幕 ") 115 | (asm "mov al,0") 116 | (asm "mov cx,0 ") 117 | (asm "mov dx,0xffff ") 118 | (asm "mov bh,0x0f ;属性为白字") 119 | (asm "int 0x10") 120 | (asm "ret") 121 | 122 | ;;打印一个字符 al=ascii值 123 | (label print-char) 124 | (asm "push ax") 125 | (asm "push bx") 126 | (asm "mov ah,0eh") 127 | (asm "mov bx,0007h") 128 | (asm "int 0x10") 129 | (asm "pop bx") 130 | (asm "pop ax") 131 | (asm "ret") 132 | 133 | ;;打印字符串 si=字符地址 134 | (label print-string) 135 | (asm "push ax") 136 | (label ps) 137 | (asm "mov al,[si]") 138 | (asm "inc si") 139 | (asm "or al,al") 140 | (asm "jz pend") 141 | (asm "call print.char") 142 | (asm "jmp ps") 143 | (label pend) 144 | (asm "pop ax") 145 | (asm "ret") 146 | 147 | ;;开启A20 148 | (label enable-a20) 149 | (asm "push ax") 150 | (asm "in al,92h") 151 | (asm "or al,2") 152 | (asm "out 92h,al") 153 | (asm "pop ax") 154 | (asm "ret") 155 | 156 | ;;关闭A20 157 | (label disable-a20) 158 | (asm "push ax") 159 | (asm "in al,92h") 160 | (asm "and al,0fdh") 161 | (asm "out 92h,al") 162 | (asm "pop ax") 163 | (asm "ret") 164 | 165 | 166 | ;;保护模式32 bit代码 167 | (label protect) 168 | (asm "bits 32") 169 | (asm "mov bx, 0x10");;data selector 170 | (asm "mov ss, bx") 171 | (asm "mov ds, bx") 172 | (asm "mov es, bx") 173 | (asm "mov fs, bx") 174 | (asm "mov gs, bx") 175 | 176 | ;;显示保护模式P 177 | (asm "mov ah,0xa4") 178 | (asm "mov al,'P'") 179 | (asm "mov edi,0xb8000") 180 | (asm "add edi,(80*0+14)*3") 181 | (asm "mov word [ds:edi],ax") 182 | 183 | ;;任务tss 184 | (asm "mov ax,0x20") 185 | ;;(asm "ltr ax") 186 | 187 | ;;分页设置 188 | (call init-page) 189 | 190 | ;;分页入口 191 | (asm "mov eax, page_dir_ptr_base") ;;0x7E00 192 | (asm "mov cr3, eax") 193 | 194 | ;;开启PAE 195 | (asm "mov eax, cr4") 196 | (asm "or eax, 1<<5") 197 | (asm "mov cr4, eax") 198 | 199 | 200 | ;;开启分页模式 201 | (asm "mov eax, cr0") 202 | (asm "or eax, 0x80000000") 203 | ;;(asm "xchg bx,bx") 204 | (asm "mov cr0, eax") 205 | 206 | ;;(asm "xchg bx,bx") 207 | 208 | ;;跳转到内核 209 | (asm "jmp kernel_base") 210 | 211 | (asm "jmp $") 212 | 213 | ;;分页设置 214 | (label init-page) 215 | ;;pdpt =>page_dir_ptr_base 216 | (asm "mov ebx,page_dir_ptr_base+0x1000|1") ;;pdpte 217 | (asm "mov esi,page_dir_ptr_base") ;;pdpt_addr 218 | (asm "mov ecx,1") 219 | (label loop-pdpte) 220 | (asm "mov dword [esi],ebx") 221 | (asm "mov dword [esi+4],0") 222 | (asm "add esi,8") 223 | (asm "loop loop.pdpte") 224 | ;;ptd =>page_dir_ptr_base + 0x1000 225 | (asm "mov ebx,page_dir_ptr_base+0x2000|3") ;;pde 226 | (asm "mov esi,page_dir_ptr_base+0x1000") 227 | (asm "mov ecx,1") 228 | (label loop-pdt) 229 | (asm "mov dword [esi],ebx") 230 | (asm "mov dword [esi+4],0") 231 | (asm "add esi,8") 232 | (asm "loop loop.pdt") 233 | ;;pt => page_dir_ptr_base + 0x2000 234 | (asm "mov ebx,0x0|3") 235 | (asm "mov esi,page_dir_ptr_base+0x2000") 236 | (asm "mov ecx,512") 237 | (label loop-pt) 238 | (asm "mov dword [esi],ebx") 239 | (asm "mov dword [esi+4],0") 240 | (asm "add ebx,0x1000") 241 | (asm "add esi,8") 242 | (asm "loop loop.pt") 243 | 244 | (asm "ret") 245 | 246 | (data boot "loader kernel") 247 | (data load.success " success") 248 | (data disk.erro "read disk erro") 249 | (data prob.failed "prob failed") 250 | 251 | ;;gdt info 252 | (label gdtinfo) 253 | (asm "dw gdt_end - gdt - 1 ") 254 | (asm "dd gdt ") 255 | (asm "gdt dd 0,0") ;;gdt 0 unuse 256 | ;; limit base basel type/s/dpl/p limith /avl/l/db/g baseh 257 | (asm "flatcode db 0xff, 0xff, 0x00, 0x00, 0x00, 10011010b, 11001111b, 0x00") ;;0x08 258 | (asm "flatdata db 0xff, 0xff, 0x00, 0x00, 0x00, 10010010b, 11001111b, 0x00") ;;0x10 259 | (asm "flatdesc db 0xff, 0xff, 0x00, 0x00, 0x00, 10010010b, 11001111b, 0x00") ;;0x18 260 | (asm "flattss db 0xff, 0xff, 0x00, 0x00, 0x00, 10001001b, 11001111b, 0x00") ;;0x20 261 | (label gdt_end) 262 | 263 | 264 | (asm "pcr0: dd 0") 265 | 266 | ) 267 | 268 | ) 269 | 270 | --------------------------------------------------------------------------------