├── .git.swp ├── Makefile ├── Makefile.bak ├── README.md ├── a.img ├── bochsout.txt ├── bochsrc ├── bochsrc.bxrc ├── boot.bak ├── boot ├── boot.asm ├── boot.bin ├── include │ ├── common.inc │ ├── fat12hdr.inc │ ├── load.inc │ └── pm.inc ├── loader.asm └── loader.bin ├── cscope.in.out ├── cscope.out ├── cscope.po.out ├── debug_log ├── global.o ├── include ├── const.h ├── global.h ├── process.h ├── protect.h ├── proto.h ├── sconst.inc ├── string.h └── type.h ├── kernel ├── global.c ├── i8259.c ├── kernel.asm ├── kernel.o ├── main.c ├── protect.c └── start.c ├── lib ├── klib.c ├── kliba.asm └── string.asm ├── libgluegen-rt.so ├── libjogl.so ├── libjogl_awt.so ├── libjogl_cg.so ├── os.log ├── peter-bochs-debugger.jar ├── peter-bochs.log ├── peter-bochs.xml ├── run └── tags /.git.swp: -------------------------------------------------------------------------------- 1 | b0VIM 7.3wlxqlxq-virtual-machine~lxq/Desktop/orange/c5/gitutf-8 3210#"! U -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ######################### 2 | # Makefile for Orange'S # 3 | ######################### 4 | 5 | # Entry point of Orange'S 6 | # It must have the same value with 'KernelEntryPointPhyAddr' in load.inc! 7 | ENTRYPOINT = 0x30400 8 | 9 | # Offset of entry point in kernel file 10 | # It depends on ENTRYPOINT 11 | ENTRYOFFSET = 0x400 12 | 13 | # Programs, flags, etc. 14 | ASM = nasm 15 | DASM = ndisasm 16 | CC = gcc 17 | LD = ld 18 | ASMBFLAGS = -I boot/include/ 19 | ASMKFLAGS = -I include/ -f elf 20 | CFLAGS = -I include/ -c -fno-builtin -fno-stack-protector 21 | LDFLAGS = -s -Ttext $(ENTRYPOINT) 22 | DASMFLAGS = -u -o $(ENTRYPOINT) -e $(ENTRYOFFSET) 23 | 24 | # This Program 25 | ORANGESBOOT = boot/boot.bin boot/loader.bin 26 | KERNEL = kernel.bin 27 | OBJS = kernel/kernel.o kernel/start.o kernel/i8259.o kernel/global.o kernel/protect.o \ 28 | lib/klib.o lib/kliba.o lib/string.o kernel/main.o 29 | 30 | DASMOUTPUT = kernel.bin.asm 31 | 32 | # All Phony Targets 33 | .PHONY : everything final run clean realclean disasm all buildimg 34 | 35 | # Default starting position 36 | everything : $(ORANGESBOOT) $(KERNEL) 37 | 38 | all : realclean everything 39 | 40 | final : all clean 41 | 42 | run : final buildimg 43 | 44 | clean : 45 | rm -f $(OBJS) 46 | 47 | realclean : 48 | rm -f $(OBJS) $(ORANGESBOOT) $(KERNEL) 49 | 50 | disasm : 51 | $(DASM) $(DASMFLAGS) $(KERNEL) > $(DASMOUTPUT) 52 | 53 | # We assume that "a.img" exists in current folder 54 | buildimg : 55 | dd if=boot/boot.bin of=a.img bs=512 count=1 conv=notrunc 56 | sudo mount -o loop a.img /mnt/floppy/ 57 | sudo cp -fv boot/loader.bin /mnt/floppy/ 58 | sudo cp -fv kernel.bin /mnt/floppy 59 | sudo umount /mnt/floppy 60 | 61 | 62 | boot/boot.bin : boot/boot.asm boot/include/load.inc boot/include/fat12hdr.inc 63 | $(ASM) $(ASMBFLAGS) -o $@ $< 64 | 65 | boot/loader.bin : boot/loader.asm boot/include/load.inc \ 66 | boot/include/fat12hdr.inc boot/include/pm.inc 67 | $(ASM) $(ASMBFLAGS) -o $@ $< 68 | 69 | $(KERNEL) : $(OBJS) 70 | $(LD) $(LDFLAGS) -o $(KERNEL) $(OBJS) 71 | 72 | kernel/kernel.o : kernel/kernel.asm include/sconst.inc 73 | $(ASM) $(ASMKFLAGS) -o $@ $< 74 | 75 | kernel/start.o: kernel/start.c include/type.h include/const.h include/protect.h \ 76 | include/proto.h include/string.h include/global.h include/process.h 77 | $(CC) $(CFLAGS) -o $@ $< 78 | 79 | kernel/i8259.o : kernel/i8259.c include/type.h include/const.h include/protect.h \ 80 | include/proto.h 81 | $(CC) $(CFLAGS) -o $@ $< 82 | 83 | kernel/global.o : kernel/global.c include/type.h include/const.h include/protect.h \ 84 | include/proto.h include/process.h include/global.h 85 | $(CC) $(CFLAGS) -o $@ $< 86 | 87 | kernel/protect.o : kernel/protect.c include/type.h include/const.h include/protect.h \ 88 | include/proto.h include/process.h include/global.h include/string.h 89 | $(CC) $(CFLAGS) -o $@ $< 90 | 91 | kernel/main.o : kernel/main.c include/type.h include/const.h include/protect.h \ 92 | include/proto.h include/process.h include/global.h include/string.h 93 | $(CC) $(CFLAGS) -o $@ $< 94 | 95 | lib/klib.o : lib/klib.c include/type.h include/const.h include/protect.h \ 96 | include/proto.h include/process.h include/global.h include/string.h 97 | $(CC) $(CFLAGS) -o $@ $< 98 | 99 | lib/kliba.o : lib/kliba.asm 100 | $(ASM) $(ASMKFLAGS) -o $@ $< 101 | 102 | lib/string.o : lib/string.asm 103 | $(ASM) $(ASMKFLAGS) -o $@ $< 104 | -------------------------------------------------------------------------------- /Makefile.bak: -------------------------------------------------------------------------------- 1 | ################################################## 2 | # Makefile 3 | ################################################## 4 | 5 | BOOT:=boot/boot.asm 6 | LDR:=boot/loader.asm 7 | KERNEL:=kernel/kernel.asm 8 | 9 | BOOT_BIN:=$(subst .asm,.bin,$(BOOT)) 10 | LDR_BIN:=$(subst .asm,.bin,$(LDR)) 11 | KERNEL_BIN:=$(subst .asm,.bin,$(KERNEL)) 12 | 13 | IMG:=a.img 14 | FLOPPY:=/mnt/floppy/ 15 | 16 | .PHONY : everything 17 | 18 | everything : $(BOOT_BIN) $(LDR_BIN) 19 | dd if=$(BOOT_BIN) of=$(IMG) bs=512 count=1 conv=notrunc 20 | sudo mount -o loop $(IMG) $(FLOPPY) 21 | sudo cp $(LDR_BIN) $(FLOPPY) -v 22 | sudo cp $(KERNEL_BIN) $(FLOPPY) -v 23 | sudo umount $(FLOPPY) 24 | 25 | clean : 26 | rm -f $(BOOT_BIN) $(LDR_BIN) $(KERNEL_BIN) *.o 27 | 28 | $(BOOT_BIN) : $(BOOT) 29 | nasm $< -o $@ 30 | 31 | $(LDR_BIN) : $(LDR) 32 | nasm $< -o $@ 33 | 34 | $(KERNEL_BIN) : $(KERNEL) 35 | nasm -f elf -o $(subst .asm,.o,$(KERNEL)) $< 36 | ld -s -Ttext 0x30400 -o $@ $(subst .asm,.o,$(KERNEL)) 37 | #启动分页机制时内存是对等映射的 系统直接指定0x8048XXX(128M以上) 38 | #为防止电脑内存不足128M所以指定内核加载的位置0x30400 39 | 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linkypi/MyOS/c3ee437c3f41a82eab6a61119938357794617a9d/README.md -------------------------------------------------------------------------------- /a.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linkypi/MyOS/c3ee437c3f41a82eab6a61119938357794617a9d/a.img -------------------------------------------------------------------------------- /bochsout.txt: -------------------------------------------------------------------------------- 1 | 00000000000i[ ] Bochs x86 Emulator 2.6.2 2 | 00000000000i[ ] Built from SVN snapshot on May 26, 2013 3 | 00000000000i[ ] Compiled on Jul 8 2013 at 20:26:59 4 | 00000000000i[ ] System configuration 5 | 00000000000i[ ] processors: 1 (cores=1, HT threads=1) 6 | 00000000000i[ ] A20 line support: yes 7 | 00000000000i[ ] IPS is set to 4000000 8 | 00000000000i[ ] CPU configuration 9 | 00000000000i[ ] SMP support: no 10 | 00000000000i[ ] level: 6 11 | 00000000000i[ ] APIC support: xapic 12 | 00000000000i[ ] FPU support: yes 13 | 00000000000i[ ] MMX support: yes 14 | 00000000000i[ ] 3dnow! support: no 15 | 00000000000i[ ] SEP support: yes 16 | 00000000000i[ ] SSE support: sse2 17 | 00000000000i[ ] XSAVE support: no 18 | 00000000000i[ ] AES support: no 19 | 00000000000i[ ] MOVBE support: no 20 | 00000000000i[ ] ADX support: no 21 | 00000000000i[ ] x86-64 support: no 22 | 00000000000i[ ] MWAIT support: yes 23 | 00000000000i[ ] Optimization configuration 24 | 00000000000i[ ] RepeatSpeedups support: no 25 | 00000000000i[ ] Fast function calls: no 26 | 00000000000i[ ] Handlers Chaining speedups: no 27 | 00000000000i[ ] Devices configuration 28 | 00000000000i[ ] NE2000 support: no 29 | 00000000000i[ ] PCI support: yes, enabled=yes 30 | 00000000000i[ ] SB16 support: no 31 | 00000000000i[ ] USB support: no 32 | 00000000000i[ ] VGA extension support: vbe 33 | 00000000000i[MEM0 ] allocated memory at 0xb4f4e008. after alignment, vector=0xb4f4f000 34 | 00000000000i[MEM0 ] 32.00MB 35 | 00000000000i[MEM0 ] mem block size = 0x00100000, blocks=32 36 | 00000000000i[MEM0 ] rom at 0xfffe0000/131072 ('/usr/local/share/bochs/BIOS-bochs-latest') 37 | 00000000000i[ ] init_dev of 'pci' plugin device by virtual method 38 | 00000000000i[DEV ] i440FX PMC present at device 0, function 0 39 | 00000000000i[ ] init_dev of 'pci2isa' plugin device by virtual method 40 | 00000000000i[DEV ] PIIX3 PCI-to-ISA bridge present at device 1, function 0 41 | 00000000000i[ ] init_dev of 'cmos' plugin device by virtual method 42 | 00000000000i[CMOS ] Using local time for initial clock 43 | 00000000000i[CMOS ] Setting initial clock to: Sun Feb 16 22:33:54 2014 (time0=1392561234) 44 | 00000000000i[ ] init_dev of 'dma' plugin device by virtual method 45 | 00000000000i[DMA ] channel 4 used by cascade 46 | 00000000000i[ ] init_dev of 'pic' plugin device by virtual method 47 | 00000000000i[ ] init_dev of 'pit' plugin device by virtual method 48 | 00000000000i[ ] init_dev of 'floppy' plugin device by virtual method 49 | 00000000000i[DMA ] channel 2 used by Floppy Drive 50 | 00000000000i[FDD ] fd0: 'a.img' ro=0, h=2,t=80,spt=18 51 | 00000000000i[ ] init_dev of 'vga' plugin device by virtual method 52 | 00000000000i[MEM0 ] Register memory access handlers: 0x0000000a0000 - 0x0000000bffff 53 | 00000000000i[VGA ] interval=200000 54 | 00000000000i[MEM0 ] Register memory access handlers: 0x0000e0000000 - 0x0000e0ffffff 55 | 00000000000i[BXVGA] VBE Bochs Display Extension Enabled 56 | 00000000000i[XGUI ] test_alloc_colors: 16 colors available out of 16 colors tried 57 | 00000000000i[XGUI ] font 8 wide x 16 high, display depth = 24 58 | 00000000000i[KMAP ] Loading keymap from '/usr/local/share/bochs/keymaps/x11-pc-us.map' 59 | 00000000000i[KMAP ] Loaded 168 symbols 60 | 00000000000i[MEM0 ] rom at 0xc0000/32768 ('/usr/local/share/bochs/VGABIOS-elpin-2.40') 61 | 00000000000i[ ] init_dev of 'acpi' plugin device by virtual method 62 | 00000000000i[DEV ] ACPI Controller present at device 1, function 3 63 | 00000000000i[ ] init_dev of 'ioapic' plugin device by virtual method 64 | 00000000000i[IOAP ] initializing I/O APIC 65 | 00000000000i[MEM0 ] Register memory access handlers: 0x0000fec00000 - 0x0000fec00fff 66 | 00000000000i[IOAP ] IOAPIC enabled (base address = 0xfec00000) 67 | 00000000000i[ ] init_dev of 'keyboard' plugin device by virtual method 68 | 00000000000i[KBD ] will paste characters every 400 keyboard ticks 69 | 00000000000i[ ] init_dev of 'harddrv' plugin device by virtual method 70 | 00000000000i[HD ] Using boot sequence floppy, none, none 71 | 00000000000i[HD ] Floppy boot signature check is enabled 72 | 00000000000i[ ] init_dev of 'pci_ide' plugin device by virtual method 73 | 00000000000i[DEV ] PIIX3 PCI IDE controller present at device 1, function 1 74 | 00000000000i[ ] init_dev of 'unmapped' plugin device by virtual method 75 | 00000000000i[ ] init_dev of 'biosdev' plugin device by virtual method 76 | 00000000000i[ ] init_dev of 'speaker' plugin device by virtual method 77 | 00000000000i[ ] init_dev of 'extfpuirq' plugin device by virtual method 78 | 00000000000i[ ] init_dev of 'parallel' plugin device by virtual method 79 | 00000000000i[PAR ] parallel port 1 at 0x0378 irq 7 80 | 00000000000i[ ] init_dev of 'serial' plugin device by virtual method 81 | 00000000000i[SER ] com1 at 0x03f8 irq 4 82 | 00000000000i[ ] init_dev of 'iodebug' plugin device by virtual method 83 | 00000000000i[ ] register state of 'pci' plugin device by virtual method 84 | 00000000000i[ ] register state of 'pci2isa' plugin device by virtual method 85 | 00000000000i[ ] register state of 'cmos' plugin device by virtual method 86 | 00000000000i[ ] register state of 'dma' plugin device by virtual method 87 | 00000000000i[ ] register state of 'pic' plugin device by virtual method 88 | 00000000000i[ ] register state of 'pit' plugin device by virtual method 89 | 00000000000i[ ] register state of 'floppy' plugin device by virtual method 90 | 00000000000i[ ] register state of 'vga' plugin device by virtual method 91 | 00000000000i[ ] register state of 'unmapped' plugin device by virtual method 92 | 00000000000i[ ] register state of 'biosdev' plugin device by virtual method 93 | 00000000000i[ ] register state of 'speaker' plugin device by virtual method 94 | 00000000000i[ ] register state of 'extfpuirq' plugin device by virtual method 95 | 00000000000i[ ] register state of 'parallel' plugin device by virtual method 96 | 00000000000i[ ] register state of 'serial' plugin device by virtual method 97 | 00000000000i[ ] register state of 'iodebug' plugin device by virtual method 98 | 00000000000i[ ] register state of 'acpi' plugin device by virtual method 99 | 00000000000i[ ] register state of 'ioapic' plugin device by virtual method 100 | 00000000000i[ ] register state of 'keyboard' plugin device by virtual method 101 | 00000000000i[ ] register state of 'harddrv' plugin device by virtual method 102 | 00000000000i[ ] register state of 'pci_ide' plugin device by virtual method 103 | 00000000000i[SYS ] bx_pc_system_c::Reset(HARDWARE) called 104 | 00000000000i[CPU0 ] cpu hardware reset 105 | 00000000000i[APIC0] allocate APIC id=0 (MMIO enabled) to 0x0000fee00000 106 | 00000000000i[CPU0 ] CPUID[0x00000000]: 00000005 756e6547 6c65746e 49656e69 107 | 00000000000i[CPU0 ] CPUID[0x00000001]: 00000633 00010800 00000008 1fcbfbff 108 | 00000000000i[CPU0 ] CPUID[0x00000002]: 00410601 00000000 00000000 00000000 109 | 00000000000i[CPU0 ] CPUID[0x00000003]: 00000000 00000000 00000000 00000000 110 | 00000000000i[CPU0 ] CPUID[0x00000004]: 00000000 00000000 00000000 00000000 111 | 00000000000i[CPU0 ] CPUID[0x00000005]: 00000040 00000040 00000003 00000020 112 | 00000000000i[CPU0 ] CPUID[0x80000000]: 80000008 00000000 00000000 00000000 113 | 00000000000i[CPU0 ] CPUID[0x80000001]: 00000000 00000000 00000000 00000000 114 | 00000000000i[CPU0 ] CPUID[0x80000002]: 20202020 20202020 20202020 6e492020 115 | 00000000000i[CPU0 ] CPUID[0x80000003]: 286c6574 50202952 69746e65 52286d75 116 | 00000000000i[CPU0 ] CPUID[0x80000004]: 20342029 20555043 20202020 00202020 117 | 00000000000i[CPU0 ] CPUID[0x80000005]: 01ff01ff 01ff01ff 40020140 40020140 118 | 00000000000i[CPU0 ] CPUID[0x80000006]: 00000000 42004200 02008140 00000000 119 | 00000000000i[CPU0 ] CPUID[0x80000007]: 00000000 00000000 00000000 00000000 120 | 00000000000i[CPU0 ] CPUID[0x80000008]: 00002028 00000000 00000000 00000000 121 | 00000000000i[ ] reset of 'pci' plugin device by virtual method 122 | 00000000000i[ ] reset of 'pci2isa' plugin device by virtual method 123 | 00000000000i[ ] reset of 'cmos' plugin device by virtual method 124 | 00000000000i[ ] reset of 'dma' plugin device by virtual method 125 | 00000000000i[ ] reset of 'pic' plugin device by virtual method 126 | 00000000000i[ ] reset of 'pit' plugin device by virtual method 127 | 00000000000i[ ] reset of 'floppy' plugin device by virtual method 128 | 00000000000i[ ] reset of 'vga' plugin device by virtual method 129 | 00000000000i[ ] reset of 'acpi' plugin device by virtual method 130 | 00000000000i[ ] reset of 'ioapic' plugin device by virtual method 131 | 00000000000i[ ] reset of 'keyboard' plugin device by virtual method 132 | 00000000000i[ ] reset of 'harddrv' plugin device by virtual method 133 | 00000000000i[ ] reset of 'pci_ide' plugin device by virtual method 134 | 00000000000i[ ] reset of 'unmapped' plugin device by virtual method 135 | 00000000000i[ ] reset of 'biosdev' plugin device by virtual method 136 | 00000000000i[ ] reset of 'speaker' plugin device by virtual method 137 | 00000000000e[SPEAK] Failed to open /dev/console: Permission denied 138 | 00000000000e[SPEAK] Deactivating beep on console 139 | 00000000000i[ ] reset of 'extfpuirq' plugin device by virtual method 140 | 00000000000i[ ] reset of 'parallel' plugin device by virtual method 141 | 00000000000i[ ] reset of 'serial' plugin device by virtual method 142 | 00000000000i[ ] reset of 'iodebug' plugin device by virtual method 143 | 00000000000i[XGUI ] Mouse capture off 144 | 00000000000i[ ] set SIGINT handler to bx_debug_ctrlc_handler 145 | 00000000000i[XGUI ] Mouse capture off 146 | -------------------------------------------------------------------------------- /bochsrc: -------------------------------------------------------------------------------- 1 | ############################################################### 2 | # Configuration file for Bochs 3 | ############################################################### 4 | 5 | # how much memory the emulated machine will have 6 | megs: 32 7 | 8 | # filename of ROM images 9 | romimage: file=/usr/local/share/bochs/BIOS-bochs-latest 10 | vgaromimage: file=/usr/local/share/bochs/VGABIOS-lgpl-latest 11 | 12 | # what disk images will be used 13 | floppya: 1_44=a.img, status=inserted 14 | 15 | # choose the boot disk. 16 | boot: a 17 | 18 | # where do we send log messages? 19 | # log: bochsout.txt 20 | 21 | # disable the mouse 22 | mouse: enabled=0 23 | 24 | # enable key mapping, using US layout as default. 25 | keyboard_mapping: enabled=1, map=/usr/local/share/bochs/keymaps/x11-pc-us.map 26 | -------------------------------------------------------------------------------- /bochsrc.bxrc: -------------------------------------------------------------------------------- 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 | 8 | # filename of ROM images 9 | romimage: file=$BXSHARE/BIOS-bochs-latest #, address=0xf0000 10 | vgaromimage: file=$BXSHARE/VGABIOS-elpin-2.40 11 | 12 | # what disk images will be used 13 | floppya: 1_44=a.img, status=inserted 14 | # floppyb: 1_44=floppyb.img, status=inserted 15 | 16 | # hard disk 17 | # ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 18 | # ata0-master: type=disk, path="hd10meg.img", cylinders=306, heads=4, spt=17 19 | 20 | # choose the boot disk. 21 | boot: a 22 | 23 | # default config interface is textconfig. 24 | #config_interface: textconfig 25 | #config_interface: wx 26 | 27 | #display_library: x 28 | # other choices: win32 sdl wx carbon amigaos beos macintosh nogui rfb term 29 | 30 | # where do we send log messages? 31 | log: bochsout.txt 32 | 33 | # disable the mouse, since DLX is text only 34 | mouse: enabled=0 35 | 36 | # enable key mapping, using US layout as default. 37 | # 38 | # NOTE: In Bochs 1.4, keyboard mapping is only 100% implemented on X windows. 39 | # However, the key mapping tables are used in the paste function, so 40 | # in the DLX Linux example I'm enabling keyboard_mapping so that paste 41 | # will work. Cut&Paste is currently implemented on win32 and X windows only. 42 | 43 | keyboard_mapping: enabled=1, map=$BXSHARE/keymaps/x11-pc-us.map 44 | #keyboard_mapping: enabled=1, map=$BXSHARE/keymaps/x11-pc-fr.map 45 | #keyboard_mapping: enabled=1, map=$BXSHARE/keymaps/x11-pc-de.map 46 | #keyboard_mapping: enabled=1, map=$BXSHARE/keymaps/x11-pc-es.map 47 | -------------------------------------------------------------------------------- /boot.bak: -------------------------------------------------------------------------------- 1 | ;将镜像加载到内存,每次加载一个扇区,为的是从中找到Loader.bin文件 2 | ;找到后将其加载到内存的指定位置 3 | ;最后跳转到该位置 将控制权交给Loader.bin 4 | org 07c00h ;bios 可将引导扇区加载到0:7c00 处 并开始执行 5 | 6 | ;宏定义 编译阶段宏会被删除 7 | RootDirSecCount equ 14 ;根目录所占扇区数 8 | SecNumOfRootDir equ 19 ;根目录开始扇区号 9 | BaseOfStack equ 07c00h ; 堆栈基地址(栈底, 从这个位置向低地址生长) 10 | BaseOfLoader equ 0900h 11 | OffsetOfLoader equ 0100h 12 | 13 | ;======================================================== 14 | jmp short startx ; Start to boot. 15 | nop ; 这个 nop 不可少 16 | 17 | %include "fat12hdr.inc" 18 | 19 | startx: 20 | mov ax,cs 21 | mov ds,ax 22 | mov es,ax 23 | mov ss,ax 24 | mov sp,BaseOfStack 25 | 26 | ;清屏 27 | mov ah,6 28 | mov al,0 29 | mov cl,0 30 | mov ch,0 31 | mov dh,24 32 | mov dl,79 33 | mov bh,7 34 | int 10h 35 | 36 | ;显示Booting... 37 | ;mov ax,msg_boot 38 | ;mov cx,10 39 | ;call dispstr 40 | 41 | ; 软驱复位 42 | xor ah,ah 43 | xor dl,dl 44 | int 13h 45 | 46 | 47 | mov byte [secnum],SecNumOfRootDir ;保存根目录起始扇区号 48 | mov byte [SecLoopCount],RootDirSecCount ;循环读取扇区次数 49 | Read: 50 | cmp byte [SecLoopCount],0 51 | jz finish ;若读完14个扇区仍未找到則显示磁盘中没有Loader.bin文件 52 | dec byte [SecLoopCount] 53 | 54 | ;准备存放缓冲区 es:bx 55 | mov ax,BaseOfLoader 56 | mov es,ax 57 | mov bx,OffsetOfLoader 58 | 59 | movzx ax,byte [secnum] ; 起始扇区号 60 | mov cl,1 ; 每次读取一个扇区 61 | call ReadSector ; 62 | 63 | cld ;将 DF 置为0 使得di si按增量方式增长 64 | mov dx,0x10 ;每个文件目录的大小为32字节, 65 | ;一个扇区512字节 共读取16遍 66 | ;显示Finding... 67 | ;mov ax,msg_find 68 | ;mov cx,18 69 | ;call dispstr 70 | 71 | ;mov ax,BaseOfLoader 72 | ;mov es,ax 73 | mov di,OffsetOfLoader 74 | findFile: ;开始查找 75 | 76 | mov si,filename 77 | mov cx,11 78 | cmpfilename: ;比较文件名称 lodsb --> si 自增或自减 79 | lodsb ;ds:si 80 | cmp al,byte [es:di] 81 | jnz nextfile 82 | inc di 83 | loop cmpfilename 84 | jmp finded 85 | 86 | nextfile: ;转到下一个文件 87 | dec dx 88 | cmp dx,0 89 | jz Read 90 | add di,0x20 91 | jmp findFile 92 | 93 | finish: 94 | mov ax,msg_nofind 95 | mov cx,9 96 | call dispstr 97 | jmp $ 98 | 99 | finded: 100 | ;显示字符串 101 | mov dx,0 102 | 103 | mov cx,word [es:di+26-11] ;获取文件开始簇号 偏移为26 104 | ;而文件名偏移为0占用11 byte 105 | mov ax, word [es:di+28-11] ;保存文件大小 文件大小占4字节 106 | mov word [fileSize],ax ;此处只取2字节 107 | push cx 108 | mov ax,cx 109 | 110 | sub ax,2 ;头两个fat值不使用 111 | add ax,SecNumOfRootDir ;根目录开始扇区号 19 112 | add ax,RootDirSecCount ;根目录占用的扇区数 14 113 | 114 | mov cl,2 115 | call ReadSector ;每次读取两个扇区 116 | ;call saveFAT ;保存fat值 第0个和第1个fat项始终不使用 117 | ;第二个FAT项开始表示数据区的每一个簇 118 | ;数据区的第一个簇号是2,不是0和1 119 | ;#################################################################################################### 120 | ;######################## 查找文件占用的扇区号 ############################################# 121 | ;#################################################################################################### 122 | findFAT: 123 | 124 | ; 软驱复位 125 | xor ah,ah 126 | xor dl,dl 127 | int 13h 128 | mov ax,1 ;FAT1 起始扇区号 129 | mov cl,9 ; 读取9个扇区 130 | call ReadSector ; 131 | mov di,OffsetOfLoader 132 | ;add di,[BPB_BytsPerSec] ;fat1从第二个扇区开始 偏移 + 0x200 133 | mov ax,word [BPB_FATSz16] 134 | mov byte [fatSecCount],al ;FAT表占用的扇区数 共占用9个扇区 135 | 136 | mov byte [xi],0 ;循环查找fat使用 标记是否为偶数项个字节 137 | 138 | mov ax,[BPB_BytsPerSec] ;记录fat1表结束位置的偏移值 139 | mov si,[BPB_FATSz16] 140 | mul si ; 0x200 * 9 141 | mov word [fatendoffset],ax 142 | 143 | pop cx 144 | inc cx ;第cx+1个为当前所找的fat值 145 | findF: 146 | cmp di,word [fatendoffset] ;判断fat中的9个扇区是否已全部读完 147 | jae badFAT ;已读完則表明fat1表有误 148 | 149 | and byte [xi],1 ;是否为第偶数项个字节 150 | ;fat值占用12 bit 高地址在高位 低地址在低位 151 | jz even ;第偶数项 从0开始算起 152 | jnz odd ;第奇数项 153 | 154 | even: ;第偶数项 155 | mov al,byte [es:di] 156 | mov ah,byte [es:di+1] 157 | and ah,0x0F 158 | 159 | inc byte [xi] 160 | dec cx 161 | inc di 162 | cmp cx,0 ;若是最后一个则跳转 163 | jnz findF 164 | jz cmpFAT 165 | 166 | odd: ;第奇数项 167 | mov al,byte [es:di] 168 | and al,0xF0 169 | mov ah,byte [es:di+1] 170 | shr ax,4 171 | 172 | inc byte [xi] 173 | dec cx 174 | add di,2 175 | cmp cx,0 ;若是最后一个则跳转 176 | jnz findF 177 | jz cmpFAT 178 | 179 | cmpFAT: ;对比fat值 180 | cmp ax,0xFF7 181 | jz badClus 182 | 183 | cmp ax,0xFF8 ;fat >= 0xFF8 --->当前簇为文件的最后一个簇 184 | ;fat < 0xFF8 --->当前簇为文件的下一个簇号 185 | ;相当以链表的形式存放 186 | 187 | jae ReadLoader ;加载Loader 188 | call saveFAT ;保存fat值 189 | jb findFAT ;继续查找 190 | 191 | saveFAT: ;保存fat值 192 | 193 | movzx si,byte [fatCount] ;fat个数 此处取得数组下标 194 | mov cx,si 195 | cmp cx,0 196 | jz next 197 | .go: 198 | add si,si 199 | loop .go 200 | ;mov si,2 ;\ 201 | ;mul si ; > si=2*si 202 | ;mov si,ax ;/ 203 | ;pop ax 204 | next: 205 | mov byte [fatList+si],al ;保存第 si 个fat值 206 | inc byte [fatCount] ;fat个数加1 207 | ret 208 | 209 | ;=========================================================================================== 210 | ;================================= 加载Loader到内存 ===================================== 211 | ;=========================================================================================== 212 | ReadLoader: 213 | ;准备存放缓冲区 es:bx 214 | ;mov ax,BaseOfLoader 215 | ;mov es,ax 216 | mov bx,OffsetOfLoader 217 | 218 | mov ax,34 ; 起始扇区号 219 | mov cl,2 ; 每次读取一个扇区 220 | call ReadSector ; 221 | 222 | cld ;将 DF 置为0 使得di si按增量方式增长 223 | 224 | ;将控制权交给Loader 225 | jmp BaseOfLoader:OffsetOfLoader 226 | 227 | 228 | ;=========================================================================================== 229 | ;================================= 显示字符串 ========================================= 230 | ;=========================================================================================== 231 | 232 | badClus: ;显示Loader.bin中存在坏簇 233 | mov ax,msg_bad 234 | mov cx,8 235 | call dispstr 236 | jmp $ 237 | 238 | badFAT: 239 | mov ax,msg_badfat 240 | mov cx,14 241 | call dispstr 242 | jmp $ 243 | 244 | dispstr: ;调用时需指定ax字符串,cx长度 245 | ;call clear 246 | mov bp,ax ;es:bp 247 | mov ax,1301h ; AH = 13 AL = 01H 248 | mov bx,000ch ;页号为0 黑底红字 BL=0ch 249 | mov dl,35 ;列数 250 | mov dh,12 ;行数 251 | int 10h 252 | ;call delay 253 | ret 254 | 255 | 256 | 257 | ;delay: ;在虚拟机下执行60000*600次循环 258 | ;相当于6秒钟,而实际情况可能会快2-3倍 259 | ; mov dx,60000 260 | ; .for1: 261 | ; ;mov ax,10 262 | ; ;.for2: 263 | ; mov cx,400 264 | ; .go: 265 | ; dec cx 266 | ; cmp cx,0 267 | ; jnz .go 268 | ; 269 | ; ;dec ax 270 | ; ;cmp ax,0 271 | ; ;jnz .for2 272 | ; 273 | ; dec dx 274 | ; cmp dx,0 275 | ; jnz .for1 276 | ;ret 277 | 278 | ;=========================================================================================== 279 | ;================================= 读取扇区 ========================================= 280 | ;=========================================================================================== 281 | ReadSector: ;读取磁盘 从第AX个扇区开始 将cl个扇区读入到ES:BX中 282 | ;扇区号为X 283 | ; |柱面号 = y >> 1 284 | ; X |商 y | 285 | ;-------------=>-| |磁头号 = y & 1 286 | ; | 287 | ; |余 z => 起始扇区号 = z + 1 288 | push bp 289 | mov bp,sp 290 | sub esp,2 ;劈出两个字节的堆栈区保存要读的扇区数:byte [bp-2] 291 | 292 | mov byte [bp-2],cl 293 | push bx 294 | mov bl,[BPB_SecPerTrk] ; bl是除数 BPB_SecPerTrk=每磁道扇区数 295 | div bl ;低8位为商 高8位为余数 296 | inc ah ;余数+1 297 | mov cl,ah ;cl->起始扇区号 298 | mov dh,al 299 | shr al,1 300 | mov ch,al ;柱面号 301 | and dh,1 ;磁头号 302 | pop bx 303 | ;至此 柱面号,起始扇区,磁头号 全部就绪 304 | mov dl,[BS_DrvNum] ;驱动器号 305 | .goon: 306 | mov ah,2 ;读 307 | mov al,byte [bp-2] ;读 al 个扇区 308 | int 13h 309 | jc .goon ;如果读取错误 CF 会被置为 1,这时会不停的读 直到正确为止 310 | 311 | add esp,2 312 | pop bp 313 | 314 | ret 315 | 316 | ;若将字符串放在开头則计算机会将字符串视为指令来执行 317 | filename db "LOADER BIN",0 ;文件名为11字节 318 | msg_nofind db "No Loader",0 319 | ;msg_finded db "Loader .......",0 320 | ;msg_boot db "Booting...",0 321 | ;msg_find db "Finding Loader ...",0 322 | msg_bad db "Bad clus",0 323 | msg_badfat db "Fat damaged...",0 324 | secnum db 0 ;扇区号 325 | SecLoopCount db 14 ;根目录所占扇区数 326 | fatSecCount db 0 ;fat占用的扇区数 327 | xi db 0 ;循环查找fat值时使用 328 | fatCount db 0 ;Loader.bin占用fat值的个数 329 | fatList times 2 db 0 ;fat值列表 2个 330 | fatendoffset dw 0 ;fat1表结尾处的偏移值 331 | fileSize dw 0 ;loader.bin文件的大小 332 | 333 | times 510-($-$$) db 0 ; 填充剩下的空间 使生成的二进制代码恰好为512字节 334 | dw 0xaa55 ;引导扇区结束标志 335 | 336 | 337 | -------------------------------------------------------------------------------- /boot/boot.asm: -------------------------------------------------------------------------------- 1 | ;将镜像加载到内存,每次加载一个扇区,为的是从中找到Loader.bin文件 2 | ;找到后将其加载到内存的指定位置 3 | ;最后跳转到该位置 将控制权交给Loader.bin 4 | org 07c00h ;bios 可将引导扇区加载到0:7c00 处 并开始执行 5 | 6 | ;宏定义 编译阶段宏会被删除 7 | BaseOfStack equ 07c00h ; 堆栈基地址(栈底, 从这个位置向低地址生长) 8 | BaseOfLoader equ 09000h 9 | OffsetOfLoader equ 0100h 10 | 11 | ;======================================================== 12 | jmp short startx ; Start to boot. 13 | nop ; 这个 nop 不可少 14 | 15 | %include "fat12hdr.inc" 16 | %include "common.inc" 17 | startx: 18 | mov ax,cs 19 | mov ds,ax 20 | mov es,ax 21 | mov ss,ax 22 | mov sp,BaseOfStack 23 | 24 | ;清屏 25 | mov ah,6 26 | mov al,0 27 | mov cl,0 28 | mov ch,0 29 | mov dh,24 30 | mov dl,79 31 | mov bh,7 32 | int 10h 33 | 34 | ;显示Booting... 35 | ;mov ax,msg_boot 36 | ;mov cx,10 37 | ;call dispstr 38 | 39 | ; 软驱复位 40 | xor ah,ah 41 | xor dl,dl 42 | int 13h 43 | 44 | 45 | mov byte [secnum],SecNumOfRootDir ;保存根目录起始扇区号19 46 | mov byte [SecLoopCount],RootDirSecCount ;循环读取扇区次数 14 47 | Read: 48 | cmp byte [SecLoopCount],0 49 | jz finish ;若读完14个扇区仍未找到則显示磁盘中没有Loader.bin文件 50 | dec byte [SecLoopCount] 51 | 52 | ;准备存放缓冲区 es:bx 53 | mov ax,BaseOfLoader 54 | mov es,ax 55 | mov bx,OffsetOfLoader 56 | 57 | movzx ax,byte [secnum] ; 起始扇区号 58 | mov cl,1 ; 每次读取一个扇区 59 | call ReadSector ; 60 | 61 | cld ;将 DF 置为0 使得di si按增量方式增长 62 | mov dx,0x10 ;共读取16遍一个扇区512字节 63 | ;显示Finding... 64 | ;mov ax,msg_find 65 | ;mov cx,18 66 | ;call dispstr 67 | 68 | ;mov ax,BaseOfLoader 69 | ;mov es,ax 70 | mov di,OffsetOfLoader 71 | findFile: ;开始查找 72 | 73 | mov si,filename 74 | mov cx,11 75 | cmpfilename: ;比较文件名称 lodsb --> si 自增或自减 76 | lodsb ;ds:si 77 | cmp al,byte [es:di] 78 | jnz nextfile 79 | inc di 80 | loop cmpfilename 81 | jmp finded 82 | 83 | nextfile: ;转到下一个文件 84 | dec dx 85 | cmp dx,0 86 | jz Read 87 | add di,0x20 ;每个目录文件大小为32字节 88 | jmp findFile 89 | 90 | finish: 91 | mov ax,msg_nofind 92 | mov cx,9 93 | call dispstr 94 | jmp $ 95 | 96 | finded: 97 | mov dx,0 98 | 99 | mov cx,word [es:di+26-11] ;获取文件开始簇号 偏移为26 100 | ;而文件名偏移为0占用11 byte 101 | mov ax,cx 102 | push ax ;保存fat值 103 | sub ax,2 ;头两个fat值不使用 104 | add ax,SecNumOfRootDir ;根目录开始扇区号 19 105 | add ax,RootDirSecCount ;根目录占用的扇区数 14 106 | 107 | Goon_Loading: 108 | mov cl,1 109 | call ReadSector ;每次读取1个扇区 110 | pop ax 111 | call GetFat 112 | cmp ax,0xFFF 113 | jz jmptoloader 114 | push ax ;保存fat值 115 | sub ax,2 ;头两个fat值不使用 116 | add ax,SecNumOfRootDir ;根目录开始扇区号 19 117 | add ax,RootDirSecCount ;根目录占用的扇区数 14 118 | add bx,[BPB_BytsPerSec] ;每加载完一个扇区則向前移动一个扇区 119 | jmp Goon_Loading 120 | ;====================================================================== 121 | ;========================== 获取fat值 =============================== 122 | ;====================================================================== 123 | 124 | GetFat: 125 | push es 126 | push bx 127 | push ax 128 | mov ax,es 129 | sub ax,0x100 ;取出4K空间用来加载fat表中的数据 130 | mov es,ax 131 | 132 | pop ax ;文件开始簇号 133 | mov bx,3 134 | mul bx 135 | mov bx,2 136 | div bx ;计算出fat值在fat表中的相对位置 137 | ;ax 为商 dx为余数 138 | mov byte [odd] ,0 139 | cmp dx,0 140 | jz Get 141 | mov byte [odd],1 ;若是第奇数项則标记 142 | Get: 143 | xor dx,dx ;这步不能少 做除法时先清空余数?待解决 144 | mov bx,[BPB_BytsPerSec] 145 | div bx ;使用ax除以每个扇区的容量512 即可得到 146 | ;下一个fat值可以从哪个扇区读取 147 | push dx ;保存fat值在扇区中的偏移 148 | mov bx,0 149 | add ax,1 ;fat表从第二个扇区开始,1+ax 即是 150 | ;当前fat值所在的扇区 151 | mov cl,2 ;每次读取2个扇区 避免在边界发生错误 152 | call ReadSector 153 | 154 | pop bx ;获取fat值在扇区中的偏移 155 | mov ax,[es:bx] ;获取下一个fat值 156 | cmp byte [odd],1 157 | jnz label ;若是奇数项(注意是从0开始,所以第一项为0 应该算偶数项)則取后三位 and ax,0x0FFF 158 | shr ax,4 ;若是偶数项則取前三位 159 | label: 160 | and ax,0x0FFF 161 | pop bx 162 | pop es 163 | ;push ax 164 | ret 165 | 166 | ;=========================================================================================== 167 | ;================================= 加载Loader到内存 ===================================== 168 | ;=========================================================================================== 169 | jmptoloader: 170 | mov ax,0 171 | mov es,ax 172 | mov ax,msg_finded 173 | mov cx,6 174 | call dispstr 175 | 176 | mov dx,30000 177 | .for1: 178 | mov cx,400 179 | .go: 180 | dec cx 181 | cmp cx,0 182 | jnz .go 183 | dec dx 184 | cmp dx,0 185 | jnz .for1 186 | 187 | ;将控制权交给Loader 188 | jmp BaseOfLoader:OffsetOfLoader 189 | 190 | 191 | ;=========================================================================================== 192 | ;================================= 显示字符串 ========================================= 193 | ;=========================================================================================== 194 | 195 | ;badClus: ;显示Loader.bin中存在坏簇 196 | ;mov ax,msg_bad 197 | ;mov cx,8 198 | ;call dispstr 199 | ;jmp $ 200 | 201 | ;badFAT: 202 | ;mov ax,msg_badfat 203 | ;mov cx,14 204 | ;call dispstr 205 | ;jmp $ 206 | 207 | ;dispstr: ;调用时需指定ax字符串,cx长度 208 | ;;call clear 209 | ;mov bp,ax ;es:bp 210 | ;mov ax,1301h ; AH = 13 AL = 01H 211 | ;mov bx,000ch ;页号为0 黑底红字 BL=0ch 212 | ;mov dl,35 ;列数 213 | ;mov dh,12 ;行数 214 | ;int 10h 215 | ;;call delay 216 | ;ret 217 | 218 | 219 | 220 | ;delay: ;在虚拟机下执行60000*600次循环 221 | ;相当于6秒钟,而实际情况可能会快2-3倍 222 | ; mov dx,60000 223 | ; .for1: 224 | ; ;mov ax,10 225 | ; ;.for2: 226 | ; mov cx,400 227 | ; .go: 228 | ; dec cx 229 | ; cmp cx,0 230 | ; jnz .go 231 | ; 232 | ; ;dec ax 233 | ; ;cmp ax,0 234 | ; ;jnz .for2 235 | ; 236 | ; dec dx 237 | ; cmp dx,0 238 | ; jnz .for1 239 | ;ret 240 | 241 | ;=========================================================================================== 242 | ;================================= 读取扇区 ========================================= 243 | ;=========================================================================================== 244 | ReadSector: ;读取磁盘 从第AX个扇区开始 将cl个扇区读入到ES:BX中 245 | ;扇区号为X 246 | ; |柱面号 = y >> 1 247 | ; X |商 y | 248 | ;-------------=>-| |磁头号 = y & 1 249 | ; | 250 | ; |余 z => 起始扇区号 = z + 1 251 | push bp 252 | mov bp,sp 253 | sub esp,2 ;劈出两个字节的堆栈区保存要读的扇区数:byte [bp-2] 254 | 255 | mov byte [bp-2],cl 256 | push bx 257 | mov bl,[BPB_SecPerTrk] ; bl是除数 BPB_SecPerTrk=每磁道扇区数 258 | div bl ;低8位为商 高8位为余数 259 | inc ah ;余数+1 260 | mov cl,ah ;cl->起始扇区号 261 | mov dh,al 262 | shr al,1 263 | mov ch,al ;柱面号 264 | and dh,1 ;磁头号 265 | pop bx 266 | ;至此 柱面号,起始扇区,磁头号 全部就绪 267 | mov dl,[BS_DrvNum] ;驱动器号 268 | .goon: 269 | mov ah,2 ;读 270 | mov al,byte [bp-2] ;读 al 个扇区 271 | int 13h 272 | jc .goon ;如果读取错误 CF 会被置为 1,这时会不停的读 直到正确为止 273 | 274 | add esp,2 275 | pop bp 276 | 277 | ret 278 | 279 | ;若将字符串放在开头則计算机会将字符串视为指令来执行 280 | filename db "LOADER BIN",0 ;文件名为11字节 281 | msg_nofind db "No Loader",0 282 | msg_finded db "Ready!",0 283 | ;msg_boot db "Booting...",0 284 | msg_bad db "Bad clus",0 285 | msg_badfat db "Fat damaged...",0 286 | secnum db 0 ;扇区号 287 | SecLoopCount db 14 ;根目录所占扇区数 288 | odd db 0 289 | 290 | times 510-($-$$) db 0 ; 填充剩下的空间 使生成的二进制代码恰好为512字节 291 | dw 0xaa55 ;引导扇区结束标志 292 | 293 | 294 | -------------------------------------------------------------------------------- /boot/boot.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linkypi/MyOS/c3ee437c3f41a82eab6a61119938357794617a9d/boot/boot.bin -------------------------------------------------------------------------------- /boot/include/common.inc: -------------------------------------------------------------------------------- 1 | ;============== 显示字符串 ============ 2 | badClus: ;显示Loader.bin中存在坏簇 3 | mov ax,msg_bad 4 | mov cx,8 5 | call dispstr 6 | jmp $ 7 | 8 | badFAT: 9 | mov ax,msg_badfat 10 | mov cx,14 11 | call dispstr 12 | jmp $ 13 | 14 | dispstr: ;调用时需指定ax字符串,cx长度 15 | ;call clear 16 | mov bp,ax ;es:bp 17 | mov ax,1301h ; AH = 13 AL = 01H 18 | mov bx,000ch ;页号为0 黑底红字 BL=0ch 19 | mov dl,35 ;列数 20 | mov dh,12 ;行数 21 | int 10h 22 | ;call delay 23 | ret 24 | 25 | 26 | -------------------------------------------------------------------------------- /boot/include/fat12hdr.inc: -------------------------------------------------------------------------------- 1 | ; 下面是 FAT12 磁盘的头 2 | BS_OEMName DB 'ForrestY' ; OEM String, 必须 8 个字节 3 | BPB_BytsPerSec DW 512 ; 每扇区字节数 4 | BPB_SecPerClus DB 1 ; 每簇多少扇区 5 | BPB_RsvdSecCnt DW 1 ; Boot 记录占用多少扇区 6 | BPB_NumFATs DB 2 ; 共有多少 FAT 表 7 | BPB_RootEntCnt DW 224 ; 根目录文件数最大值 8 | BPB_TotSec16 DW 2880 ; 逻辑扇区总数 9 | BPB_Media DB 0xF0 ; 媒体描述符 10 | BPB_FATSz16 DW 9 ; 每FAT扇区数 11 | BPB_SecPerTrk DW 18 ; 每磁道扇区数 12 | BPB_NumHeads DW 2 ; 磁头数(面数) 13 | BPB_HiddSec DD 0 ; 隐藏扇区数 14 | BPB_TotSec32 DD 0 ; 如果 wTotalSectorCount 是 0 由这个值记录扇区数 15 | BS_DrvNum DB 0 ; 中断 13 的驱动器号 16 | BS_Reserved1 DB 0 ; 未使用 17 | BS_BootSig DB 29h ; 扩展引导标记 (29h) 18 | BS_VolID DD 0 ; 卷序列号 19 | BS_VolLab DB 'OrangeS0.02'; 卷标, 必须 11 个字节 20 | BS_FileSysType DB 'FAT12 ' ; 文件系统类型, 必须 8个字节 21 | 22 | 23 | RootDirSecCount equ 14 ;根目录所占扇区数 24 | SecNumOfRootDir equ 19 ;根目录开始扇区号 25 | -------------------------------------------------------------------------------- /boot/include/load.inc: -------------------------------------------------------------------------------- 1 | BaseOfLoader equ 09000h ; LOADER.BIN 被加载到的位置 ---- 段地址 2 | OffsetOfLoader equ 0100h ; LOADER.BIN 被加载到的位置 ---- 偏移地址 3 | 4 | BaseOfLoaderPhyAddr equ BaseOfLoader*10h ; LOADER.BIN 被加载到的位置 ---- 物理地址 5 | 6 | BaseOfKernel equ 08000h ; KERNEL.BIN 被加载到的位置 ---- 段地址 7 | OffsetOfKernel equ 0h ; KERNEL.BIN 被加载到的位置 ---- 偏移地址 8 | 9 | BaseOfKernelPhyAddr equ BaseOfKernel * 10h 10 | KernelEntryPointPhyAddr equ 030400h ;注意1.必须与makefile中参数-Ttext的值相等 11 | ;2.这是地址而非偏移 12 | 13 | PageDirBase equ 200000h ;页目录开始地址 2M 14 | PageTblBase equ 201000h ;页表开始地址 2M + 4K 15 | -------------------------------------------------------------------------------- /boot/include/pm.inc: -------------------------------------------------------------------------------- 1 | 2 | 3 | ; 描述符图示 4 | 5 | ; 图示一 6 | ; 7 | ; ------ ┏━━┳━━┓高地址 8 | ; ┃ 7 ┃ 段 ┃ 9 | ; ┣━━┫ ┃ 10 | ; 基 11 | ; 字节 7 ┆ ┆ ┆ 12 | ; 址 13 | ; ┣━━┫ ② ┃ 14 | ; ┃ 0 ┃ ┃ 15 | ; ------ ┣━━╋━━┫ 16 | ; ┃ 7 ┃ G ┃ 17 | ; ┣━━╉──┨ 18 | ; ┃ 6 ┃ D ┃ 19 | ; ┣━━╉──┨ 20 | ; ┃ 5 ┃ 0 ┃ 21 | ; ┣━━╉──┨ 22 | ; ┃ 4 ┃ AVL┃ 23 | ; 字节 6 ┣━━╉──┨ 24 | ; ┃ 3 ┃ ┃ 25 | ; ┣━━┫ 段 ┃ 26 | ; ┃ 2 ┃ 界 ┃ 27 | ; ┣━━┫ 限 ┃ 28 | ; ┃ 1 ┃ ┃ 29 | ; ┣━━┫ ② ┃ 30 | ; ┃ 0 ┃ ┃ 31 | ; ------ ┣━━╋━━┫ 32 | ; ┃ 7 ┃ P ┃ 33 | ; ┣━━╉──┨ 34 | ; ┃ 6 ┃ ┃ 35 | ; ┣━━┫ DPL┃ 36 | ; ┃ 5 ┃ ┃ 37 | ; ┣━━╉──┨ 38 | ; ┃ 4 ┃ S ┃ 39 | ; 字节 5 ┣━━╉──┨ 40 | ; ┃ 3 ┃ ┃ 41 | ; ┣━━┫ T ┃ 42 | ; ┃ 2 ┃ Y ┃ 43 | ; ┣━━┫ P ┃ 44 | ; ┃ 1 ┃ E ┃ 45 | ; ┣━━┫ ┃ 46 | ; ┃ 0 ┃ ┃ 47 | ; ------ ┣━━╋━━┫ 48 | ; ┃ 23 ┃ ┃ 49 | ; ┣━━┫ ┃ 50 | ; ┃ 22 ┃ ┃ 51 | ; ┣━━┫ 段 ┃ 52 | ; 53 | ; 字节 ┆ ┆ 基 ┆ 54 | ; 2, 3, 4 55 | ; ┣━━┫ 址 ┃ 56 | ; ┃ 1 ┃ ① ┃ 57 | ; ┣━━┫ ┃ 58 | ; ┃ 0 ┃ ┃ 59 | ; ------ ┣━━╋━━┫ 60 | ; ┃ 15 ┃ ┃ 61 | ; ┣━━┫ ┃ 62 | ; ┃ 14 ┃ ┃ 63 | ; ┣━━┫ 段 ┃ 64 | ; 65 | ; 字节 0,1┆ ┆ 界 ┆ 66 | ; 67 | ; ┣━━┫ 限 ┃ 68 | ; ┃ 1 ┃ ① ┃ 69 | ; ┣━━┫ ┃ 70 | ; ┃ 0 ┃ ┃ 71 | ; ------ ┗━━┻━━┛低地址 72 | ; 73 | 74 | 75 | ; 图示二 76 | 77 | ; 高地址………………………………………………………………………低地址 78 | 79 | ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 80 | ; |7654321076543210765432107654321076543210765432107654321076543210| <- 共 8 字节 81 | ; |--------========--------========--------========--------========| 82 | ; ┏━━━┳━━━━━━━┳━━━━━━━━━━━┳━━━━━━━┓ 83 | ; ┃31..24┃ (见下图) ┃ 段基址(23..0) ┃ 段界限(15..0)┃ 84 | ; ┃ ┃ ┃ ┃ ┃ 85 | ; ┃ 基址2┃③│②│ ①┃基址1b│ 基址1a ┃ 段界限1 ┃ 86 | ; ┣━━━╋━━━┳━━━╋━━━━━━━━━━━╋━━━━━━━┫ 87 | ; ┃ %6 ┃ %5 ┃ %4 ┃ %3 ┃ %2 ┃ %1 ┃ 88 | ; ┗━━━┻━━━┻━━━┻━━━┻━━━━━━━┻━━━━━━━┛ 89 | ; │ \_________ 90 | ; │ \__________________ 91 | ; │ \________________________________________________ 92 | ; │ \ 93 | ; ┏━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┓ 94 | ; ┃ 7 ┃ 6 ┃ 5 ┃ 4 ┃ 3 ┃ 2 ┃ 1 ┃ 0 ┃ 7 ┃ 6 ┃ 5 ┃ 4 ┃ 3 ┃ 2 ┃ 1 ┃ 0 ┃ 95 | ; ┣━━╋━━╋━━╋━━╋━━┻━━┻━━┻━━╋━━╋━━┻━━╋━━╋━━┻━━┻━━┻━━┫ 96 | ; ┃ G ┃ D ┃ 0 ┃ AVL┃ 段界限 2 (19..16) ┃ P ┃ DPL ┃ S ┃ TYPE ┃ 97 | ; ┣━━┻━━┻━━┻━━╋━━━━━━━━━━━╋━━┻━━━━━┻━━┻━━━━━━━━━━━┫ 98 | ; ┃ ③: 属性 2 ┃ ②: 段界限 2 ┃ ①: 属性1 ┃ 99 | ; ┗━━━━━━━━━━━┻━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━┛ 100 | ; 高地址 低地址 101 | ; 102 | ; 103 | 104 | ; 说明: 105 | ; 106 | ; (1) P: 存在(Present)位。 107 | ; P=1 表示描述符对地址转换是有效的,或者说该描述符所描述的段存在,即在内存中; 108 | ; P=0 表示描述符对地址转换无效,即该段不存在。使用该描述符进行内存访问时会引起异常。 109 | ; 110 | ; (2) DPL: 表示描述符特权级(Descriptor Privilege level),共2位。它规定了所描述段的特权级,用于特权检查,以决定对该段能否访问。 111 | ; 112 | ; (3) S: 说明描述符的类型。 113 | ; 对于存储段描述符而言,S=1,以区别与系统段描述符和门描述符(S=0)。 114 | ; 115 | ; (4) TYPE: 说明存储段描述符所描述的存储段的具体属性。 116 | ; 117 | ; 118 | ; 数据段类型 类型值 说明 119 | ; ---------------------------------- 120 | ; 0 只读 121 | ; 1 只读、已访问 122 | ; 2 读/写 123 | ; 3 读/写、已访问 124 | ; 4 只读、向下扩展 125 | ; 5 只读、向下扩展、已访问 126 | ; 6 读/写、向下扩展 127 | ; 7 读/写、向下扩展、已访问 128 | ; 129 | ; 130 | ; 类型值 说明 131 | ; 代码段类型 ---------------------------------- 132 | ; 8 只执行 133 | ; 9 只执行、已访问 134 | ; A 执行/读 135 | ; B 执行/读、已访问 136 | ; C 只执行、一致码段 137 | ; D 只执行、一致码段、已访问 138 | ; E 执行/读、一致码段 139 | ; F 执行/读、一致码段、已访问 140 | ; 141 | ; 142 | ; 系统段类型 类型编码 说明 143 | ; ---------------------------------- 144 | ; 0 <未定义> 145 | ; 1 可用286TSS 146 | ; 2 LDT 147 | ; 3 忙的286TSS 148 | ; 4 286调用门 149 | ; 5 任务门 150 | ; 6 286中断门 151 | ; 7 286陷阱门 152 | ; 8 未定义 153 | ; 9 可用386TSS 154 | ; A <未定义> 155 | ; B 忙的386TSS 156 | ; C 386调用门 157 | ; D <未定义> 158 | ; E 386中断门 159 | ; F 386陷阱门 160 | ; 161 | ; (5) G: 段界限粒度(Granularity)位。 162 | ; G=0 表示界限粒度为字节; 163 | ; G=1 表示界限粒度为4K 字节。 164 | ; 注意,界限粒度只对段界限有效,对段基地址无效,段基地址总是以字节为单位。 165 | ; 166 | ; (6) D: D位是一个很特殊的位,在描述可执行段、向下扩展数据段或由SS寄存器寻址的段(通常是堆栈段)的三种描述符中的意义各不相同。 167 | ; ⑴ 在描述可执行段的描述符中,D位决定了指令使用的地址及操作数所默认的大小。 168 | ; ① D=1表示默认情况下指令使用32位地址及32位或8位操作数,这样的代码段也称为32位代码段; 169 | ; ② D=0 表示默认情况下,使用16位地址及16位或8位操作数,这样的代码段也称为16位代码段,它与80286兼容。可以使用地址大小前缀和操作数大小前缀分别改变默认的地址或操作数的大小。 170 | ; ⑵ 在向下扩展数据段的描述符中,D位决定段的上部边界。 171 | ; ① D=1表示段的上部界限为4G; 172 | ; ② D=0表示段的上部界限为64K,这是为了与80286兼容。 173 | ; ⑶ 在描述由SS寄存器寻址的段描述符中,D位决定隐式的堆栈访问指令(如PUSH和POP指令)使用何种堆栈指针寄存器。 174 | ; ① D=1表示使用32位堆栈指针寄存器ESP; 175 | ; ② D=0表示使用16位堆栈指针寄存器SP,这与80286兼容。 176 | ; 177 | ; (7) AVL: 软件可利用位。80386对该位的使用未左规定,Intel公司也保证今后开发生产的处理器只要与80386兼容,就不会对该位的使用做任何定义或规定。 178 | ; 179 | 180 | 181 | ;---------------------------------------------------------------------------- 182 | ; 描述符类型值说明 183 | ; 其中: 184 | ; DA_ : Descriptor Attribute 185 | ; D : 数据段 186 | ; C : 代码段 187 | ; S : 系统段 188 | ; R : 只读 189 | ; RW : 读写 190 | ; A : 已访问 191 | ; 其它 : 可按照字面意思理解 192 | ;---------------------------------------------------------------------------- 193 | DA_32 EQU 4000h ; 32 位段 194 | DA_LIMIT_4K EQU 8000h ; 段界限粒度为 4K 字节 195 | 196 | DA_DPL0 EQU 00h ; DPL = 0 197 | DA_DPL1 EQU 20h ; DPL = 1 198 | DA_DPL2 EQU 40h ; DPL = 2 199 | DA_DPL3 EQU 60h ; DPL = 3 200 | ;---------------------------------------------------------------------------- 201 | ; 存储段描述符类型值说明 202 | ;---------------------------------------------------------------------------- 203 | DA_DR EQU 90h ; 存在的只读数据段类型值 204 | DA_DRW EQU 92h ; 存在的可读写数据段属性值 205 | DA_DRWA EQU 93h ; 存在的已访问可读写数据段类型值 206 | DA_C EQU 98h ; 存在的只执行代码段属性值 207 | DA_CR EQU 9Ah ; 存在的可执行可读代码段属性值 208 | DA_CCO EQU 9Ch ; 存在的只执行一致代码段属性值 209 | DA_CCOR EQU 9Eh ; 存在的可执行可读一致代码段属性值 210 | ;---------------------------------------------------------------------------- 211 | ; 系统段描述符类型值说明 212 | ;---------------------------------------------------------------------------- 213 | DA_LDT EQU 82h ; 局部描述符表段类型值 214 | DA_TaskGate EQU 85h ; 任务门类型值 215 | DA_386TSS EQU 89h ; 可用 386 任务状态段类型值 216 | DA_386CGate EQU 8Ch ; 386 调用门类型值 217 | DA_386IGate EQU 8Eh ; 386 中断门类型值 218 | DA_386TGate EQU 8Fh ; 386 陷阱门类型值 219 | ;---------------------------------------------------------------------------- 220 | 221 | 222 | ; 选择子图示: 223 | ; ┏━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┓ 224 | ; ┃ 15 ┃ 14 ┃ 13 ┃ 12 ┃ 11 ┃ 10 ┃ 9 ┃ 8 ┃ 7 ┃ 6 ┃ 5 ┃ 4 ┃ 3 ┃ 2 ┃ 1 ┃ 0 ┃ 225 | ; ┣━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━╋━━╋━━┻━━┫ 226 | ; ┃ 描述符索引 ┃ TI ┃ RPL ┃ 227 | ; ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━┻━━━━━┛ 228 | ; 229 | ; RPL(Requested Privilege Level): 请求特权级,用于特权检查。 230 | ; 231 | ; TI(Table Indicator): 引用描述符表指示位 232 | ; TI=0 指示从全局描述符表GDT中读取描述符; 233 | ; TI=1 指示从局部描述符表LDT中读取描述符。 234 | ; 235 | 236 | ;---------------------------------------------------------------------------- 237 | ; 选择子类型值说明 238 | ; 其中: 239 | ; SA_ : Selector Attribute 240 | 241 | SA_RPL0 EQU 0 ; ┓ 242 | SA_RPL1 EQU 1 ; ┣ RPL 243 | SA_RPL2 EQU 2 ; ┃ 244 | SA_RPL3 EQU 3 ; ┛ 245 | 246 | SA_TIG EQU 0 ; ┓TI 247 | SA_TIL EQU 4 ; ┛ 248 | ;---------------------------------------------------------------------------- 249 | 250 | 251 | ;---------------------------------------------------------------------------- 252 | ; 分页机制使用的常量说明 253 | ;---------------------------------------------------------------------------- 254 | PG_P EQU 1 ; 页存在属性位 255 | PG_RWR EQU 0 ; R/W 属性位值, 读/执行 256 | PG_RWW EQU 2 ; R/W 属性位值, 读/写/执行 257 | PG_USS EQU 0 ; U/S 属性位值, 系统级 258 | PG_USU EQU 4 ; U/S 属性位值, 用户级 259 | ;---------------------------------------------------------------------------- 260 | 261 | 262 | 263 | 264 | ; ========================================= 265 | ; FLAGS - Intel 8086 Family Flags Register 266 | ; ========================================= 267 | ; 268 | ; |11|10|F|E|D|C|B|A|9|8|7|6|5|4|3|2|1|0| 269 | ; | | | | | | | | | | | | | | | | | '--- CF……Carry Flag 270 | ; | | | | | | | | | | | | | | | | '--- 1 271 | ; | | | | | | | | | | | | | | | '--- PF……Parity Flag 272 | ; | | | | | | | | | | | | | | '--- 0 273 | ; | | | | | | | | | | | | | '--- AF……Auxiliary Flag 274 | ; | | | | | | | | | | | | '--- 0 275 | ; | | | | | | | | | | | '--- ZF……Zero Flag 276 | ; | | | | | | | | | | '--- SF……Sign Flag 277 | ; | | | | | | | | | '--- TF……Trap Flag (Single Step) 278 | ; | | | | | | | | '--- IF……Interrupt Flag 279 | ; | | | | | | | '--- DF……Direction Flag 280 | ; | | | | | | '--- OF……Overflow flag 281 | ; | | | | '----- IOPL……I/O Privilege Level (286+ only) 282 | ; | | | '----- NT……Nested Task Flag (286+ only) 283 | ; | | '----- 0 284 | ; | '----- RF……Resume Flag (386+ only) 285 | ; '------ VM……Virtual Mode Flag (386+ only) 286 | ; 287 | ; 注: see PUSHF POPF STI CLI STD CLD 288 | ; 289 | 290 | 291 | ; 宏 ------------------------------------------------------------------------------------------------------ 292 | ; 293 | ; 描述符 294 | ; usage: Descriptor Base, Limit, Attr 295 | ; Base: dd 296 | ; Limit: dd (low 20 bits available) 297 | ; Attr: dw (lower 4 bits of higher byte are always 0) 298 | %macro Descriptor 3 299 | dw %2 & 0FFFFh ; 段界限 1 (2 字节) 300 | dw %1 & 0FFFFh ; 段基址 1 (2 字节) 301 | db (%1 >> 16) & 0FFh ; 段基址 2 (1 字节) 302 | dw ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh) ; 属性 1 + 段界限 2 + 属性 2 (2 字节) 303 | db (%1 >> 24) & 0FFh ; 段基址 3 (1 字节) 304 | %endmacro ; 共 8 字节 305 | ; 306 | ; 门 307 | ; usage: Gate Selector, Offset, DCount, Attr 308 | ; Selector: dw 309 | ; Offset: dd 310 | ; DCount: db 311 | ; Attr: db 312 | %macro Gate 4 313 | dw (%2 & 0FFFFh) ; 偏移 1 (2 字节) 314 | dw %1 ; 选择子 (2 字节) 315 | dw (%3 & 1Fh) | ((%4 << 8) & 0FF00h) ; 属性 (2 字节) 316 | dw ((%2 >> 16) & 0FFFFh) ; 偏移 2 (2 字节) 317 | %endmacro ; 共 8 字节 318 | ; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 319 | -------------------------------------------------------------------------------- /boot/loader.asm: -------------------------------------------------------------------------------- 1 | ;找到Kernel.bin文件 2 | ;找到后将其加载到内存的指定位置 3 | ;最后跳转到该位置 将控制权交给Kernel.bin 4 | org 0100h 5 | 6 | ;宏定义 编译阶段宏会被删除 7 | BaseOfStack equ 0100h ; 堆栈基地址(栈底, 从这个位置向低地址生长) 8 | 9 | ;======================================================== 10 | jmp startx ; Start to boot. 11 | 12 | %include "fat12hdr.inc" 13 | %include "pm.inc" 14 | %include "load.inc" 15 | %include "common.inc" 16 | ; GDT 17 | ; 段地址 段界限 属性 18 | GDT: Descriptor 0, 0, 0 ;空描述符 19 | Desc_Flag_c: Descriptor 0, 0fffffh, DA_CR|DA_32|DA_LIMIT_4K ; 0-4G 20 | Desc_Flag_rw: Descriptor 0, 0fffffh, DA_DRW|DA_32|DA_LIMIT_4K ; 0-4G 21 | Desc_Video: Descriptor 0B8000h, 0ffffh , DA_DRW|DA_DPL3 ;显存首地址 22 | 23 | GdtLen equ $ - GDT 24 | GdtPtr dw GdtLen - 1 ;段界限 25 | dd BaseOfLoaderPhyAddr + GDT ;基地址 26 | 27 | ;GDT 选择子 28 | SltFlagC equ Desc_Flag_c - GDT 29 | SltFlagRW equ Desc_Flag_rw - GDT 30 | SltVideo equ Desc_Video - GDT + SA_RPL3 31 | 32 | 33 | startx: 34 | mov ax,cs 35 | mov ds,ax 36 | mov es,ax 37 | mov ss,ax 38 | mov sp,BaseOfStack 39 | 40 | ;清屏 41 | mov ah,6 42 | mov al,0 43 | mov cl,0 44 | mov ch,0 45 | mov dh,24 46 | mov dl,79 47 | mov bh,7 48 | int 10h 49 | 50 | 51 | ;得到内存数 52 | mov ebx,0 ;ebx=后续值 开始时需为0 53 | mov di,_MemChkBuf ;es:di 指向一个地址范围描述符结构ARDS 54 | .MemChkLoop: 55 | mov eax, 0E820h ; eax = 0000E820h 56 | mov ecx, 20 ; ecx = 地址范围描述符结构的大小 57 | mov edx, 0534D4150h ; edx = 'SMAP' 58 | int 15h ; int 15h 59 | jc .MemChkFail 60 | add di, 20 61 | inc dword [_dwMCRNumber] ; dwMCRNumber = ARDS 的个数 62 | cmp ebx, 0 63 | jne .MemChkLoop 64 | jmp .MemChkOK 65 | .MemChkFail: 66 | mov dword [_dwMCRNumber], 0 67 | .MemChkOK: 68 | 69 | ;============ 在A盘根目录下寻找KERNEL.BIN =========== 70 | 71 | ; 软驱复位 72 | xor ah,ah 73 | xor dl,dl 74 | int 13h 75 | 76 | 77 | mov byte [secnum],SecNumOfRootDir ;保存根目录起始扇区号 78 | mov byte [SecLoopCount],RootDirSecCount ;循环读取扇区次数 79 | Read: 80 | cmp byte [SecLoopCount],0 81 | jz finish ;若读完14个扇区仍未找到則显示磁盘中没有Loader.bin文件 82 | dec byte [SecLoopCount] 83 | 84 | ;准备存放缓冲区 es:bx 85 | mov ax,BaseOfKernel 86 | mov es,ax 87 | mov bx,OffsetOfKernel 88 | 89 | movzx ax,byte [secnum] ; 起始扇区号 90 | mov cl,1 ; 每次读取一个扇区 91 | call ReadSector ; 92 | 93 | cld ;将 DF 置为0 使得di si按增量方式增长 94 | mov dx,0x10 ;每个文件目录的大小为32字节, 95 | ;一个扇区512字节 共读取16遍 96 | ;显示Finding... 97 | ;mov ax,msg_find 98 | ;mov cx,18 99 | ;call dispstr 100 | 101 | ;mov ax,BaseOfKernel 102 | ;mov es,ax 103 | mov di,OffsetOfKernel 104 | findFile: ;开始查找 105 | 106 | mov si,filename 107 | mov cx,11 108 | cmpfilename: ;比较文件名称 lodsb --> si 自增或自减 109 | lodsb ;ds:si 110 | cmp al,byte [es:di] 111 | jnz nextfile 112 | inc di 113 | loop cmpfilename 114 | jmp finded 115 | 116 | nextfile: ;转到下一个文件 117 | dec dx 118 | cmp dx,0 119 | jz Read 120 | add di,0x20 121 | jmp findFile 122 | 123 | finish: 124 | mov ax,0 125 | mov es,ax 126 | mov ax,msg_nofind 127 | mov cx,9 128 | call dispstr 129 | jmp $ 130 | 131 | finded: 132 | mov dx,0 133 | 134 | mov cx,word [es:di+26-11] ;获取文件开始簇号 偏移为26 135 | ;而文件名偏移为0占用11 byte 136 | mov ax,cx 137 | push ax ;保存fat值 138 | sub ax,2 ;头两个fat值不使用 139 | add ax,SecNumOfRootDir ;根目录开始扇区号 19 140 | add ax,RootDirSecCount ;根目录占用的扇区数 14 141 | 142 | Goon_Loading: 143 | mov cl,1 144 | call ReadSector ;每次读取1个扇区 145 | pop ax 146 | call GetFat 147 | cmp ax,0xFFF 148 | jz jmptokernel 149 | push ax ;保存fat值 150 | sub ax,2 ;头两个fat值不使用 151 | add ax,SecNumOfRootDir ;根目录开始扇区号 19 152 | add ax,RootDirSecCount ;根目录占用的扇区数 14 153 | add bx,[BPB_BytsPerSec] ;每加载完毕一个扇区則向前移动一个扇区 154 | jmp Goon_Loading 155 | ;====================================================================== 156 | ;========================== 获取fat值 =============================== 157 | ;====================================================================== 158 | 159 | GetFat: 160 | push es 161 | push bx 162 | push ax 163 | mov ax,es 164 | sub ax,0x100 165 | mov es,ax 166 | 167 | pop ax ;文件开始簇号 168 | mov bx,3 169 | mul bx 170 | mov bx,2 171 | div bx ;计算出fat值在fat表中的相对位置 172 | ;ax 为商 dx为余数 173 | mov byte [odd] ,0 174 | cmp dx,0 175 | jz Get 176 | mov byte [odd],1 ;若是第奇数项則标记 177 | Get: 178 | xor dx,dx ;这步不能少 做除法时先清空余数?待解决 179 | mov bx,[BPB_BytsPerSec] 180 | div bx ;使用ax除以每个扇区的容量512 即可得到 181 | ;下一个fat值可以从哪个扇区读取 182 | push dx ;保存fat值在扇区中的偏移 183 | mov bx,0 184 | add ax,1 ;fat表从第二个扇区开始,1+ax 即是 185 | ;当前fat值所在的扇区 186 | mov cl,2 ;每次读取2个扇区 避免在边界发生错误 187 | call ReadSector 188 | 189 | pop bx ;获取fat值在扇区中的偏移 190 | mov ax,[es:bx] ;获取下一个fat值 191 | cmp byte [odd],1 192 | jnz label ;若是奇数项(注意是从0开始,所以第一项为0 应该算偶数项)則取后三位 and ax,0x0FFF 193 | shr ax,4 ;若是偶数项則取前三位 194 | label: 195 | and ax,0x0FFF 196 | pop bx 197 | pop es 198 | ret 199 | 200 | ;=========================================================================================== 201 | ;================================= 加载Loader到内存 ===================================== 202 | ;=========================================================================================== 203 | jmptokernel: 204 | 205 | call KillMotor 206 | 207 | mov ax,0 208 | mov es,ax 209 | mov ax,msg_finded 210 | mov cx,7 211 | call dispstr 212 | 213 | ;停顿几秒 214 | mov dx,30000 215 | .for1: 216 | mov cx,400 217 | .go: 218 | dec cx 219 | cmp cx,0 220 | jnz .go 221 | dec dx 222 | cmp dx,0 223 | jnz .for1 224 | 225 | ;下面准备跳入保护模式 226 | lgdt [GdtPtr] 227 | 228 | ;关中断 229 | cli 230 | 231 | ;打开A20地址线 232 | in al,92h 233 | or al,00000010b 234 | out 92h,al 235 | 236 | ;准备切换到保护模式 237 | mov eax,cr0 238 | or eax,1 239 | mov cr0,eax 240 | 241 | ;真正进入保护模式 242 | jmp dword SltFlagC:(BaseOfLoaderPhyAddr+LABEL_PM_START) 243 | 244 | 245 | ;=========================================================================================== 246 | ;================================= 显示字符串 ========================================= 247 | ;=========================================================================================== 248 | 249 | ;badClus: ;显示Loader.bin中存在坏簇 250 | ;mov ax,msg_bad 251 | ;mov cx,8 252 | ;call dispstr 253 | ;jmp $ 254 | 255 | ;badFAT: 256 | ;mov ax,msg_badfat 257 | ;mov cx,14 258 | ;call dispstr 259 | ;jmp $ 260 | 261 | ;dispstr: ;调用时需指定ax字符串,cx长度 262 | ;;call clear 263 | ;mov bp,ax ;es:bp 264 | ;mov ax,1301h ; AH = 13 AL = 01H 265 | ;mov bx,000ch ;页号为0 黑底红字 BL=0ch 266 | ;mov dl,35 ;列数 267 | ;mov dh,12 ;行数 268 | ;int 10h 269 | ;;call delay 270 | ;ret 271 | 272 | 273 | ;=========================================================================================== 274 | ;================================= 读取扇区 ========================================= 275 | ;=========================================================================================== 276 | ReadSector: ;读取磁盘 从第AX个扇区开始 将cl个扇区读入到ES:BX中 277 | ;扇区号为X 278 | ; |柱面号 = y >> 1 279 | ; X |商 y | 280 | ;-------------=>-| |磁头号 = y & 1 281 | ; | 282 | ; |余 z => 起始扇区号 = z + 1 283 | push bp 284 | mov bp,sp 285 | sub esp,2 ;劈出两个字节的堆栈区保存要读的扇区数:byte [bp-2] 286 | 287 | mov byte [bp-2],cl 288 | push bx 289 | mov bl,[BPB_SecPerTrk] ; bl是除数 BPB_SecPerTrk=每磁道扇区数 290 | div bl ;低8位为商 高8位为余数 291 | inc ah ;余数+1 292 | mov cl,ah ;cl->起始扇区号 293 | mov dh,al 294 | 295 | shr al,1 296 | mov ch,al ;柱面号 297 | and dh,1 ;磁头号 298 | pop bx 299 | ;至此 柱面号,起始扇区,磁头号 全部就绪 300 | mov dl,[BS_DrvNum] ;驱动器号 301 | .goon: 302 | mov ah,2 ;读 303 | mov al,byte [bp-2] ;读 al 个扇区 304 | int 13h 305 | jc .goon ;如果读取错误 CF 会被置为 1,这时会不停的读 直到正确为止 306 | 307 | add esp,2 308 | pop bp 309 | 310 | ret 311 | ;============ 关闭马达 ========= 312 | KillMotor: 313 | push dx 314 | mov dx,03F2h 315 | mov al,0 316 | out dx,al 317 | pop dx 318 | ret 319 | 320 | 321 | ;若将字符串放在开头則计算机会将字符串视为指令来执行 322 | filename db "KERNEL BIN",0 ;文件名为11字节 323 | msg_nofind db "No kernel",0 324 | msg_finded db "Kernel!",0 325 | ;msg_boot db "Booting...",0 326 | msg_bad db "Bad clus",0 327 | msg_badfat db "Fat damaged...",0 328 | secnum db 0 ;扇区号 329 | SecLoopCount db 14 ;根目录所占扇区数 330 | odd db 0 331 | 332 | 333 | ;进入保护模式 334 | [SECTION .s32] 335 | ALIGN 32 336 | 337 | [BITS 32] 338 | 339 | LABEL_PM_START: 340 | mov ax, SltVideo 341 | mov gs, ax 342 | 343 | mov ax, SltFlagRW 344 | mov ds, ax 345 | mov es, ax 346 | mov fs, ax 347 | mov ss, ax 348 | mov esp, TopOfStack 349 | 350 | push szMemChkTitle 351 | call DispPMStr 352 | add esp, 4 353 | 354 | call DispMemInfo 355 | call SetupPaging 356 | 357 | ;mov ah, 0Fh ; 0000: 黑底 1111: 白字 358 | ;mov al, 'P' 359 | ;mov [gs:((80 * 0 + 39) * 2)], ax ; 屏幕第 0 行, 第 39 列 360 | 361 | call InitKernel 362 | 363 | ;正式进入内核 364 | jmp SltFlagC:KernelEntryPointPhyAddr 365 | 366 | ;%include "lib.inc" ;因为在保护模式下显示内存使用情况 367 | ;所以这段显示的函数必须放在32位代码段中 368 | 369 | 370 | ; ------------------------------------------------------------------------ 371 | ; 显示 AL 中的数字 372 | ; ------------------------------------------------------------------------ 373 | DispAL: 374 | push ecx 375 | push edx 376 | push edi 377 | 378 | mov edi,dword [dwDispPos] 379 | 380 | mov ah, 0Fh ; 0000b: 黑底 1111b: 白字 381 | mov dl, al 382 | shr al, 4 383 | mov ecx, 2 384 | .begin: 385 | and al, 01111b 386 | cmp al, 9 387 | ja .1 388 | add al, '0' 389 | jmp .2 390 | .1: 391 | sub al, 0Ah 392 | add al, 'A' 393 | .2: 394 | mov [gs:edi], ax 395 | add edi, 2 396 | 397 | mov al, dl 398 | loop .begin 399 | ;add edi, 2 400 | 401 | mov [dwDispPos], edi 402 | 403 | pop edi 404 | pop edx 405 | pop ecx 406 | 407 | ret 408 | ; DispAL 结束------------------------------------------------------------- 409 | 410 | ;------------------------------------------------------------------------- 411 | ;换行 412 | ;------------------------------------------------------------------------- 413 | DispReturn: 414 | push szReturn 415 | call DispPMStr 416 | add esp,4 417 | ret 418 | 419 | 420 | ; ------------------------------------------------------------------------ 421 | ; 显示一个整形数 422 | ; ------------------------------------------------------------------------ 423 | DispInt: 424 | mov eax, [esp + 4] 425 | shr eax, 24 426 | call DispAL 427 | 428 | mov eax, [esp + 4] 429 | shr eax, 16 430 | call DispAL 431 | 432 | mov eax, [esp + 4] 433 | shr eax, 8 434 | call DispAL 435 | 436 | mov eax, [esp + 4] 437 | call DispAL 438 | 439 | mov ah, 07h ; 0000b: 黑底 0111b: 灰字 440 | mov al, 'h' 441 | push edi 442 | mov edi, [dwDispPos] 443 | mov [gs:edi], ax 444 | add edi, 4 445 | mov [dwDispPos], edi 446 | pop edi 447 | 448 | ret 449 | ; DispInt 结束------------------------------------------------------------ 450 | 451 | ; ------------------------------------------------------------------------ 452 | ; 显示一个字符串 453 | ; ------------------------------------------------------------------------ 454 | DispPMStr: 455 | push ebp 456 | mov ebp, esp 457 | push ebx 458 | push esi 459 | push edi 460 | 461 | mov esi, [ebp + 8] ; pszInfo 462 | mov edi, [dwDispPos] 463 | mov ah, 0Fh 464 | .1: 465 | lodsb 466 | test al, al 467 | jz .2 468 | cmp al, 0Ah ; 是回车吗? 469 | jnz .3 470 | push eax 471 | mov eax, edi 472 | mov bl, 160 473 | div bl 474 | and eax, 0FFh 475 | inc eax 476 | mov bl, 160 477 | mul bl 478 | mov edi, eax 479 | pop eax 480 | jmp .1 481 | .3: 482 | mov [gs:edi], ax 483 | add edi, 2 484 | jmp .1 485 | 486 | .2: 487 | mov [dwDispPos], edi 488 | 489 | pop edi 490 | pop esi 491 | pop ebx 492 | pop ebp 493 | ret 494 | ; DispPMStr 结束------------------------------------------------------------ 495 | 496 | 497 | 498 | ;------------------------------------------------- 499 | ;InitKernel 500 | ;------------------------------------------------- 501 | ;将kernel.bin的内容经过整理对齐后放到行的位置 502 | ;首先取得ELF文件中program header的个数 503 | ;然后根据个数来遍历加载Program header 504 | ;------------------------------------------------- 505 | InitKernel: 506 | xor esi,esi 507 | mov cx,word [BaseOfKernelPhyAddr+2ch] ;在ELF Header中取得Program header的个数 508 | movzx ecx,cx 509 | mov esi,[BaseOfKernelPhyAddr+ 1Ch] ; program header开始的地址偏移 e_poff 510 | add esi,BaseOfKernelPhyAddr ;将指针指向第一个Program header 511 | .begin: 512 | mov eax,[esi+0] 513 | cmp eax,0 514 | jz .null 515 | push dword [esi+010h] ;size 516 | mov eax,[esi+04h] ;取得第一个字节在文件中的偏移 517 | add eax,BaseOfKernelPhyAddr 518 | push eax ;src 519 | push dword [esi+08h] ;dst 第一个字节在内存中的虚拟地址 520 | call MemCpy 521 | add esp,12 ;3个参数入栈执行复制函数完毕后将栈指针复原 522 | .null: 523 | add esi,020h ;每个Program Header大小为32 Bytes 524 | dec cx 525 | jnz .begin 526 | ret 527 | 528 | ;---------------------------------------------------- 529 | ;内存拷贝 仿memcpy 530 | ;---------------------------------------------------- 531 | ;void* MemCpy(void* es:pDest,void* ds:pSrc,int iSize); 532 | ;---------------------------------------------------- 533 | MemCpy: 534 | push ebp 535 | mov ebp,esp 536 | 537 | push esi 538 | push edi 539 | push ecx 540 | 541 | mov edi,[ebp+8] ;Destination 542 | mov esi,[ebp+12];Source 543 | mov ecx,[ebp+16];counter 544 | .1: 545 | cmp ecx,0 546 | jz .2 547 | mov al,[ds:esi] 548 | inc esi 549 | 550 | mov byte [es:edi],al 551 | inc edi 552 | 553 | dec ecx 554 | jmp .1 555 | .2: 556 | mov eax,[ebp+8] ;返回值 557 | 558 | pop ecx 559 | pop edi 560 | pop esi 561 | mov esp,ebp 562 | pop ebp 563 | 564 | ret 565 | 566 | ; 显示内存信息 -------------------------------------------------------------- 567 | DispMemInfo: 568 | push esi 569 | push edi 570 | push ecx 571 | 572 | mov esi, MemChkBuf 573 | mov ecx, [dwMCRNumber];for(int i=0;i<[MCRNumber];i++)//每次得到一个ARDS 574 | .loop: ;{ 575 | mov edx, 5 ; for(int j=0;j<5;j++)//每次得到一个ARDS中的成员 576 | mov edi, ARDStruct ; {//依次显示:BaseAddrLow,BaseAddrHigh,LengthLow 577 | .1: ; LengthHigh,Type 578 | push dword [esi] ; 579 | call DispInt ; DispInt(MemChkBuf[j*4]); // 显示一个成员 580 | pop eax ; 581 | stosd ; ARDStruct[j*4] = MemChkBuf[j*4]; 582 | add esi, 4 ; 583 | dec edx ; 584 | cmp edx, 0 ; 585 | 586 | jnz .1 ; } 587 | call DispReturn ; printf("\n"); 588 | cmp dword [dwType], 1 ; if(Type == AddressRangeMemory) 589 | jne .2 ; { 590 | mov eax, [dwBaseAddrLow]; 591 | add eax, [dwLengthLow]; 592 | cmp eax, [dwMemSize] ; if(BaseAddrLow + LengthLow > MemSize) 593 | jb .2 ; 594 | mov [dwMemSize], eax ; MemSize = BaseAddrLow + LengthLow; 595 | .2: ; } 596 | loop .loop ;} 597 | ; 598 | call DispReturn ;printf("\n"); 599 | push szRAMSize ; 600 | call DispPMStr ;printf("RAM size:"); 601 | add esp, 4 ; 602 | ; 603 | push dword [dwMemSize] ; 604 | call DispInt ;DispInt(MemSize); 605 | add esp, 4 ; 606 | 607 | pop ecx 608 | pop edi 609 | pop esi 610 | ret 611 | ; --------------------------------------------------------------------------- 612 | 613 | ; 启动分页机制 -------------------------------------------------------------- 614 | SetupPaging: 615 | ; 根据内存大小计算应初始化多少PDE以及多少页表 616 | xor edx, edx 617 | mov eax, [dwMemSize] 618 | mov ebx, 400000h ; 400000h = 4M = 4096 * 1024, 一个页表对应的内存大小 619 | div ebx 620 | mov ecx, eax ; 此时 ecx 为页表的个数,也即 PDE 应该的个数 621 | test edx, edx 622 | jz .no_remainder 623 | inc ecx ; 如果余数不为 0 就需增加一个页表 624 | .no_remainder: 625 | push ecx ; 暂存页表个数 626 | 627 | ; 为简化处理, 所有线性地址对应相等的物理地址. 并且不考虑内存空洞. 628 | 629 | ; 首先初始化页目录 630 | mov ax, SltFlagRW 631 | mov es, ax 632 | mov edi, PageDirBase ; 此段首地址为 PageDirBase 633 | xor eax, eax 634 | mov eax, PageTblBase | PG_P | PG_USU | PG_RWW 635 | .1: 636 | stosd 637 | add eax, 4096 ; 为了简化, 所有页表在内存中是连续的 638 | loop .1 639 | 640 | ; 再初始化所有页表 641 | pop eax ; 页表个数 642 | mov ebx, 1024 ; 每个页表 1024 个 PTE 643 | mul ebx 644 | mov ecx, eax ; PTE个数 = 页表个数 * 1024 645 | mov edi, PageTblBase ; 此段首地址为 PageTblBase 646 | xor eax, eax 647 | mov eax, PG_P | PG_USU | PG_RWW 648 | .2: 649 | stosd 650 | add eax, 4096 ; 每一页指向 4K 的空间 651 | loop .2 652 | 653 | mov eax, PageDirBase 654 | mov cr3, eax 655 | mov eax, cr0 656 | or eax, 80000000h 657 | mov cr0, eax 658 | jmp short .3 659 | .3: 660 | nop 661 | 662 | ret 663 | ; 分页机制启动完毕 ---------------------------------------------------------- 664 | 665 | 666 | ; SECTION .data1 之开始 --------------------------------------------------------------------------------------------- 667 | [SECTION .data1] 668 | 669 | ALIGN 32 670 | 671 | LABEL_DATA: 672 | ; 实模式下使用这些符号 673 | ; 字符串 674 | _szMemChkTitle: db "BaseAddrL BaseAddrH LengthLow LengthHigh Type", 0Ah, 0 675 | _szRAMSize: db "RAM size:", 0 676 | _szReturn: db 0Ah, 0 677 | ;; 变量 678 | _dwMCRNumber: dd 0 ; Memory Check Result 679 | _dwDispPos: dd (80 * 6 + 0) * 2 ; 屏幕第 6 行, 第 0 列 680 | _dwMemSize: dd 0 681 | _ARDStruct: ; Address Range Descriptor Structure 682 | _dwBaseAddrLow: dd 0 683 | _dwBaseAddrHigh: dd 0 684 | _dwLengthLow: dd 0 685 | _dwLengthHigh: dd 0 686 | _dwType: dd 0 687 | _MemChkBuf: times 256 db 0 688 | ; 689 | ;; 保护模式下使用这些符号 690 | szMemChkTitle equ BaseOfLoaderPhyAddr + _szMemChkTitle 691 | szRAMSize equ BaseOfLoaderPhyAddr + _szRAMSize 692 | szReturn equ BaseOfLoaderPhyAddr + _szReturn 693 | dwDispPos equ BaseOfLoaderPhyAddr + _dwDispPos 694 | dwMemSize equ BaseOfLoaderPhyAddr + _dwMemSize 695 | dwMCRNumber equ BaseOfLoaderPhyAddr + _dwMCRNumber 696 | ARDStruct equ BaseOfLoaderPhyAddr + _ARDStruct 697 | dwBaseAddrLow equ BaseOfLoaderPhyAddr + _dwBaseAddrLow 698 | dwBaseAddrHigh equ BaseOfLoaderPhyAddr + _dwBaseAddrHigh 699 | dwLengthLow equ BaseOfLoaderPhyAddr + _dwLengthLow 700 | dwLengthHigh equ BaseOfLoaderPhyAddr + _dwLengthHigh 701 | dwType equ BaseOfLoaderPhyAddr + _dwType 702 | MemChkBuf equ BaseOfLoaderPhyAddr + _MemChkBuf 703 | 704 | 705 | ; 堆栈就在数据段的末尾 706 | StackSpace: times 1024 db 0 707 | TopOfStack equ BaseOfLoaderPhyAddr + $ ; 栈顶 708 | ; SECTION .data1 之结束 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 709 | 710 | 711 | 712 | 713 | -------------------------------------------------------------------------------- /boot/loader.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linkypi/MyOS/c3ee437c3f41a82eab6a61119938357794617a9d/boot/loader.bin -------------------------------------------------------------------------------- /cscope.in.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linkypi/MyOS/c3ee437c3f41a82eab6a61119938357794617a9d/cscope.in.out -------------------------------------------------------------------------------- /cscope.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linkypi/MyOS/c3ee437c3f41a82eab6a61119938357794617a9d/cscope.out -------------------------------------------------------------------------------- /cscope.po.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linkypi/MyOS/c3ee437c3f41a82eab6a61119938357794617a9d/cscope.po.out -------------------------------------------------------------------------------- /debug_log: -------------------------------------------------------------------------------- 1 | 2 | boot.asm 3 | 4 | 0x7cd9 --> jmp finded 5 | 0x7d56 --> jmptoLoader 6 | 0x7d76 -->jmp far 9000:100 7 | 8 | Loader.asm 9 | 10 | 0x9021f jmp finded 11 | 0x9025b jmp jmptoKernel 12 | 0x902f2 jmp protectMode 13 | 0x903b3 jmp kernel 14 | 15 | kernel.asm 16 | 17 | 0x3040c jmp cstart 18 | 0x30418 jmp csinit 19 | -------------------------------------------------------------------------------- /global.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linkypi/MyOS/c3ee437c3f41a82eab6a61119938357794617a9d/global.o -------------------------------------------------------------------------------- /include/const.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _CONST_H_ 3 | #define _CONST_H_ 4 | 5 | #define EXTERN extern 6 | 7 | /*函数类型*/ 8 | #define PUBLIC 9 | #define PRIVATE static 10 | 11 | /* GDT AND IDT 中描述符的个数 */ 12 | #define GDT_SIZE 128 13 | #define IDT_SIZE 256 14 | 15 | /*8259A interrupt controller port.*/ 16 | #define INT_M_CTL 0x20 /* I/O port for interrupt controller */ 17 | #define INT_M_CTLMASK 0x21 /* setting bits in this port disables ints */ 18 | #define INT_S_CTL 0xA0 /* I/O port for second interrupt controller */ 19 | #define INT_S_CTLMASK 0xA1 /* setting bits in this port disables ints */ 20 | 21 | /* 权限 */ 22 | #define PRIVILEGE_KRNL 0 23 | #define PRIVILEGE_TASK 1 24 | #define PRIVILEGE_USER 3 25 | 26 | /* RPL 请求特权级 */ 27 | #define RPL_KRNL SA_RPL0 28 | #define RPL_TASK SA_RPL1 29 | #define RPL_USER SA_RPL3 30 | 31 | 32 | 33 | /* Boolean */ 34 | #define TRUE 1 35 | #define FALSE 0 36 | 37 | 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /include/global.h: -------------------------------------------------------------------------------- 1 | 2 | //global.h 3 | 4 | #ifdef GLOBAL_VARIABLES_HERE 5 | #undef EXTERN 6 | #define EXTERN 7 | #endif 8 | 9 | 10 | 11 | EXTERN int disp_pos; 12 | EXTERN u8 gdt_ptr[6]; /* 0 ~15: Limit (2 bytes ) 13 | 16~47: Base (4 bytes ) */ 14 | EXTERN DESCRIPTOR gdt[GDT_SIZE]; 15 | EXTERN u8 idt_ptr[6]; /* 0~15:Limit 16~47:Base */ 16 | EXTERN GATE idt[IDT_SIZE]; 17 | 18 | EXTERN TSS tss; 19 | EXTERN PROCESS* p_proc_ready; 20 | extern PROCESS proc_table[]; 21 | extern char task_stack[]; 22 | -------------------------------------------------------------------------------- /include/process.h: -------------------------------------------------------------------------------- 1 | /*========================================= 2 | Process.h 3 | ===========================================*/ 4 | 5 | typedef struct s_stackframe { 6 | u32 gs; /* \ */ 7 | u32 fs; /* | */ 8 | u32 es; /* | */ 9 | u32 ds; /* | */ 10 | u32 edi; /* | */ 11 | u32 esi; /* | pushed by save() */ 12 | u32 ebp; /* | */ 13 | u32 kernel_esp; /* <- 'popad' will ignore it */ 14 | u32 ebx; /* | */ 15 | u32 edx; /* | */ 16 | u32 ecx; /* | */ 17 | u32 eax; /* / */ 18 | u32 retaddr; /* return addr for kernel.asm::save() */ 19 | u32 eip; /* \ */ 20 | u32 cs; /* | */ 21 | u32 eflags; /* | pushed by CPU during interrupt */ 22 | u32 esp; /* | */ 23 | u32 ss; /* / */ 24 | }STACK_FRAME; 25 | 26 | 27 | typedef struct s_proc { 28 | STACK_FRAME regs; /* process registers saved in stack frame */ 29 | u16 ldt_sel; /* gdt selector giving ldt base and limit */ 30 | DESCRIPTOR ldts[LDT_SIZE]; /* local descriptors for code and data */ 31 | u32 pid; /* process id passed in from MM */ 32 | char p_name[16]; /* name of the process */ 33 | }PROCESS; 34 | 35 | /* Max number of tasks */ 36 | #define MAX_TASKS 1 37 | 38 | /* stacks of tasks */ 39 | #define STACK_SIZE_TESTA 0x8000 40 | 41 | #define STACK_SIZE_TOTAL STACK_SIZE_TESTA 42 | -------------------------------------------------------------------------------- /include/protect.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _PROTECT_H_ 3 | #define _PROTECT_H_ 4 | 5 | 6 | /* GDT */ 7 | /* 描述符索引 */ 8 | #define INDEX_DUMMY 0 // ┓ 9 | #define INDEX_FLAT_C 1 // ┣ LOADER 里面已经确定了的. 10 | #define INDEX_FLAT_RW 2 // ┃ 11 | #define INDEX_VIDEO 3 // ┛ 12 | #define INDEX_TSS 4 13 | #define INDEX_LDT_FIRST 5 14 | 15 | 16 | /* 选择子 */ 17 | #define SELECTOR_DUMMY 0 // ┓ 18 | #define SELECTOR_FLAT_C 0x08 // ┣ LOADER 里面已经确定了的. 19 | #define SELECTOR_FLAT_RW 0x10 // ┃ 20 | #define SELECTOR_VIDEO (0x18+3) // ┛<-- RPL=3 21 | #define SELECTOR_TSS 0x20 22 | #define SELECTOR_LDT_FIRST 0x28 23 | 24 | #define SELECTOR_KERNEL_CS SELECTOR_FLAT_C 25 | #define SELECTOR_KERNEL_DS SELECTOR_FLAT_RW 26 | #define SELECTOR_KERNEL_GS SELECTOR_VIDEO 27 | 28 | /* 每个任务有一个单独的LDT,每个LDT中的描述符个数*/ 29 | #define LDT_SIZE 2 30 | 31 | 32 | /* 选择子类型值说明 */ 33 | /* SA_: Selector Attribute */ 34 | #define SA_RPL_MASK 0xFFFC // C -> 1100 与选择子与操作后即可屏蔽掉RPL 35 | #define SA_RPL0 0 36 | #define SA_RPL1 1 37 | #define SA_RPL2 2 38 | #define SA_RPL3 3 39 | 40 | /* 41 | |<----------- selector -------------->| 42 | |15 ... 3| 2 | 1 0 | 43 | |<--- 描述符索引 ---->| TI | RPL | 44 | */ 45 | #define SA_TI_MASK 0xFFFB // B -> 1011 和选择子进行与操作后即可屏蔽TI 46 | #define SA_TIG 0 /* TI=0 描述符找GDT */ 47 | #define SA_TIL 4 /* TO=1 描述符找LDT */ 48 | 49 | /* 描述符类型值说明 */ 50 | #define DA_32 0x4000 /* 32 位段 */ 51 | #define DA_LIMIT_4K 0x8000 /* 段界限粒度为 4K 字节 */ 52 | #define DA_DPL0 0x00 /* DPL = 0 */ 53 | #define DA_DPL1 0x20 /* DPL = 1 */ 54 | #define DA_DPL2 0x40 /* DPL = 2 */ 55 | #define DA_DPL3 0x60 /* DPL = 3 */ 56 | /* 存储段描述符类型值说明 */ 57 | #define DA_DR 0x90 /* 存在的只读数据段类型值 */ 58 | #define DA_DRW 0x92 /* 存在的可读写数据段属性值 */ 59 | #define DA_DRWA 0x93 /* 存在的已访问可读写数据段类型值 */ 60 | #define DA_C 0x98 /* 存在的只执行代码段属性值 */ 61 | #define DA_CR 0x9A /* 存在的可执行可读代码段属性值 */ 62 | #define DA_CCO 0x9C /* 存在的只执行一致代码段属性值 */ 63 | #define DA_CCOR 0x9E /* 存在的可执行可读一致代码段属性值 */ 64 | /* 系统段描述符类型值说明 */ 65 | #define DA_LDT 0x82 /* 局部描述符表段类型值 */ 66 | #define DA_TaskGate 0x85 /* 任务门类型值 */ 67 | #define DA_386TSS 0x89 /* 可用 386 任务状态段类型值 */ 68 | #define DA_386CGate 0x8C /* 386 调用门类型值 */ 69 | #define DA_386IGate 0x8E /* 386 中断门类型值 */ 70 | #define DA_386TGate 0x8F /* 386 陷阱门类型值 */ 71 | 72 | 73 | 74 | /* 中断向量 */ 75 | #define INT_VECTOR_DIVIDE 0x0 76 | #define INT_VECTOR_DEBUG 0x1 77 | #define INT_VECTOR_NMI 0x2 78 | #define INT_VECTOR_BREAKPOINT 0x3 79 | #define INT_VECTOR_OVERFLOW 0x4 80 | #define INT_VECTOR_BOUNDS 0x5 81 | #define INT_VECTOR_INVAL_OP 0x6 82 | #define INT_VECTOR_COPROC_NOT 0x7 83 | #define INT_VECTOR_DOUBLE_FAULT 0x8 84 | #define INT_VECTOR_COPROC_SEG 0x9 85 | #define INT_VECTOR_INVAL_TSS 0xA 86 | #define INT_VECTOR_SEG_NOT 0xB 87 | #define INT_VECTOR_STACK_FAULT 0xC 88 | #define INT_VECTOR_PROTECTION 0xD 89 | #define INT_VECTOR_PAGE_FAULT 0xE 90 | #define INT_VECTOR_COPROC_ERR 0x10 91 | 92 | #define INT_VECTOR_IRQ0 0x20 93 | #define INT_VECTOR_IRQ8 0x28 94 | 95 | 96 | /* 线性地址转为物理地址 */ 97 | #define vir2phys(seg_base,vir)(u32)(((u32)seg_base) + (u32)(vir)) 98 | 99 | 100 | 101 | /*存储段描述符/系统段描述符 */ 102 | 103 | typedef struct s_descriptor /* 8字节 */ 104 | { 105 | u16 limit_low; 106 | u16 base_low; 107 | u8 base_mid; 108 | u8 attr1; /*P(1) DPL(2) DT(1) TYPE(4)*/ 109 | u8 limit_high_attr2; 110 | u8 base_high; 111 | }DESCRIPTOR; 112 | 113 | 114 | /* 门描述符 */ 115 | typedef struct s_gate 116 | { 117 | u16 offset_low; 118 | u16 selector; 119 | u8 dcount; /* 该字段只在调用门描述符中有效。如果在利用调用门 120 | 调用子程序时引起特权级的转换和堆栈的改变,需要将 121 | 外层堆栈中的参数复制到内层堆栈。该双字计数字段就 122 | 是用于说明这种情况发生时,要复制的双字参数的数量*/ 123 | u8 attr; 124 | u16 offset_hight; 125 | }GATE; 126 | 127 | 128 | typedef struct s_tss{ 129 | u32 backlink; 130 | u32 esp0; /* stack pointer to use during interrupt */ 131 | u32 ss0; /* " segment " " " " */ 132 | u32 esp1; 133 | u32 ss1; 134 | u32 esp2; 135 | u32 ss2; 136 | u32 cr3; 137 | u32 eip; 138 | u32 flags; 139 | u32 eax; 140 | u32 ecx; 141 | u32 edx; 142 | u32 ebx; 143 | u32 esp; 144 | u32 ebp; 145 | u32 esi; 146 | u32 edi; 147 | u32 es; 148 | u32 cs; 149 | u32 ss; 150 | u32 ds; 151 | u32 fs; 152 | u32 gs; 153 | u32 ldt; 154 | u16 trap; 155 | u16 iobase; /* I/O位图基址大于或等于TSS段界限,就表示没有I/O许可位图 */ 156 | }TSS; 157 | 158 | 159 | 160 | #endif 161 | -------------------------------------------------------------------------------- /include/proto.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | /*===================================================== 4 | proto.h 5 | =====================================================*/ 6 | 7 | 8 | PUBLIC void out_byte(u16 port,u8 value); 9 | PUBLIC u8 in_byte(u16 port); 10 | PUBLIC void disp_str(char* info); 11 | PUBLIC void disp_color_str(char* info,int color); 12 | PUBLIC void init_prot(); 13 | PUBLIC void init_8259A(); 14 | -------------------------------------------------------------------------------- /include/sconst.inc: -------------------------------------------------------------------------------- 1 | 2 | ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 | ; sconst.inc 4 | ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 | 6 | P_STACKBASE equ 0 7 | GSREG equ P_STACKBASE 8 | FSREG equ GSREG + 4 9 | ESREG equ FSREG + 4 10 | DSREG equ ESREG + 4 11 | EDIREG equ DSREG + 4 12 | ESIREG equ EDIREG + 4 13 | EBPREG equ ESIREG + 4 14 | KERNELESPREG equ EBPREG + 4 15 | EBXREG equ KERNELESPREG + 4 16 | EDXREG equ EBXREG + 4 17 | ECXREG equ EDXREG + 4 18 | EAXREG equ ECXREG + 4 19 | RETADR equ EAXREG + 4 20 | EIPREG equ RETADR + 4 21 | CSREG equ EIPREG + 4 22 | EFLAGSREG equ CSREG + 4 23 | ESPREG equ EFLAGSREG + 4 24 | SSREG equ ESPREG + 4 25 | P_STACKTOP equ SSREG + 4 26 | P_LDT_SEL equ P_STACKTOP 27 | P_LDT equ P_LDT_SEL + 4 28 | 29 | TSS3_S_SP0 equ 4 30 | 31 | ; 以下选择子值必须与 protect.h 中保持一致!!! 32 | SELECTOR_FLAT_C equ 0x08 ; LOADER 里面已经确定了的. 33 | SELECTOR_TSS equ 0x20 ; TSS 34 | SELECTOR_KERNEL_CS equ SELECTOR_FLAT_C 35 | 36 | -------------------------------------------------------------------------------- /include/string.h: -------------------------------------------------------------------------------- 1 | 2 | PUBLIC void* memcpy(void* p_dst, void* p_src, int size); 3 | -------------------------------------------------------------------------------- /include/type.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _TYPE_H_ 3 | #define _TYPE_H_ 4 | 5 | typedef unsigned int u32; 6 | typedef unsigned short u16; 7 | typedef unsigned char u8; 8 | 9 | typedef void (*int_handler) (); /*函数指针*/ 10 | 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /kernel/global.c: -------------------------------------------------------------------------------- 1 | 2 | //=================== global.c =============== 3 | #define GLOBAL_VARIABLES_HERE 4 | 5 | #include "type.h" 6 | #include "const.h" 7 | #include "protect.h" 8 | #include "proto.h" 9 | #include "process.h" 10 | #include "global.h" 11 | 12 | PUBLIC char task_stack[STACK_SIZE_TOTAL]; 13 | 14 | PUBLIC PROCESS proc_table[MAX_TASKS]; 15 | -------------------------------------------------------------------------------- /kernel/i8259.c: -------------------------------------------------------------------------------- 1 | /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 2 | /* i8259.c */ 3 | /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 4 | 5 | #include "type.h" 6 | #include "const.h" 7 | #include "protect.h" 8 | #include "proto.h" 9 | 10 | PUBLIC void init_8259A() 11 | { 12 | /* Master 8259, ICW1 */ 13 | out_byte(INT_M_CTL,0x11); 14 | 15 | /* Slaves 8259, ICW1 .*/ 16 | out_byte(INT_S_CTL,0x11); 17 | 18 | /* Master 8259, ICW2 *设置主8259的中断入口地址为0x20**/ 19 | out_byte(INT_M_CTLMASK,INT_VECTOR_IRQ0); 20 | 21 | /* Slave 8259 ICW2 设置从8259的中断入口地址为0x28*/ 22 | out_byte(INT_S_CTLMASK,INT_VECTOR_IRQ8); 23 | 24 | /* Master 8259 ICW3 IR2对应从8259 */ 25 | out_byte(INT_M_CTLMASK,0x4); 26 | 27 | /* Slave 8259 ICW3 对应主8259的 IR2 */ 28 | out_byte(INT_S_CTLMASK,0x2); 29 | 30 | /*Master 8259 ICW4 */ 31 | out_byte(INT_M_CTLMASK,0x1); 32 | 33 | /*Slave 8269 ICW4 */ 34 | out_byte(INT_S_CTLMASK,0x1); 35 | 36 | /* Master 8259 OCW1*/ 37 | out_byte(INT_M_CTLMASK,0xFD); //仅打开键盘中断 38 | 39 | /*Slave 8259 OCW1 */ 40 | out_byte(INT_S_CTLMASK,0xFF); 41 | 42 | } 43 | 44 | PUBLIC void intrpt_handler(int irq) 45 | { 46 | disp_str("Interrupt Request, Num: "); 47 | disp_int(irq); 48 | disp_str("\n"); 49 | } 50 | -------------------------------------------------------------------------------- /kernel/kernel.asm: -------------------------------------------------------------------------------- 1 | 2 | ;========================================================= 3 | ;kernel.asm 4 | ;========================================================= 5 | 6 | %include "sconst.inc" 7 | 8 | 9 | ;导入函数 10 | extern cstart 11 | extern kernel_main 12 | extern exception_handler 13 | extern intrpt_handler 14 | 15 | ;导入全局变量 16 | extern gdt_ptr 17 | extern idt_ptr 18 | extern disp_pos 19 | extern tss 20 | extern p_proc_ready 21 | 22 | [section .bss] 23 | StackSpace resb 2 * 1024 ;resb用于声明未初始化的存储空间 resw resd resq 24 | StackTop: ;栈顶 堆栈内容向低地址扩展 25 | 26 | [section .text] 27 | 28 | 29 | global _start 30 | 31 | global restart 32 | 33 | ;导出异常函数 34 | global divide_error 35 | global single_step_exception 36 | global nmi 37 | global breakpoint_exception 38 | global overflow 39 | global bounds_check 40 | global inval_opcode 41 | global copr_not_available 42 | global double_fault 43 | global copr_seg_overrun 44 | global inval_tss 45 | global segment_not_present 46 | global stack_exception 47 | global general_protection 48 | global page_fault 49 | global copr_error 50 | 51 | 52 | ;导出中断函数 Hard Interrupt 53 | global hint00 54 | global hint01 55 | global hint02 56 | global hint03 57 | global hint04 58 | global hint05 59 | global hint06 60 | global hint07 61 | global hint08 62 | global hint09 63 | global hint10 64 | global hint11 65 | global hint12 66 | global hint13 67 | global hint14 68 | global hint15 69 | 70 | 71 | 72 | _start: 73 | 74 | ;把esp从loader挪到kernel 75 | mov esp,StackTop 76 | 77 | mov dword [disp_pos],0 78 | 79 | sgdt [gdt_ptr] ;sgdt 用于获取GDT的虚拟地址 80 | call cstart ;在此函数中改变gdt_ptr,让他指向新的GDT 81 | lgdt [gdt_ptr] ;使用新的GDT 82 | 83 | lidt [idt_ptr] 84 | 85 | jmp SELECTOR_KERNEL_CS:csinit 86 | csinit: 87 | 88 | ;ud2 89 | ;jmp 0x40:0 90 | 91 | ;sti ;设置IF位 92 | ;hlt 93 | 94 | xor eax,eax 95 | mov ax , SELECTOR_TSS 96 | ltr ax 97 | 98 | jmp kernel_main 99 | 100 | 101 | ;================================================= 102 | ; 切换进程 103 | ;================================================= 104 | restart: 105 | mov esp, [p_proc_ready] 106 | lldt [esp+P_LDT_SEL] 107 | lea eax,[esp+P_STACKTOP] 108 | mov dword [tss+TSS3_S_SP0],eax 109 | 110 | pop gs 111 | pop fs 112 | pop es 113 | pop ds 114 | popad 115 | add esp , 4 116 | iretd 117 | 118 | ;中断处理 119 | %macro int_master 1 120 | push %1 121 | call intrpt_handler 122 | add esp,4 123 | hlt 124 | %endmacro 125 | 126 | ALIGN 16 127 | hint00: ; irq 0 --> the clock 128 | iret 129 | ;int_master 0 130 | 131 | ALIGN 16 132 | hint01: ; irq 1 --> keyboard 133 | int_master 1 134 | 135 | ALIGN 16 136 | hint02: ; irq 2 --> cascade 137 | int_master 2 138 | 139 | ALIGN 16 140 | hint03: ; irq 3 --> second serial 141 | int_master 3 142 | 143 | ALIGN 16 144 | hint04: ; irq 4 --> first serial 145 | int_master 4 146 | 147 | ALIGN 16 148 | hint05: ; irq 5 --> XT winchester 149 | int_master 5 150 | 151 | ALIGN 16 152 | hint06: ; irq 6 --> floppy 153 | int_master 6 154 | 155 | ALIGN 16 156 | hint07: ; irq 7 --> printer 157 | int_master 7 158 | 159 | ;-------------------------------- 160 | %macro int_slave 1 161 | push %1 162 | call intrpt_handler 163 | add esp , 4 164 | hlt 165 | %endmacro 166 | ;-------------------------------- 167 | 168 | ALIGN 16 169 | hint08: ; irq 8 --> realtime clock 170 | int_slave 8 171 | 172 | ALIGN 16 173 | hint09: ; irq 9 --> irq 2 redirected 174 | int_slave 9 175 | 176 | ALIGN 16 177 | hint10: ; irq 10 178 | int_slave 10 179 | 180 | ALIGN 16 181 | hint11: ; irq 11 182 | int_slave 11 183 | 184 | ALIGN 16 185 | hint12: ; irq 12 186 | int_slave 12 187 | 188 | ALIGN 16 189 | hint13: ; irq 13 --> FPU Exception 190 | int_slave 13 191 | 192 | ALIGN 16 193 | hint14: ; irq 14 --> AT winchester 194 | int_slave 14 195 | 196 | ALIGN 16 197 | hint15: ; irq 15 198 | int_slave 15 199 | 200 | 201 | ;异常处理 202 | divide_error: 203 | push 0xFFFFFFFF ;no error code 204 | push 0 ;vector_no=0 205 | jmp exception 206 | 207 | single_step_exception: 208 | push 0xFFFFFFFF ;no error code 209 | push 1 ;vector_no=1 210 | jmp exception 211 | 212 | nmi: 213 | push 0xFFFFFFFF 214 | push 2 ;vector_no=2 215 | jmp exception 216 | 217 | breakpoint_exception: 218 | push 0xFFFFFFFF 219 | push 3 220 | jmp exception 221 | 222 | overflow: 223 | push 0xFFFFFFFF 224 | push 4 225 | jmp exception 226 | 227 | bounds_check: 228 | push 0xFFFFFFFF 229 | push 5 230 | jmp exception 231 | 232 | inval_opcode: 233 | push 0xFFFFFFFF 234 | push 6 235 | jmp exception 236 | 237 | copr_not_available: 238 | push 0xFFFFFFFF 239 | push 7 240 | jmp exception 241 | 242 | double_fault: 243 | push 8 244 | jmp exception 245 | 246 | copr_seg_overrun: 247 | push 0xFFFFFFFF 248 | push 9 249 | jmp exception 250 | 251 | inval_tss: 252 | push 10 ;vector_no = A 253 | jmp exception 254 | 255 | segment_not_present: 256 | push 11 257 | jmp exception 258 | 259 | stack_exception: 260 | push 12 261 | jmp exception 262 | 263 | general_protection: 264 | push 13 265 | jmp exception 266 | 267 | page_fault: 268 | push 14 269 | jmp exception 270 | 271 | copr_error: 272 | push 0xFFFFFFFF 273 | push 16 274 | jmp exception 275 | 276 | exception: 277 | call exception_handler 278 | add esp,4*2 ;让栈顶指向EIP,中断发生是参数入栈顺序 279 | ;为 eflags , cs , eip 280 | hlt 281 | -------------------------------------------------------------------------------- /kernel/kernel.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linkypi/MyOS/c3ee437c3f41a82eab6a61119938357794617a9d/kernel/kernel.o -------------------------------------------------------------------------------- /kernel/main.c: -------------------------------------------------------------------------------- 1 | 2 | /*================================================= 3 | main.c 4 | =================================================*/ 5 | 6 | #include "type.h" 7 | #include "const.h" 8 | #include "protect.h" 9 | #include "proto.h" 10 | #include "string.h" 11 | #include "process.h" 12 | #include "global.h" 13 | 14 | 15 | 16 | /*================================================= 17 | kernel_main 18 | ==================================================*/ 19 | 20 | PUBLIC int kernel_main() 21 | { 22 | disp_str("--------\"kernel_main\"---------"); 23 | 24 | PROCESS* p_proc = proc_table; 25 | 26 | p_proc->ldt_sel = SELECTOR_LDT_FIRST; 27 | /*为简化起见,ldt有两个描述符,分别被初始化 28 | 为内核代码段和内核数据段 */ 29 | memcpy(&p_proc->ldts[0],&gdt[SELECTOR_KERNEL_CS>>3],sizeof(DESCRIPTOR)); 30 | p_proc->ldt[0].attr1 = DA_C | PRIVILEGE << 5;//改变描述符特权级 31 | 32 | memcpy(&p_proc->ldts[1],&gdt[SELECTOR_KERNEL_DS>>3],sizeof(DESCRIPTOR)); 33 | p_proc->ldt[1].attr1 = DA_DRW | PRIVILEGE << 5;//改变描述符特权级 34 | 35 | /*先将RPL,TI屏蔽 之后将个寄存器(即选择子)设置TI=1(LDT),RPL=1 */ 36 | p_proc->regs.cs = (0 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK; 37 | p_proc->regs.ds = (8 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK; 38 | p_proc->regs.es = (8 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK; 39 | p_proc->regs.fs = (8 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK; 40 | p_proc->regs.ss = (8 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK; 41 | p_proc->regs.gs = (SELECTOR_KERNEL_GS & SA_RPL_MASK) | RPL_TASK; 42 | p_proc->regs.eip = (u32)TestA; 43 | p_proc->regs.esp = (u32)task_stack + STACK_SIZE_TOTAL; 44 | p_proc->regs.eflags = 0x1202; // IF=1 IOPL=1 bit 2 is always 1. 45 | 46 | p_proc_ready = proc_table; 47 | restart(); 48 | 49 | while(1){} 50 | } 51 | 52 | void TestA() 53 | { 54 | int i=0; 55 | while(1){ 56 | disp_str("A"); 57 | disp_int(i++); 58 | disp_str("."); 59 | delay(1); 60 | } 61 | } 62 | 63 | -------------------------------------------------------------------------------- /kernel/protect.c: -------------------------------------------------------------------------------- 1 | /* protect.c */ 2 | 3 | #include "type.h" 4 | #include "const.h" 5 | #include "protect.h" 6 | #include "global.h" 7 | #include "proto.h" 8 | #include "process.h" 9 | /*文件内函数声明*/ 10 | PRIVATE void init_idt_desc(unsigned char vector , u8 desc_type, 11 | int_handler handler,unsigned char privilege); 12 | 13 | PRIVATE void init_descriptor(DESCRIPTOR *p_desc,u32 base,u32 limit,u16 attr); 14 | 15 | 16 | 17 | /*异常处理函数 定义在kernel.asm中 */ 18 | void divide_error(); 19 | void single_step_exception(); 20 | void nmi(); 21 | void breakpoint_exception(); 22 | void overflow(); 23 | void bounds_check(); 24 | void inval_opcode(); 25 | void copr_not_available(); 26 | void double_fault(); 27 | void copr_seg_overrun(); 28 | void inval_tss(); 29 | void segment_not_present(); 30 | void stack_exception(); 31 | void general_protection(); 32 | void page_fault(); 33 | void copr_error(); 34 | 35 | /*中断处理函数 定义在kernel.asm中 */ 36 | void hint00(); 37 | void hint01(); 38 | void hint02(); 39 | void hint03(); 40 | void hint04(); 41 | void hint05(); 42 | void hint06(); 43 | void hint07(); 44 | void hint08(); 45 | void hint09(); 46 | void hint10(); 47 | void hint11(); 48 | void hint12(); 49 | void hint13(); 50 | void hint14(); 51 | void hint15(); 52 | /*======================================================= 53 | init_prot() 54 | ========================================================*/ 55 | PUBLIC void init_prot() 56 | { 57 | init_8259A(); 58 | 59 | //初始化异常 (中断门 没有陷阱门) 60 | init_idt_desc( INT_VECTOR_DIVIDE, DA_386IGate, divide_error, PRIVILEGE_KRNL); 61 | init_idt_desc( INT_VECTOR_DEBUG, DA_386IGate, single_step_exception, PRIVILEGE_KRNL); 62 | init_idt_desc( INT_VECTOR_NMI, DA_386IGate, nmi, PRIVILEGE_KRNL); 63 | init_idt_desc( INT_VECTOR_BREAKPOINT, DA_386IGate, breakpoint_exception, PRIVILEGE_USER); 64 | init_idt_desc( INT_VECTOR_OVERFLOW, DA_386IGate , overflow, PRIVILEGE_USER); 65 | init_idt_desc( INT_VECTOR_BOUNDS, DA_386IGate, bounds_check, PRIVILEGE_KRNL); 66 | init_idt_desc( INT_VECTOR_INVAL_OP, DA_386IGate, inval_opcode, PRIVILEGE_KRNL); 67 | init_idt_desc( INT_VECTOR_COPROC_NOT, DA_386IGate, copr_not_available, PRIVILEGE_KRNL); 68 | init_idt_desc( INT_VECTOR_DOUBLE_FAULT, DA_386IGate, double_fault, PRIVILEGE_KRNL); 69 | init_idt_desc( INT_VECTOR_COPROC_SEG, DA_386IGate, copr_seg_overrun, PRIVILEGE_KRNL); 70 | init_idt_desc( INT_VECTOR_INVAL_TSS, DA_386IGate, inval_tss, PRIVILEGE_KRNL); 71 | init_idt_desc( INT_VECTOR_SEG_NOT, DA_386IGate, segment_not_present, PRIVILEGE_KRNL); 72 | init_idt_desc( INT_VECTOR_STACK_FAULT, DA_386IGate, stack_exception, PRIVILEGE_KRNL); 73 | init_idt_desc( INT_VECTOR_PROTECTION, DA_386IGate, general_protection, PRIVILEGE_KRNL); 74 | init_idt_desc( INT_VECTOR_PAGE_FAULT, DA_386IGate, page_fault, PRIVILEGE_KRNL); 75 | init_idt_desc( INT_VECTOR_COPROC_ERR, DA_386IGate, copr_error, PRIVILEGE_KRNL); 76 | 77 | /*初始化中断*/ 78 | init_idt_desc(INT_VECTOR_IRQ0 + 0, DA_386IGate , hint00 , PRIVILEGE_KRNL); 79 | init_idt_desc(INT_VECTOR_IRQ0 + 1, DA_386IGate , hint01 , PRIVILEGE_KRNL); 80 | init_idt_desc(INT_VECTOR_IRQ0 + 2, DA_386IGate , hint02 , PRIVILEGE_KRNL); 81 | init_idt_desc(INT_VECTOR_IRQ0 + 3, DA_386IGate , hint03 , PRIVILEGE_KRNL); 82 | init_idt_desc(INT_VECTOR_IRQ0 + 4, DA_386IGate , hint04 , PRIVILEGE_KRNL); 83 | init_idt_desc(INT_VECTOR_IRQ0 + 5, DA_386IGate , hint05 , PRIVILEGE_KRNL); 84 | init_idt_desc(INT_VECTOR_IRQ0 + 6, DA_386IGate , hint06 , PRIVILEGE_KRNL); 85 | init_idt_desc(INT_VECTOR_IRQ0 + 7, DA_386IGate , hint07 , PRIVILEGE_KRNL); 86 | init_idt_desc(INT_VECTOR_IRQ8 + 0, DA_386IGate , hint08 , PRIVILEGE_KRNL); 87 | init_idt_desc(INT_VECTOR_IRQ8 + 1, DA_386IGate , hint09 , PRIVILEGE_KRNL); 88 | init_idt_desc(INT_VECTOR_IRQ8 + 2, DA_386IGate , hint10 , PRIVILEGE_KRNL); 89 | init_idt_desc(INT_VECTOR_IRQ8 + 3, DA_386IGate , hint11 , PRIVILEGE_KRNL); 90 | init_idt_desc(INT_VECTOR_IRQ8 + 4, DA_386IGate , hint12 , PRIVILEGE_KRNL); 91 | init_idt_desc(INT_VECTOR_IRQ8 + 5, DA_386IGate , hint13 , PRIVILEGE_KRNL); 92 | init_idt_desc(INT_VECTOR_IRQ8 + 6, DA_386IGate , hint14 , PRIVILEGE_KRNL); 93 | init_idt_desc(INT_VECTOR_IRQ8 + 7, DA_386IGate , hint15 , PRIVILEGE_KRNL); 94 | 95 | 96 | /* 填充 GDT 中的 TSS */ 97 | memset(&tss,0,sizeof(tss)); 98 | tss.ss0 = SELECTOR_KERNEL_DS; 99 | init_descriptor(&gdt[INDEX_TSS], 100 | vir2phys(seg2phys(SELECTOR_KERNEL_DS),&tss), 101 | sizeof(tss) - 1, DA_386TSS); 102 | 103 | tss.iobase = sizeof(tss); /*没有I/O许可位图*/ 104 | 105 | /*填充 GDT 中进程的 LDT的描述符 */ 106 | init_descriptor(&gdt[INDEX_LDT_FIRST], 107 | vir2phys(seg2phys(SELECTOR_KERNEL_DS),proc_table[0].ldts), 108 | LDT_SIZE * sizeof(DESCRIPTOR) - 1, DA_LDT); 109 | } 110 | 111 | 112 | /*==================================================================== 113 | init_idt_desc 初始化 386 中断门 114 | =====================================================================*/ 115 | PRIVATE void init_idt_desc(unsigned char vector,u8 desc_type, 116 | int_handler handler,unsigned char privilege) 117 | { 118 | GATE* p_gate = &idt[vector]; 119 | u32 base = (u32)handler; 120 | p_gate->offset_low = base & 0xFFFF; 121 | p_gate->selector = SELECTOR_KERNEL_CS; 122 | p_gate->dcount = 0; 123 | p_gate->attr = desc_type | (privilege << 5); 124 | p_gate->offset_hight = (base>>16) & 0xFFFF; 125 | } 126 | 127 | 128 | /*================================================================ 129 | seg2phys 由段名求绝对地址 130 | ================================================================*/ 131 | PUBLIC u32 seg2phys(u16 seg) 132 | { 133 | DESCRIPTOR* p_desc = &gdt[ seg >> 3]; 134 | return (p_desc->base_high << 24 | p_desc->base_mid << 16 | p_desc->base_low); 135 | } 136 | 137 | /*================================================================ 138 | init_descriptor 初始化段描述符 139 | ================================================================*/ 140 | PRIVATE void inito_descriptor(DESCIPRTOR* p_desc,u32 base ,u32 limit,u16 attr) 141 | { 142 | p_desc->limit_low = limit & 0x0FFFF; 143 | p_desc->base_low = base & 0x0FFFF; 144 | p_desc->base_mid = (base>>16) & 0x0FF; 145 | p_desc->attr1 = attr & 0xFF; 146 | p_desc->limit_high_attr2 = ((limit>>16)&0x0F)|(attr>>8)&0xF0; 147 | p_desc->base_high = (base>>24) & 0x0FF; 148 | } 149 | 150 | PUBLIC void exception_handler(int vec_no,int err_code,int eip,int cs,int eflags) 151 | { 152 | int i; 153 | int text_color = 0x74; /* 灰底红字 */ 154 | 155 | char * err_msg[] = { 156 | "#DE Divide Error", 157 | "#DB RESERVED", 158 | "-- NMI Interrupt", 159 | "#BP Breakpoint", 160 | "#OF Overflow", 161 | "#BR BOUND Range Exceeded", 162 | "#UD Invalid Opcode (Undefined Opcode)", 163 | "#NM Device Not Available (No Math Coprocessor)", 164 | "#DF Double Fault", 165 | " Coprocessor Segment Overrun (reserved)", 166 | "#TS Invalid TSS", 167 | "#NP Segment Not Present", 168 | "#SS Stack-Segment Fault", 169 | "#GP General Protection", 170 | "#PF Page Fault", 171 | "-- (Intel reserved. Do not use.)", 172 | "#MF x87 FPU Floating-Point Error (Math Fault)", 173 | "#AC Alignment Check", 174 | "#MC Machine Check", 175 | "#XF SIMD Floating-Point Exception" 176 | }; 177 | 178 | /* 通过打印空格的方式清空屏幕的前五行,并把 disp_pos 清零 */ 179 | disp_pos = 0; 180 | for(i=0;i<80*5;i++){ 181 | disp_str(" "); 182 | } 183 | disp_pos = 0; 184 | 185 | disp_color_str("Exception! --> ", text_color); 186 | disp_color_str(err_msg[vec_no], text_color); 187 | disp_color_str("\n\n", text_color); 188 | disp_color_str("EFLAGS:", text_color); 189 | disp_int(eflags); 190 | disp_color_str("CS:", text_color); 191 | disp_int(cs); 192 | disp_color_str("EIP:", text_color); 193 | disp_int(eip); 194 | 195 | if(err_code != 0xFFFFFFFF){ 196 | disp_color_str("Error code:", text_color); 197 | disp_int(err_code); 198 | } 199 | } 200 | 201 | -------------------------------------------------------------------------------- /kernel/start.c: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------ 2 | start.c 3 | -------------------------------------------------*/ 4 | 5 | #include "type.h" 6 | #include "const.h" 7 | #include "protect.h" 8 | #include "string.h" 9 | #include "proto.h" 10 | #include "global.h" 11 | #include "process.h" 12 | 13 | PUBLIC void cstart() 14 | { 15 | disp_str("\n\n\n\n\n\n\n\n\n\n\n\n\n\n-----\"cstart\" begins-----\n"); 16 | 17 | /*将Loader中的GDT复制到新的GDT*/ 18 | memcpy(&gdt, /* new GDT */ 19 | (void*)(*((u32*)(&gdt_ptr[2]))), /*Base of old GDT*/ 20 | *((u16*)(&gdt_ptr[0]))+1 ); /*Limit of old GDT*/ 21 | 22 | /*gdt_ptr[6]共 6 个字节:0~15:limit 16~47:Base 用作sgdt/lgdt的参数*/ 23 | u16* p_gdt_limit = (u16*)(&gdt_ptr[0]); 24 | u32* p_gdt_base = (u32*)(&gdt_ptr[2]); 25 | *p_gdt_limit = GDT_SIZE * sizeof(DESCRIPTOR) - 1; 26 | *p_gdt_base =(u32)&gdt; 27 | 28 | /* idt_ptr[6] 共6个字节:0~15:Limit 16~47:Base */ 29 | u16* p_idt_limit = (u16*)(&idt_ptr[0]); 30 | u32* p_idt_base = (u32*)(&idt_ptr[2]); 31 | *p_idt_limit = IDT_SIZE * sizeof(GATE) - 1; 32 | *p_idt_base = (u32)&idt; 33 | 34 | init_prot(); //初始化 8259A,异常,及中断 35 | 36 | disp_str("-----\"cstart\" ends-----"); 37 | } 38 | 39 | -------------------------------------------------------------------------------- /lib/klib.c: -------------------------------------------------------------------------------- 1 | /*==================================================== 2 | klib.c 3 | ====================================================*/ 4 | 5 | #include "type.h" 6 | #include "const.h" 7 | #include "protect.h" 8 | #include "proto.h" 9 | #include "string.h" 10 | #include "global.h" 11 | #include "process.h" 12 | /*================================================== 13 | itoa 将数字转为16进制数字符 数字前面的0不显示 14 | ==================================================*/ 15 | PUBLIC char* itoa(char* str,int num ) 16 | { 17 | char* p= str; 18 | char ch; 19 | int i; 20 | int flag=0; 21 | 22 | *p++='0'; 23 | *p++='x'; 24 | 25 | if(num==0) 26 | { 27 | *p++ = '0'; 28 | } 29 | else 30 | { 31 | for(i=28;i>=0;i-=4) 32 | { 33 | ch= (num>>i) & 0xF; 34 | if(flag||(ch>0)) 35 | { 36 | flag = 1; 37 | ch += '0'; 38 | if(ch > '9'){ 39 | ch += 7; 40 | } 41 | *p++ = ch; 42 | } 43 | } 44 | } 45 | *p = 0; 46 | return str; 47 | } 48 | 49 | /*==================================================== 50 | disp_int 51 | =====================================================*/ 52 | PUBLIC void disp_int(int input) 53 | { 54 | char output[16]; 55 | itoa(output,input); 56 | disp_str(output); 57 | } 58 | 59 | 60 | /*==================================================== 61 | delay 62 | =====================================================*/ 63 | PUBLIC void delay(int time) 64 | { 65 | int i,j,k; 66 | for(k=0;k 2 | 3 | u /10 4 | u /10 0x7c3b 5 | s 6 | u /20 7 | u /10 0x7c42 8 | u /5 ox7cda 9 | u /5 0x7cda 10 | u /5 0x7cca 11 | U /10 0x7d35 12 | U /10 0x7d30 13 | u /10 0x7d32 14 | u /10 0x7d35 15 | u /10 0x7cf0 16 | u /10 0x7d28 17 | u /10 0x7d50 18 | u /10 0x90120 19 | u /10 0x9012a 20 | u /10 0x90138 21 | u /10 0x90180 22 | u /10 0x90175 23 | u /10 0x90170 24 | u /10 0x90160 25 | u /10 0x90165 26 | u /10 0x7d2f 27 | u /10 0x7d65 28 | u /10 0x7d78 29 | u /0x903ae 30 | u /10 0x903ae 31 | u /10 0x904a0 32 | 33 | 34 | en_US 35 | false 36 | 324 37 | 161 38 | Dialog 39 | 12 40 | 41 | 654 42 | false 43 | 44 | false 45 | false 46 | /home/lxq/Desktop/orange/chapter4/c/find/. 47 | /home/lxq/Desktop/orange/chapter4/c/find/. 48 | /home/lxq/Desktop/orange/chapter4/c/find/. 49 | 50 | false 51 | false 52 | false 53 | 54 | 0x0x7df6 55 | 0x7c00 56 | 0x7d1e 57 | 0x7dbf 58 | 0x7df2 59 | 0x7df3 60 | 0x7df4 61 | 0x7df5 62 | 0x7df6 63 | 0x7dfa 64 | 0x800 65 | 0x8000 66 | 0x80000 67 | 0x8f000 68 | 0x900 69 | 0x90000 70 | 0x90100 71 | 0x901a0 72 | 0x901c0 73 | 0x90200 74 | 0x90280 75 | 0x902b8 76 | 0x902bd 77 | 0x902c2 78 | 0x902e7 79 | 0x902e8 80 | 0x902ed 81 | 0x90300 82 | 0x90500 83 | 0x9100 84 | 0x9120 85 | 0x9200 86 | 0x9300 87 | 0x97de7 88 | 0x97de8 89 | 90 | 91 | false 92 | 93 | 150 94 | 95 | 96 | 97 | 98 | 99 | false 100 | 101 | 102 | 103 | 104 | false 105 | false 106 | false 107 | false 108 | false 109 | false 110 | false 111 | false 112 | false 113 | false 114 | false 115 | false 116 | false 117 | false 118 | false 119 | false 120 | true 121 | false 122 | true 123 | true 124 | 872 125 | 653 126 | 87 127 | 128 | -------------------------------------------------------------------------------- /run: -------------------------------------------------------------------------------- 1 | java -jar peter-bochs-debugger.jar bochs -q -f bochsrc.bxrc 2 | -------------------------------------------------------------------------------- /tags: -------------------------------------------------------------------------------- 1 | !_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ 2 | !_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ 3 | !_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/ 4 | !_TAG_PROGRAM_NAME Exuberant Ctags // 5 | !_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ 6 | !_TAG_PROGRAM_VERSION 5.9~svn20110310 // 7 | ARDStruct boot/loader.asm /^ ARDStruct equ BaseOfLoaderPhyAddr + _ARDStruct$/;" d 8 | ASM Makefile /^ASM = nasm$/;" m 9 | ASMBFLAGS Makefile /^ASMBFLAGS = -I boot\/include\/$/;" m 10 | ASMKFLAGS Makefile /^ASMKFLAGS = -I include\/ -f elf$/;" m 11 | BaseOfLoader boot/boot.asm /^BaseOfLoader equ 09000h$/;" d 12 | BaseOfStack boot/boot.asm /^BaseOfStack equ 07c00h ; 堆栈基地址(栈底, 从这个位置向低地址生长)$/;" d 13 | BaseOfStack boot/loader.asm /^BaseOfStack equ 0100h ; 堆栈基地址(栈底, 从这个位置向低地址生长)$/;" d 14 | CC Makefile /^CC = gcc$/;" m 15 | CFLAGS Makefile /^CFLAGS = -I include\/ -c -fno-builtin -fno-stack-protector$/;" m 16 | DASM Makefile /^DASM = ndisasm$/;" m 17 | DASMFLAGS Makefile /^DASMFLAGS = -u -o $(ENTRYPOINT) -e $(ENTRYOFFSET)$/;" m 18 | DASMOUTPUT Makefile /^DASMOUTPUT = kernel.bin.asm$/;" m 19 | DA_32 include/protect.h 50;" d 20 | DA_386CGate include/protect.h 68;" d 21 | DA_386IGate include/protect.h 69;" d 22 | DA_386TGate include/protect.h 70;" d 23 | DA_386TSS include/protect.h 67;" d 24 | DA_C include/protect.h 60;" d 25 | DA_CCO include/protect.h 62;" d 26 | DA_CCOR include/protect.h 63;" d 27 | DA_CR include/protect.h 61;" d 28 | DA_DPL0 include/protect.h 52;" d 29 | DA_DPL1 include/protect.h 53;" d 30 | DA_DPL2 include/protect.h 54;" d 31 | DA_DPL3 include/protect.h 55;" d 32 | DA_DR include/protect.h 57;" d 33 | DA_DRW include/protect.h 58;" d 34 | DA_DRWA include/protect.h 59;" d 35 | DA_LDT include/protect.h 65;" d 36 | DA_LIMIT_4K include/protect.h 51;" d 37 | DA_TaskGate include/protect.h 66;" d 38 | DESCRIPTOR include/protect.h /^}DESCRIPTOR;$/;" t typeref:struct:s_descriptor 39 | Desc_Flag_c boot/loader.asm /^Desc_Flag_c: Descriptor 0, 0fffffh, DA_CR|DA_32|DA_LIMIT_4K ; 0-4G$/;" l 40 | Desc_Flag_rw boot/loader.asm /^Desc_Flag_rw: Descriptor 0, 0fffffh, DA_DRW|DA_32|DA_LIMIT_4K ; 0-4G$/;" l 41 | Desc_Video boot/loader.asm /^Desc_Video: Descriptor 0B8000h, 0ffffh , DA_DRW|DA_DPL3 ;显存首地址$/;" l 42 | DispAL boot/loader.asm /^DispAL:$/;" l 43 | DispInt boot/loader.asm /^DispInt:$/;" l 44 | DispMemInfo boot/loader.asm /^ DispMemInfo:$/;" l 45 | DispPMStr boot/loader.asm /^DispPMStr:$/;" l 46 | DispReturn boot/loader.asm /^DispReturn:$/;" l 47 | ENTRYOFFSET Makefile /^ENTRYOFFSET = 0x400$/;" m 48 | ENTRYPOINT Makefile /^ENTRYPOINT = 0x30400$/;" m 49 | EXTERN include/const.h 5;" d 50 | EXTERN include/global.h 5;" d 51 | EXTERN include/global.h 6;" d 52 | FALSE include/const.h 35;" d 53 | GATE include/protect.h /^}GATE;$/;" t typeref:struct:s_gate 54 | GDT boot/loader.asm /^GDT: Descriptor 0, 0, 0 ;空描述符$/;" l 55 | GDT_SIZE include/const.h 12;" d 56 | GLOBAL_VARIABLES_HERE kernel/global.c 3;" d file: 57 | GdtLen boot/loader.asm /^GdtLen equ $ - GDT $/;" d 58 | GdtPtr boot/loader.asm /^GdtPtr dw GdtLen - 1 ;段界限$/;" d 59 | Get boot/boot.asm /^Get:$/;" l 60 | Get boot/loader.asm /^Get:$/;" l 61 | GetFat boot/boot.asm /^GetFat:$/;" l 62 | GetFat boot/loader.asm /^GetFat:$/;" l 63 | Goon_Loading boot/boot.asm /^Goon_Loading:$/;" l 64 | Goon_Loading boot/loader.asm /^Goon_Loading:$/;" l 65 | IDT_SIZE include/const.h 13;" d 66 | INDEX_DUMMY include/protect.h 8;" d 67 | INDEX_FLAT_C include/protect.h 9;" d 68 | INDEX_FLAT_RW include/protect.h 10;" d 69 | INDEX_LDT_FIRST include/protect.h 13;" d 70 | INDEX_TSS include/protect.h 12;" d 71 | INDEX_VIDEO include/protect.h 11;" d 72 | INT_M_CTL include/const.h 16;" d 73 | INT_M_CTLMASK include/const.h 17;" d 74 | INT_S_CTL include/const.h 18;" d 75 | INT_S_CTLMASK include/const.h 19;" d 76 | INT_VECTOR_BOUNDS include/protect.h 80;" d 77 | INT_VECTOR_BREAKPOINT include/protect.h 78;" d 78 | INT_VECTOR_COPROC_ERR include/protect.h 90;" d 79 | INT_VECTOR_COPROC_NOT include/protect.h 82;" d 80 | INT_VECTOR_COPROC_SEG include/protect.h 84;" d 81 | INT_VECTOR_DEBUG include/protect.h 76;" d 82 | INT_VECTOR_DIVIDE include/protect.h 75;" d 83 | INT_VECTOR_DOUBLE_FAULT include/protect.h 83;" d 84 | INT_VECTOR_INVAL_OP include/protect.h 81;" d 85 | INT_VECTOR_INVAL_TSS include/protect.h 85;" d 86 | INT_VECTOR_IRQ0 include/protect.h 92;" d 87 | INT_VECTOR_IRQ8 include/protect.h 93;" d 88 | INT_VECTOR_NMI include/protect.h 77;" d 89 | INT_VECTOR_OVERFLOW include/protect.h 79;" d 90 | INT_VECTOR_PAGE_FAULT include/protect.h 89;" d 91 | INT_VECTOR_PROTECTION include/protect.h 88;" d 92 | INT_VECTOR_SEG_NOT include/protect.h 86;" d 93 | INT_VECTOR_STACK_FAULT include/protect.h 87;" d 94 | InitKernel boot/loader.asm /^ InitKernel:$/;" l 95 | KERNEL Makefile /^KERNEL = kernel.bin$/;" m 96 | KillMotor boot/loader.asm /^KillMotor:$/;" l 97 | LABEL_DATA boot/loader.asm /^ LABEL_DATA:$/;" l 98 | LABEL_PM_START boot/loader.asm /^ LABEL_PM_START:$/;" l 99 | LD Makefile /^LD = ld$/;" m 100 | LDFLAGS Makefile /^LDFLAGS = -s -Ttext $(ENTRYPOINT)$/;" m 101 | LDT_SIZE include/protect.h 29;" d 102 | MAX_TASKS include/process.h 36;" d 103 | MemChkBuf boot/loader.asm /^ MemChkBuf equ BaseOfLoaderPhyAddr + _MemChkBuf$/;" d 104 | MemCpy boot/loader.asm /^ MemCpy:$/;" l 105 | OBJS Makefile /^OBJS = kernel\/kernel.o kernel\/start.o kernel\/i8259.o kernel\/global.o kernel\/protect.o \\$/;" m 106 | ORANGESBOOT Makefile /^ORANGESBOOT = boot\/boot.bin boot\/loader.bin$/;" m 107 | OffsetOfLoader boot/boot.asm /^OffsetOfLoader equ 0100h$/;" d 108 | PRIVATE include/const.h 9;" d 109 | PRIVILEGE_KRNL include/const.h 22;" d 110 | PRIVILEGE_TASK include/const.h 23;" d 111 | PRIVILEGE_USER include/const.h 24;" d 112 | PROCESS include/process.h /^}PROCESS;$/;" t typeref:struct:s_proc 113 | PUBLIC include/const.h 8;" d 114 | RPL_KRNL include/const.h 27;" d 115 | RPL_TASK include/const.h 28;" d 116 | RPL_USER include/const.h 29;" d 117 | Read boot/boot.asm /^Read: $/;" l 118 | Read boot/loader.asm /^Read: $/;" l 119 | ReadSector boot/boot.asm /^ReadSector: ;读取磁盘 从第AX个扇区开始 将cl个扇区读入到ES:BX中$/;" l 120 | ReadSector boot/loader.asm /^ReadSector: ;读取磁盘 从第AX个扇区开始 将cl个扇区读入到ES:BX中$/;" l 121 | SA_RPL0 include/protect.h 35;" d 122 | SA_RPL1 include/protect.h 36;" d 123 | SA_RPL2 include/protect.h 37;" d 124 | SA_RPL3 include/protect.h 38;" d 125 | SA_RPL_MASK include/protect.h 34;" d 126 | SA_TIG include/protect.h 46;" d 127 | SA_TIL include/protect.h 47;" d 128 | SA_TI_MASK include/protect.h 45;" d 129 | SELECTOR_DUMMY include/protect.h 17;" d 130 | SELECTOR_FLAT_C include/protect.h 18;" d 131 | SELECTOR_FLAT_RW include/protect.h 19;" d 132 | SELECTOR_KERNEL_CS include/protect.h 24;" d 133 | SELECTOR_KERNEL_DS include/protect.h 25;" d 134 | SELECTOR_KERNEL_GS include/protect.h 26;" d 135 | SELECTOR_LDT_FIRST include/protect.h 22;" d 136 | SELECTOR_TSS include/protect.h 21;" d 137 | SELECTOR_VIDEO include/protect.h 20;" d 138 | STACK_FRAME include/process.h /^}STACK_FRAME; $/;" t typeref:struct:s_stackframe 139 | STACK_SIZE_TESTA include/process.h 39;" d 140 | STACK_SIZE_TOTAL include/process.h 41;" d 141 | SecLoopCount boot/boot.asm /^SecLoopCount db 14 ;根目录所占扇区数$/;" d 142 | SecLoopCount boot/loader.asm /^SecLoopCount db 14 ;根目录所占扇区数$/;" d 143 | SetupPaging boot/loader.asm /^ SetupPaging:$/;" l 144 | SltFlagC boot/loader.asm /^SltFlagC equ Desc_Flag_c - GDT$/;" d 145 | SltFlagRW boot/loader.asm /^SltFlagRW equ Desc_Flag_rw - GDT$/;" d 146 | SltVideo boot/loader.asm /^SltVideo equ Desc_Video - GDT + SA_RPL3$/;" d 147 | StackSpace boot/loader.asm /^ StackSpace: times 1024 db 0$/;" l 148 | StackSpace kernel/kernel.asm /^StackSpace resb 2 * 1024 ;resb用于声明未初始化的存储空间 resw resd resq$/;" l 149 | StackTop kernel/kernel.asm /^StackTop: ;栈顶 堆栈内容向低地址扩展$/;" l 150 | TRUE include/const.h 34;" d 151 | TSS include/protect.h /^}TSS;$/;" t typeref:struct:s_tss 152 | TestA kernel/main.c /^void TestA()$/;" f 153 | TopOfStack boot/loader.asm /^ TopOfStack equ BaseOfLoaderPhyAddr + $ ; 栈顶$/;" d 154 | _ARDStruct boot/loader.asm /^ _ARDStruct: ; Address Range Descriptor Structure$/;" l 155 | _CONST_H_ include/const.h 3;" d 156 | _MemChkBuf boot/loader.asm /^ _MemChkBuf: times 256 db 0$/;" l 157 | _PROTECT_H_ include/protect.h 3;" d 158 | _TYPE_H_ include/type.h 3;" d 159 | _dwBaseAddrHigh boot/loader.asm /^ _dwBaseAddrHigh: dd 0$/;" d 160 | _dwBaseAddrLow boot/loader.asm /^ _dwBaseAddrLow: dd 0$/;" d 161 | _dwDispPos boot/loader.asm /^ _dwDispPos: dd (80 * 6 + 0) * 2 ; 屏幕第 6 行, 第 0 列$/;" d 162 | _dwLengthHigh boot/loader.asm /^ _dwLengthHigh: dd 0$/;" d 163 | _dwLengthLow boot/loader.asm /^ _dwLengthLow: dd 0$/;" d 164 | _dwMCRNumber boot/loader.asm /^ _dwMCRNumber: dd 0 ; Memory Check Result$/;" d 165 | _dwMemSize boot/loader.asm /^ _dwMemSize: dd 0$/;" d 166 | _dwType boot/loader.asm /^ _dwType: dd 0$/;" d 167 | _start kernel/kernel.asm /^_start:$/;" l 168 | _szMemChkTitle boot/loader.asm /^ _szMemChkTitle: db "BaseAddrL BaseAddrH LengthLow LengthHigh Type", 0Ah, 0$/;" d 169 | _szRAMSize boot/loader.asm /^ _szRAMSize: db "RAM size:", 0$/;" d 170 | _szReturn boot/loader.asm /^ _szReturn: db 0Ah, 0$/;" d 171 | attr include/protect.h /^ u8 attr;$/;" m struct:s_gate 172 | attr1 include/protect.h /^ u8 attr1; \/*P(1) DPL(2) DT(1) TYPE(4)*\/$/;" m struct:s_descriptor 173 | backlink include/protect.h /^ u32 backlink;$/;" m struct:s_tss 174 | base_high include/protect.h /^ u8 base_high;$/;" m struct:s_descriptor 175 | base_low include/protect.h /^ u16 base_low;$/;" m struct:s_descriptor 176 | base_mid include/protect.h /^ u8 base_mid;$/;" m struct:s_descriptor 177 | bounds_check kernel/kernel.asm /^bounds_check:$/;" l 178 | breakpoint_exception kernel/kernel.asm /^breakpoint_exception:$/;" l 179 | cmpfilename boot/boot.asm /^cmpfilename: ;比较文件名称 lodsb --> si 自增或自减$/;" l 180 | cmpfilename boot/loader.asm /^cmpfilename: ;比较文件名称 lodsb --> si 自增或自减$/;" l 181 | copr_error kernel/kernel.asm /^copr_error:$/;" l 182 | copr_not_available kernel/kernel.asm /^copr_not_available:$/;" l 183 | copr_seg_overrun kernel/kernel.asm /^copr_seg_overrun:$/;" l 184 | cr3 include/protect.h /^ u32 cr3;$/;" m struct:s_tss 185 | cs include/process.h /^ u32 cs; \/* | *\/$/;" m struct:s_stackframe 186 | cs include/protect.h /^ u32 cs; $/;" m struct:s_tss 187 | csinit kernel/kernel.asm /^csinit:$/;" l 188 | cstart kernel/start.c /^PUBLIC void cstart()$/;" f 189 | dcount include/protect.h /^ u8 dcount; \/* 该字段只在调用门描述符中有效。如果在利用调用门$/;" m struct:s_gate 190 | dec boot/boot.asm /^ dec dx$/;" d 191 | dec boot/boot.asm /^ dec dx$/;" d 192 | dec boot/loader.asm /^ dec dx$/;" d 193 | dec boot/loader.asm /^ dec dx$/;" d 194 | delay lib/klib.c /^PUBLIC void delay(int time)$/;" f 195 | disp_color_str lib/kliba.asm /^disp_color_str:$/;" l 196 | disp_int lib/klib.c /^PUBLIC void disp_int(int input)$/;" f 197 | disp_pos include/global.h /^EXTERN int disp_pos;$/;" v 198 | disp_str lib/kliba.asm /^disp_str:$/;" l 199 | divide_error kernel/kernel.asm /^divide_error:$/;" l 200 | double_fault kernel/kernel.asm /^double_fault:$/;" l 201 | ds include/process.h /^ u32 ds; \/* | *\/$/;" m struct:s_stackframe 202 | ds include/protect.h /^ u32 ds; $/;" m struct:s_tss 203 | dw boot/boot.asm /^dw 0xaa55 ;引导扇区结束标志$/;" l 204 | dwBaseAddrHigh boot/loader.asm /^ dwBaseAddrHigh equ BaseOfLoaderPhyAddr + _dwBaseAddrHigh$/;" d 205 | dwBaseAddrLow boot/loader.asm /^ dwBaseAddrLow equ BaseOfLoaderPhyAddr + _dwBaseAddrLow$/;" d 206 | dwDispPos boot/loader.asm /^ dwDispPos equ BaseOfLoaderPhyAddr + _dwDispPos$/;" d 207 | dwLengthHigh boot/loader.asm /^ dwLengthHigh equ BaseOfLoaderPhyAddr + _dwLengthHigh$/;" d 208 | dwLengthLow boot/loader.asm /^ dwLengthLow equ BaseOfLoaderPhyAddr + _dwLengthLow$/;" d 209 | dwMCRNumber boot/loader.asm /^ dwMCRNumber equ BaseOfLoaderPhyAddr + _dwMCRNumber$/;" d 210 | dwMemSize boot/loader.asm /^ dwMemSize equ BaseOfLoaderPhyAddr + _dwMemSize$/;" d 211 | dwType boot/loader.asm /^ dwType equ BaseOfLoaderPhyAddr + _dwType$/;" d 212 | eax include/process.h /^ u32 eax; \/* \/ *\/$/;" m struct:s_stackframe 213 | eax include/protect.h /^ u32 eax;$/;" m struct:s_tss 214 | ebp include/process.h /^ u32 ebp; \/* | *\/$/;" m struct:s_stackframe 215 | ebp include/protect.h /^ u32 ebp;$/;" m struct:s_tss 216 | ebx include/process.h /^ u32 ebx; \/* | *\/$/;" m struct:s_stackframe 217 | ebx include/protect.h /^ u32 ebx;$/;" m struct:s_tss 218 | ecx include/process.h /^ u32 ecx; \/* | *\/$/;" m struct:s_stackframe 219 | ecx include/protect.h /^ u32 ecx;$/;" m struct:s_tss 220 | edi include/process.h /^ u32 edi; \/* | *\/$/;" m struct:s_stackframe 221 | edi include/protect.h /^ u32 edi;$/;" m struct:s_tss 222 | edx include/process.h /^ u32 edx; \/* | *\/$/;" m struct:s_stackframe 223 | edx include/protect.h /^ u32 edx;$/;" m struct:s_tss 224 | eflags include/process.h /^ u32 eflags; \/* | pushed by CPU during interrupt *\/$/;" m struct:s_stackframe 225 | eip include/process.h /^ u32 eip; \/* \\ *\/$/;" m struct:s_stackframe 226 | eip include/protect.h /^ u32 eip;$/;" m struct:s_tss 227 | es include/process.h /^ u32 es; \/* | *\/$/;" m struct:s_stackframe 228 | es include/protect.h /^ u32 es; $/;" m struct:s_tss 229 | esi include/process.h /^ u32 esi; \/* | pushed by save() *\/$/;" m struct:s_stackframe 230 | esi include/protect.h /^ u32 esi;$/;" m struct:s_tss 231 | esp include/process.h /^ u32 esp; \/* | *\/$/;" m struct:s_stackframe 232 | esp include/protect.h /^ u32 esp;$/;" m struct:s_tss 233 | esp0 include/protect.h /^ u32 esp0; \/* stack pointer to use during interrupt *\/$/;" m struct:s_tss 234 | esp1 include/protect.h /^ u32 esp1;$/;" m struct:s_tss 235 | esp2 include/protect.h /^ u32 esp2;$/;" m struct:s_tss 236 | exception kernel/kernel.asm /^exception:$/;" l 237 | exception_handler kernel/protect.c /^PUBLIC void exception_handler(int vec_no,int err_code,int eip,int cs,int eflags)$/;" f 238 | extern kernel/kernel.asm /^extern cstart$/;" l 239 | extern kernel/kernel.asm /^extern disp_pos$/;" l 240 | extern kernel/kernel.asm /^extern exception_handler$/;" l 241 | extern kernel/kernel.asm /^extern gdt_ptr$/;" l 242 | extern kernel/kernel.asm /^extern idt_ptr$/;" l 243 | extern kernel/kernel.asm /^extern intrpt_handler$/;" l 244 | extern kernel/kernel.asm /^extern kernel_main$/;" l 245 | extern kernel/kernel.asm /^extern p_proc_ready$/;" l 246 | extern kernel/kernel.asm /^extern tss$/;" l 247 | extern lib/kliba.asm /^extern disp_pos$/;" l 248 | filename boot/boot.asm /^filename db "LOADER BIN",0 ;文件名为11字节$/;" d 249 | filename boot/loader.asm /^filename db "KERNEL BIN",0 ;文件名为11字节$/;" d 250 | findFile boot/boot.asm /^findFile: ;开始查找$/;" l 251 | findFile boot/loader.asm /^findFile: ;开始查找$/;" l 252 | finded boot/boot.asm /^finded: $/;" l 253 | finded boot/loader.asm /^finded: $/;" l 254 | finish boot/boot.asm /^finish:$/;" l 255 | finish boot/loader.asm /^finish:$/;" l 256 | flags include/protect.h /^ u32 flags;$/;" m struct:s_tss 257 | fs include/process.h /^ u32 fs; \/* | *\/$/;" m struct:s_stackframe 258 | fs include/protect.h /^ u32 fs; $/;" m struct:s_tss 259 | gdt include/global.h /^EXTERN DESCRIPTOR gdt[GDT_SIZE];$/;" v 260 | gdt_ptr include/global.h /^EXTERN u8 gdt_ptr[6]; \/* 0 ~15: Limit (2 bytes ) $/;" v 261 | general_protection kernel/kernel.asm /^general_protection:$/;" l 262 | global kernel/kernel.asm /^global hint00$/;" l 263 | global kernel/kernel.asm /^global hint01$/;" l 264 | global kernel/kernel.asm /^global hint02$/;" l 265 | global kernel/kernel.asm /^global hint03$/;" l 266 | global kernel/kernel.asm /^global hint04$/;" l 267 | global kernel/kernel.asm /^global hint05$/;" l 268 | global kernel/kernel.asm /^global hint06$/;" l 269 | global kernel/kernel.asm /^global hint07$/;" l 270 | global kernel/kernel.asm /^global hint08$/;" l 271 | global kernel/kernel.asm /^global hint09$/;" l 272 | global kernel/kernel.asm /^global hint10$/;" l 273 | global kernel/kernel.asm /^global hint11$/;" l 274 | global kernel/kernel.asm /^global hint12$/;" l 275 | global kernel/kernel.asm /^global hint13$/;" l 276 | global kernel/kernel.asm /^global hint14$/;" l 277 | global kernel/kernel.asm /^global hint15$/;" l 278 | global kernel/kernel.asm /^global _start$/;" l 279 | global kernel/kernel.asm /^global bounds_check$/;" l 280 | global kernel/kernel.asm /^global breakpoint_exception$/;" l 281 | global kernel/kernel.asm /^global copr_error$/;" l 282 | global kernel/kernel.asm /^global copr_not_available$/;" l 283 | global kernel/kernel.asm /^global copr_seg_overrun$/;" l 284 | global kernel/kernel.asm /^global divide_error$/;" l 285 | global kernel/kernel.asm /^global double_fault$/;" l 286 | global kernel/kernel.asm /^global general_protection$/;" l 287 | global kernel/kernel.asm /^global inval_opcode$/;" l 288 | global kernel/kernel.asm /^global inval_tss$/;" l 289 | global kernel/kernel.asm /^global nmi$/;" l 290 | global kernel/kernel.asm /^global overflow$/;" l 291 | global kernel/kernel.asm /^global page_fault$/;" l 292 | global kernel/kernel.asm /^global restart$/;" l 293 | global kernel/kernel.asm /^global segment_not_present$/;" l 294 | global kernel/kernel.asm /^global single_step_exception$/;" l 295 | global kernel/kernel.asm /^global stack_exception$/;" l 296 | global lib/kliba.asm /^global disp_str$/;" l 297 | global lib/kliba.asm /^global disp_color_str$/;" l 298 | global lib/kliba.asm /^global in_byte$/;" l 299 | global lib/kliba.asm /^global out_byte$/;" l 300 | global lib/string.asm /^global memcpy$/;" l 301 | gs include/process.h /^ u32 gs; \/* \\ *\/$/;" m struct:s_stackframe 302 | gs include/protect.h /^ u32 gs; $/;" m struct:s_tss 303 | hint00 kernel/kernel.asm /^hint00: ; irq 0 --> the clock$/;" l 304 | hint01 kernel/kernel.asm /^hint01: ; irq 1 --> keyboard$/;" l 305 | hint02 kernel/kernel.asm /^hint02: ; irq 2 --> cascade$/;" l 306 | hint03 kernel/kernel.asm /^hint03: ; irq 3 --> second serial$/;" l 307 | hint04 kernel/kernel.asm /^hint04: ; irq 4 --> first serial$/;" l 308 | hint05 kernel/kernel.asm /^hint05: ; irq 5 --> XT winchester$/;" l 309 | hint06 kernel/kernel.asm /^hint06: ; irq 6 --> floppy$/;" l 310 | hint07 kernel/kernel.asm /^hint07: ; irq 7 --> printer$/;" l 311 | hint08 kernel/kernel.asm /^hint08: ; irq 8 --> realtime clock$/;" l 312 | hint09 kernel/kernel.asm /^hint09: ; irq 9 --> irq 2 redirected$/;" l 313 | hint10 kernel/kernel.asm /^hint10: ; irq 10 $/;" l 314 | hint11 kernel/kernel.asm /^hint11: ; irq 11$/;" l 315 | hint12 kernel/kernel.asm /^hint12: ; irq 12$/;" l 316 | hint13 kernel/kernel.asm /^hint13: ; irq 13 --> FPU Exception$/;" l 317 | hint14 kernel/kernel.asm /^hint14: ; irq 14 --> AT winchester$/;" l 318 | hint15 kernel/kernel.asm /^hint15: ; irq 15$/;" l 319 | idt include/global.h /^EXTERN GATE idt[IDT_SIZE];$/;" v 320 | idt_ptr include/global.h /^EXTERN u8 idt_ptr[6]; \/* 0~15:Limit 16~47:Base *\/$/;" v 321 | in_byte lib/kliba.asm /^in_byte:$/;" l 322 | inc boot/boot.asm /^ inc di$/;" d 323 | inc boot/loader.asm /^ inc di$/;" d 324 | init_8259A kernel/i8259.c /^PUBLIC void init_8259A()$/;" f 325 | init_idt_desc kernel/protect.c /^PRIVATE void init_idt_desc(unsigned char vector,u8 desc_type,$/;" f 326 | init_prot kernel/protect.c /^PUBLIC void init_prot()$/;" f 327 | inito_descriptor kernel/protect.c /^PRIVATE void inito_descriptor(DESCIPRTOR* p_desc,u32 base ,u32 limit,u16 attr)$/;" f 328 | int boot/boot.asm /^int 10h$/;" l 329 | int boot/boot.asm /^int 13h $/;" l 330 | int boot/loader.asm /^int 10h$/;" l 331 | int_handler include/type.h /^typedef void (*int_handler) (); \/*函数指针*\/$/;" t 332 | intrpt_handler kernel/i8259.c /^PUBLIC void intrpt_handler(int irq)$/;" f 333 | inval_opcode kernel/kernel.asm /^inval_opcode:$/;" l 334 | inval_tss kernel/kernel.asm /^inval_tss:$/;" l 335 | iobase include/protect.h /^ u16 iobase; \/* I\/O位图基址大于或等于TSS段界限,就表示没有I\/O许可位图 *\/$/;" m struct:s_tss 336 | itoa lib/klib.c /^PUBLIC char* itoa(char* str,int num )$/;" f 337 | jmp boot/boot.asm /^jmp short startx ; Start to boot.$/;" l 338 | jmp boot/loader.asm /^jmp startx ; Start to boot.$/;" l 339 | jmptokernel boot/loader.asm /^jmptokernel:$/;" l 340 | jmptoloader boot/boot.asm /^jmptoloader:$/;" l 341 | jnz boot/boot.asm /^ jnz label ;若是奇数项(注意是从0开始,所以第一项为0 应该算偶数项)則取后三位 and ax,0x0FFF$/;" l 342 | jnz boot/loader.asm /^ jnz label ;若是奇数项(注意是从0开始,所以第一项为0 应该算偶数项)則取后三位 and ax,0x0FFF$/;" l 343 | kernel_esp include/process.h /^ u32 kernel_esp; \/* <- 'popad' will ignore it *\/$/;" m struct:s_stackframe 344 | kernel_main kernel/main.c /^PUBLIC int kernel_main()$/;" f 345 | ldt include/protect.h /^ u32 ldt;$/;" m struct:s_tss 346 | ldt_sel include/process.h /^ u16 ldt_sel; \/* gdt selector giving ldt base and limit *\/$/;" m struct:s_proc 347 | ldts include/process.h /^ DESCRIPTOR ldts[LDT_SIZE]; \/* local descriptors for code and data *\/$/;" m struct:s_proc 348 | limit_high_attr2 include/protect.h /^ u8 limit_high_attr2; $/;" m struct:s_descriptor 349 | limit_low include/protect.h /^ u16 limit_low;$/;" m struct:s_descriptor 350 | memcpy lib/string.asm /^memcpy:$/;" l 351 | mov boot/boot.asm /^mov ah,6$/;" l 352 | mov boot/boot.asm /^mov al,0$/;" l 353 | mov boot/boot.asm /^mov ax,cs$/;" l 354 | mov boot/boot.asm /^mov bh,7$/;" l 355 | mov boot/boot.asm /^mov ch,0$/;" l 356 | mov boot/boot.asm /^mov cl,0$/;" l 357 | mov boot/boot.asm /^mov dh,24$/;" l 358 | mov boot/boot.asm /^mov dl,79$/;" l 359 | mov boot/boot.asm /^mov ds,ax$/;" l 360 | mov boot/boot.asm /^mov es,ax$/;" l 361 | mov boot/boot.asm /^mov sp,BaseOfStack$/;" l 362 | mov boot/boot.asm /^mov ss,ax$/;" l 363 | mov boot/loader.asm /^mov ah,6$/;" l 364 | mov boot/loader.asm /^mov al,0$/;" l 365 | mov boot/loader.asm /^mov ax,cs$/;" l 366 | mov boot/loader.asm /^mov bh,7$/;" l 367 | mov boot/loader.asm /^mov ch,0$/;" l 368 | mov boot/loader.asm /^mov cl,0$/;" l 369 | mov boot/loader.asm /^mov dh,24$/;" l 370 | mov boot/loader.asm /^mov dl,79$/;" l 371 | mov boot/loader.asm /^mov ds,ax$/;" l 372 | mov boot/loader.asm /^mov es,ax$/;" l 373 | mov boot/loader.asm /^mov sp,BaseOfStack$/;" l 374 | mov boot/loader.asm /^mov ss,ax$/;" l 375 | msg_bad boot/boot.asm /^msg_bad db "Bad clus",0$/;" d 376 | msg_bad boot/loader.asm /^msg_bad db "Bad clus",0$/;" d 377 | msg_badfat boot/boot.asm /^msg_badfat db "Fat damaged...",0$/;" d 378 | msg_badfat boot/loader.asm /^msg_badfat db "Fat damaged...",0$/;" d 379 | msg_finded boot/boot.asm /^msg_finded db "Ready!",0$/;" d 380 | msg_finded boot/loader.asm /^msg_finded db "Kernel!",0$/;" d 381 | msg_nofind boot/boot.asm /^msg_nofind db "No Loader",0$/;" d 382 | msg_nofind boot/loader.asm /^msg_nofind db "No kernel",0$/;" d 383 | nextfile boot/boot.asm /^nextfile: ;转到下一个文件$/;" l 384 | nextfile boot/loader.asm /^nextfile: ;转到下一个文件$/;" l 385 | nmi kernel/kernel.asm /^nmi:$/;" l 386 | odd boot/boot.asm /^odd db 0$/;" d 387 | odd boot/loader.asm /^odd db 0$/;" d 388 | offset_hight include/protect.h /^ u16 offset_hight;$/;" m struct:s_gate 389 | offset_low include/protect.h /^ u16 offset_low;$/;" m struct:s_gate 390 | org boot/boot.asm /^org 07c00h ;bios 可将引导扇区加载到0:7c00 处 并开始执行$/;" l 391 | org boot/loader.asm /^org 0100h $/;" l 392 | out_byte lib/kliba.asm /^out_byte:$/;" l 393 | overflow kernel/kernel.asm /^overflow:$/;" l 394 | p_name include/process.h /^ char p_name[16]; \/* name of the process *\/$/;" m struct:s_proc 395 | p_proc_ready include/global.h /^EXTERN PROCESS* p_proc_ready;$/;" v 396 | page_fault kernel/kernel.asm /^page_fault:$/;" l 397 | pid include/process.h /^ u32 pid; \/* process id passed in from MM *\/$/;" m struct:s_proc 398 | pop boot/loader.asm /^ pop dx$/;" d 399 | pop kernel/kernel.asm /^ pop ds$/;" d 400 | proc_table kernel/global.c /^PUBLIC PROCESS proc_table[MAX_TASKS];$/;" v 401 | push boot/boot.asm /^ push dx ;保存fat值在扇区中的偏移$/;" d 402 | push boot/loader.asm /^ push dx ;保存fat值在扇区中的偏移$/;" d 403 | push boot/loader.asm /^ push dx$/;" d 404 | regs include/process.h /^ STACK_FRAME regs; \/* process registers saved in stack frame *\/$/;" m struct:s_proc 405 | restart kernel/kernel.asm /^restart:$/;" l 406 | retaddr include/process.h /^ u32 retaddr; \/* return addr for kernel.asm::save() *\/$/;" m struct:s_stackframe 407 | s_descriptor include/protect.h /^typedef struct s_descriptor \/* 8字节 *\/$/;" s 408 | s_gate include/protect.h /^typedef struct s_gate$/;" s 409 | s_proc include/process.h /^typedef struct s_proc {$/;" s 410 | s_stackframe include/process.h /^typedef struct s_stackframe { $/;" s 411 | s_tss include/protect.h /^typedef struct s_tss{$/;" s 412 | secnum boot/boot.asm /^secnum db 0 ;扇区号$/;" d 413 | secnum boot/loader.asm /^secnum db 0 ;扇区号$/;" d 414 | seg2phys kernel/protect.c /^PUBLIC u32 seg2phys(u16 seg)$/;" f 415 | segment_not_present kernel/kernel.asm /^segment_not_present:$/;" l 416 | selector include/protect.h /^ u16 selector;$/;" m struct:s_gate 417 | single_step_exception kernel/kernel.asm /^single_step_exception:$/;" l 418 | ss include/process.h /^ u32 ss; \/* \/ *\/$/;" m struct:s_stackframe 419 | ss include/protect.h /^ u32 ss; $/;" m struct:s_tss 420 | ss0 include/protect.h /^ u32 ss0; \/* " segment " " " " *\/$/;" m struct:s_tss 421 | ss1 include/protect.h /^ u32 ss1;$/;" m struct:s_tss 422 | ss2 include/protect.h /^ u32 ss2;$/;" m struct:s_tss 423 | stack_exception kernel/kernel.asm /^stack_exception:$/;" l 424 | startx boot/boot.asm /^startx:$/;" l 425 | startx boot/loader.asm /^startx:$/;" l 426 | szMemChkTitle boot/loader.asm /^ szMemChkTitle equ BaseOfLoaderPhyAddr + _szMemChkTitle$/;" d 427 | szRAMSize boot/loader.asm /^ szRAMSize equ BaseOfLoaderPhyAddr + _szRAMSize$/;" d 428 | szReturn boot/loader.asm /^ szReturn equ BaseOfLoaderPhyAddr + _szReturn$/;" d 429 | task_stack kernel/global.c /^PUBLIC char task_stack[STACK_SIZE_TOTAL];$/;" v 430 | times boot/boot.asm /^times 510-($-$$) db 0 ; 填充剩下的空间 使生成的二进制代码恰好为512字节$/;" l 431 | trap include/protect.h /^ u16 trap;$/;" m struct:s_tss 432 | tss include/global.h /^EXTERN TSS tss;$/;" v 433 | u16 include/type.h /^typedef unsigned short u16;$/;" t 434 | u32 include/type.h /^typedef unsigned int u32;$/;" t 435 | u8 include/type.h /^typedef unsigned char u8;$/;" t 436 | vir2phys include/protect.h 97;" d 437 | xor boot/boot.asm /^xor ah,ah$/;" l 438 | xor boot/boot.asm /^xor dl,dl$/;" l 439 | --------------------------------------------------------------------------------