├── .gitignore ├── CREDITS.md ├── LICENSE ├── Makefile ├── README.md ├── Rules.inc ├── boot └── x86_64 │ ├── Makefile │ ├── entry64.S │ ├── entry64.o │ ├── entryother │ ├── entryother.S │ ├── include │ ├── asm.h │ ├── defs.h │ ├── memlayout.h │ ├── mmu.h │ ├── param.h │ ├── proc.h │ ├── syscall.h │ ├── traps.h │ ├── types.h │ └── x86.h │ ├── initcode │ ├── initcode64.S │ ├── kernel64.ld │ ├── main.c │ └── main.o ├── kernel ├── Makefile ├── console.rs ├── kalloc.rs ├── kernel.rs ├── lapic.rs ├── memlayout.rs ├── mmu.rs ├── picirq.rs ├── rlibc.rs ├── spinlock.rs ├── task.rs ├── traps.rs ├── uart.rs └── x86asm.rs ├── staging ├── Makefile ├── iso │ └── boot │ │ └── grub │ │ └── grub.cfg └── linker.ld ├── tools ├── Makefile ├── install.sh └── uninstall.sh └── xv62rustx.map /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled files 2 | *.o 3 | *.a 4 | *.so 5 | *.rlib 6 | *.dll 7 | *.lock 8 | 9 | # Executables 10 | *.exe 11 | 12 | # Generated by Cargo 13 | /target/ 14 | -------------------------------------------------------------------------------- /CREDITS.md: -------------------------------------------------------------------------------- 1 | * Got started with the information here http://wiki.osdev.org/64-bit_Higher_Half_Kernel_with_GRUB_2 2 | boot.s and linker.ld are from there 3 | 4 | * Got insights about stack checking code inserted by rustc and the fact that FS needs to be set correctly from https://github.com/thepowersgang/rust_os 5 | 6 | * Got help in compiling standalone rust from https://github.com/Zoxc 7 | 8 | * Thanks to [Yukang](https://github.com/chenyukang) for pointing me to location of pre-built binutils for mac 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Kashyap 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | # 3 | # Copyright (c) 2014 Kashyap 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | include Rules.inc 24 | 25 | all: 26 | make SOURCE_ROOT=$$PWD -C kernel 27 | make SOURCE_ROOT=$$PWD -C staging 28 | 29 | iso: all 30 | make SOURCE_ROOT=$$PWD -C staging iso 31 | 32 | 33 | reinstall_rust: 34 | make SOURCE_ROOT=$$PWD -C tools reinstall_rust 35 | 36 | run: 37 | $(QEMU) 38 | 39 | clean: 40 | make SOURCE_ROOT=$$PWD -C kernel clean 41 | make SOURCE_ROOT=$$PWD -C staging clean 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | unix 2 | ==== 3 | 4 | 5 | Project stalled for now - doing this in Nim https://github.com/ckkashyap/nim-xv6 6 | 7 | Unix kernel in rust. 8 | To start off with, its a port of xv6 that runs on x86_64. 9 | 10 | * Wiki - https://github.com/ckkashyap/unix/wiki 11 | * Journal - https://github.com/ckkashyap/unix/wiki/Journal 12 | -------------------------------------------------------------------------------- /Rules.inc: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | # 3 | # Copyright (c) 2014 Kashyap 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | LD=ld 24 | AR=ar 25 | QEMU=qemu-system-x86_64 -kernel staging/kernel.sys -serial stdio -vnc :1 -no-reboot -d int -s 26 | LINUX_TARGET=x86_64-unknown-linux-gnu 27 | MAC_TARGET=x86_64-apple-darwin 28 | LINUX_RUST_DIR=$(RUST_ROOT)/rust-nightly-$(LINUX_TARGET) 29 | MAC_RUST_DIR=$(RUST_ROOT)/rust-nightly-$(MAC_TARGET) 30 | RUST_DIR=$(LINUX_RUST_DIR) 31 | OBJDUMP=objdump 32 | RUSTC=LD_LIBRARY_PATH=$(LINUX_RUST_DIR)/lib $(LINUX_RUST_DIR)/bin/rustc 33 | 34 | 35 | OS=$(shell uname) 36 | ifeq ($(OS), Darwin) 37 | LD=$(LINKEDITOR) 38 | AR=$(ARCHIVE) 39 | LD_LIBRARY_PATH=DYLD_LIBRARY_PATH 40 | QEMU=qemu-system-x86_64 -kernel staging/kernel.sys -serial stdio -no-reboot -d int 41 | RUST_DIR=$(MAC_RUST_DIR) 42 | RUSTC=DYLD_LIBRARY_PATH=$(MAC_RUST_DIR)/lib $(MAC_RUST_DIR)/bin/rustc 43 | endif 44 | 45 | AT=@ 46 | 47 | dummy: all 48 | 49 | %o:%s 50 | @echo "$<" 51 | $(AT)nasm -felf64 $< -o $@ 52 | 53 | process_sub_dirs: 54 | $(AT)for file in $(SUB_DIRS); do make SOURCE_ROOT=$(SOURCE_ROOT) -C $$file; done 55 | 56 | clean_sub_dirs: 57 | $(AT)for file in $(SUB_DIRS); do make SOURCE_ROOT=$(SOURCE_ROOT) -C $$file clean; done 58 | -------------------------------------------------------------------------------- /boot/x86_64/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -MD -ggdb -fno-omit-frame-pointer -ffreestanding -fno-common -nostdlib -Iinclude -gdwarf-2 -m64 -DX64 -mcmodel=kernel -mtls-direct-seg-refs -mno-red-zone -O0 -fno-stack-protector -nostdinc -I. -o initcode.o -c initcode64.S 3 | ld -m elf_x86_64 -nodefaultlibs -N -e start -Ttext 0 -o initcode.out initcode.o 4 | objcopy -S -O binary initcode.out initcode 5 | gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -MD -ggdb -fno-omit-frame-pointer -ffreestanding -fno-common -nostdlib -Iinclude -gdwarf-2 -m64 -DX64 -mcmodel=kernel -mtls-direct-seg-refs -mno-red-zone -O0 -fno-stack-protector -fno-pic -nostdinc -I. -o entryother.o -c entryother.S 6 | ld -m elf_x86_64 -nodefaultlibs -N -e start -Ttext 0x7000 -o bootblockother.o entryother.o 7 | objcopy -S -O binary -j .text bootblockother.o entryother 8 | gcc -gdwarf-2 -Wa,-divide -Iinclude -m64 -DX64 -mcmodel=kernel -mtls-direct-seg-refs -mno-red-zone -c -o entry64.o entry64.S 9 | gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -MD -ggdb -fno-omit-frame-pointer -ffreestanding -fno-common -nostdlib -Iinclude -gdwarf-2 -m64 -DX64 -mcmodel=kernel -mtls-direct-seg-refs -mno-red-zone -O0 -fno-stack-protector -c -o main.o main.c 10 | #ld -m elf_x86_64 -nodefaultlibs -T kernel64.ld -o kernel.elf entry64.o main.o -b binary initcode entryother 11 | 12 | 13 | clean: 14 | rm -f initcode.o initcode.out initcode entryother.o entryother bootblockother.o entry64.o main.o kernel.elf *.d 15 | 16 | 17 | run: 18 | qemu-system-x86_64 -kernel kernel.elf -vnc :1 -no-reboot -d int -serial stdio 19 | -------------------------------------------------------------------------------- /boot/x86_64/entry64.S: -------------------------------------------------------------------------------- 1 | /* entry64.S 2 | * 3 | * Copyright (c) 2013 Brian Swetland 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining 6 | * a copy of this software and associated documentation files (the 7 | * "Software"), to deal in the Software without restriction, including 8 | * without limitation the rights to use, copy, modify, merge, publish, 9 | * distribute, sublicense, and/or sell copies of the Software, and to 10 | * permit persons to whom the Software is furnished to do so, subject to 11 | * the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | * 24 | */ 25 | 26 | #define mboot_magic 0x1badb002 27 | #define mboot_flags 0x00010000 28 | 29 | .code32 30 | .global mboot_header 31 | .global mboot_entry 32 | 33 | mboot_header: 34 | .long mboot_magic 35 | .long mboot_flags 36 | .long (-mboot_magic -mboot_flags) # checksum 37 | .long mboot_load_addr # header_addr 38 | .long mboot_load_addr 39 | .long mboot_load_end 40 | .long mboot_bss_end 41 | .long mboot_entry_addr 42 | 43 | mboot_entry: 44 | 45 | # zero 4 pages for our bootstrap page tables 46 | xor %eax, %eax 47 | mov $0x1000, %edi 48 | mov $0x5000, %ecx 49 | rep stosb 50 | 51 | # P4ML[0] -> 0x2000 (PDPT-A) 52 | mov $(0x2000 | 3), %eax 53 | mov %eax, 0x1000 54 | 55 | # P4ML[511] -> 0x3000 (PDPT-B) 56 | mov $(0x3000 | 3), %eax 57 | mov %eax, 0x1FF8 58 | 59 | # PDPT-A[0] -> 0x4000 (PD) 60 | mov $(0x4000 | 3), %eax 61 | mov %eax, 0x2000 62 | 63 | # PDPT-B[510] -> 0x4000 (PD) 64 | mov $(0x4000 | 3), %eax 65 | mov %eax, 0x3FF0 66 | 67 | # PD[0..511] -> 0..1022MB 68 | mov $0x83, %eax 69 | mov $0x4000, %ebx 70 | mov $512, %ecx 71 | ptbl_loop: 72 | mov %eax, (%ebx) 73 | add $0x200000, %eax 74 | add $0x8, %ebx 75 | dec %ecx 76 | jnz ptbl_loop 77 | 78 | # Clear ebx for initial processor boot. 79 | # When secondary processors boot, they'll call through 80 | # entry32mp (from entryother), but with a nonzero ebx. 81 | # We'll reuse these bootstrap pagetables and GDT. 82 | xor %ebx, %ebx 83 | 84 | .global entry32mp 85 | entry32mp: 86 | # CR3 -> 0x1000 (P4ML) 87 | mov $0x1000, %eax 88 | mov %eax, %cr3 89 | 90 | lgdt (gdtr64 - mboot_header + mboot_load_addr) 91 | 92 | # Enable PAE - CR4.PAE=1 93 | mov %cr4, %eax 94 | bts $5, %eax 95 | mov %eax, %cr4 96 | 97 | # enable long mode - EFER.LME=1 98 | mov $0xc0000080, %ecx 99 | rdmsr 100 | bts $8, %eax 101 | wrmsr 102 | 103 | # enable paging 104 | mov %cr0, %eax 105 | bts $31, %eax 106 | mov %eax, %cr0 107 | 108 | # shift to 64bit segment 109 | ljmp $8,$(entry64low - mboot_header + mboot_load_addr) 110 | 111 | .align 16 112 | gdtr64: 113 | .word gdt64_end - gdt64_begin - 1; 114 | .quad gdt64_begin - mboot_header + mboot_load_addr 115 | 116 | .align 16 117 | gdt64_begin: 118 | .long 0x00000000 # 0: null desc 119 | .long 0x00000000 120 | .long 0x00000000 # 1: Code, R/X, Nonconforming 121 | .long 0x00209800 122 | .long 0x00000000 # 2: Data, R/W, Expand Down 123 | .long 0x00009000 124 | gdt64_end: 125 | 126 | .align 16 127 | .code64 128 | entry64low: 129 | movq $entry64high, %rax 130 | jmp *%rax 131 | 132 | .global _start 133 | _start: 134 | entry64high: 135 | 136 | # ensure data segment registers are sane 137 | xor %rax, %rax 138 | mov %ax, %ss 139 | mov %ax, %ds 140 | mov %ax, %es 141 | mov %ax, %fs 142 | mov %ax, %gs 143 | 144 | # check to see if we're booting a secondary core 145 | test %ebx, %ebx 146 | jnz entry64mp 147 | 148 | # setup initial stack 149 | mov $0xFFFFFFFF80010000, %rax 150 | mov %rax, %rsp 151 | 152 | # enter main() 153 | jmp main 154 | 155 | .global __deadloop 156 | __deadloop: 157 | # we should never return here... 158 | jmp . 159 | 160 | entry64mp: 161 | # obtain kstack from data block before entryother 162 | mov $0x7000, %rax 163 | mov -16(%rax), %rsp 164 | jmp mpenter 165 | 166 | .global wrmsr 167 | wrmsr: 168 | mov %rdi, %rcx # arg0 -> msrnum 169 | mov %rsi, %rax # val.low -> eax 170 | shr $32, %rsi 171 | mov %rsi, %rdx # val.high -> edx 172 | wrmsr 173 | retq 174 | 175 | -------------------------------------------------------------------------------- /boot/x86_64/entry64.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckkashyap/rustix/a7df7bb1e2b88993f9e6d0d2f550fe2a8fa8c0e2/boot/x86_64/entry64.o -------------------------------------------------------------------------------- /boot/x86_64/entryother: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckkashyap/rustix/a7df7bb1e2b88993f9e6d0d2f550fe2a8fa8c0e2/boot/x86_64/entryother -------------------------------------------------------------------------------- /boot/x86_64/entryother.S: -------------------------------------------------------------------------------- 1 | #include "asm.h" 2 | #include "memlayout.h" 3 | #include "mmu.h" 4 | 5 | # Each non-boot CPU ("AP") is started up in response to a STARTUP 6 | # IPI from the boot CPU. Section B.4.2 of the Multi-Processor 7 | # Specification says that the AP will start in real mode with CS:IP 8 | # set to XY00:0000, where XY is an 8-bit value sent with the 9 | # STARTUP. Thus this code must start at a 4096-byte boundary. 10 | # 11 | # Because this code sets DS to zero, it must sit 12 | # at an address in the low 2^16 bytes. 13 | # 14 | # Startothers (in main.c) sends the STARTUPs one at a time. 15 | # It copies this code (start) at 0x7000. It puts the address of 16 | # a newly allocated per-core stack in start-4,the address of the 17 | # place to jump to (mpenter) in start-8, and the physical address 18 | # of entrypgdir in start-12. 19 | # 20 | # This code is identical to bootasm.S except: 21 | # - it does not need to enable A20 22 | # - it uses the address at start-4, start-8, and start-12 23 | 24 | .code16 25 | .globl start 26 | start: 27 | cli 28 | 29 | xorw %ax,%ax 30 | movw %ax,%ds 31 | movw %ax,%es 32 | movw %ax,%ss 33 | 34 | lgdt gdtdesc 35 | movl %cr0, %eax 36 | orl $CR0_PE, %eax 37 | movl %eax, %cr0 38 | 39 | //PAGEBREAK! 40 | ljmpl $(SEG_KCODE<<3), $(start32) 41 | 42 | .code32 43 | start32: 44 | movw $(SEG_KDATA<<3), %ax 45 | movw %ax, %ds 46 | movw %ax, %es 47 | movw %ax, %ss 48 | movw $0, %ax 49 | movw %ax, %fs 50 | movw %ax, %gs 51 | 52 | #if X64 53 | # defer paging until we switch to 64bit mode 54 | # set ebx=1 so shared boot code knows we're booting a secondary core 55 | mov $1, %ebx 56 | #else 57 | # Turn on page size extension for 4Mbyte pages 58 | movl %cr4, %eax 59 | orl $(CR4_PSE), %eax 60 | movl %eax, %cr4 61 | # Use enterpgdir as our initial page table 62 | movl (start-12), %eax 63 | movl %eax, %cr3 64 | # Turn on paging. 65 | movl %cr0, %eax 66 | orl $(CR0_PE|CR0_PG|CR0_WP), %eax 67 | movl %eax, %cr0 68 | #endif 69 | 70 | # Switch to the stack allocated by startothers() 71 | movl (start-4), %esp 72 | # Call mpenter() 73 | call *(start-8) 74 | 75 | movw $0x8a00, %ax 76 | movw %ax, %dx 77 | outw %ax, %dx 78 | movw $0x8ae0, %ax 79 | outw %ax, %dx 80 | spin: 81 | jmp spin 82 | 83 | .p2align 2 84 | gdt: 85 | SEG_NULLASM 86 | SEG_ASM(STA_X|STA_R, 0, 0xffffffff) 87 | SEG_ASM(STA_W, 0, 0xffffffff) 88 | 89 | 90 | gdtdesc: 91 | .word (gdtdesc - gdt - 1) 92 | .long gdt 93 | 94 | -------------------------------------------------------------------------------- /boot/x86_64/include/asm.h: -------------------------------------------------------------------------------- 1 | // 2 | // assembler macros to create x86 segments 3 | // 4 | 5 | #define SEG_NULLASM \ 6 | .word 0, 0; \ 7 | .byte 0, 0, 0, 0 8 | 9 | // The 0xC0 means the limit is in 4096-byte units 10 | // and (for executable segments) 32-bit mode. 11 | #define SEG_ASM(type,base,lim) \ 12 | .word (((lim) >> 12) & 0xffff), ((base) & 0xffff); \ 13 | .byte (((base) >> 16) & 0xff), (0x90 | (type)), \ 14 | (0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff) 15 | 16 | #define STA_X 0x8 // Executable segment 17 | #define STA_E 0x4 // Expand down (non-executable segments) 18 | #define STA_C 0x4 // Conforming code segment (executable only) 19 | #define STA_W 0x2 // Writeable (non-executable segments) 20 | #define STA_R 0x2 // Readable (executable segments) 21 | #define STA_A 0x1 // Accessed 22 | -------------------------------------------------------------------------------- /boot/x86_64/include/defs.h: -------------------------------------------------------------------------------- 1 | struct buf; 2 | struct context; 3 | struct file; 4 | struct inode; 5 | struct pipe; 6 | struct proc; 7 | struct spinlock; 8 | struct stat; 9 | struct superblock; 10 | 11 | // bio.c 12 | void binit(void); 13 | struct buf* bread(uint, uint); 14 | void brelse(struct buf*); 15 | void bwrite(struct buf*); 16 | 17 | // console.c 18 | void consoleinit(void); 19 | void cprintf(char*, ...); 20 | void consoleintr(int(*)(void)); 21 | void panic(char*) __attribute__((noreturn)); 22 | 23 | // exec.c 24 | int exec(char*, char**); 25 | 26 | // file.c 27 | struct file* filealloc(void); 28 | void fileclose(struct file*); 29 | struct file* filedup(struct file*); 30 | void fileinit(void); 31 | int fileread(struct file*, char*, int n); 32 | int filestat(struct file*, struct stat*); 33 | int filewrite(struct file*, char*, int n); 34 | 35 | // fs.c 36 | void readsb(int dev, struct superblock *sb); 37 | int dirlink(struct inode*, char*, uint); 38 | struct inode* dirlookup(struct inode*, char*, uint*); 39 | struct inode* ialloc(uint, short); 40 | struct inode* idup(struct inode*); 41 | void iinit(void); 42 | void ilock(struct inode*); 43 | void iput(struct inode*); 44 | void iunlock(struct inode*); 45 | void iunlockput(struct inode*); 46 | void iupdate(struct inode*); 47 | int namecmp(const char*, const char*); 48 | struct inode* namei(char*); 49 | struct inode* nameiparent(char*, char*); 50 | int readi(struct inode*, char*, uint, uint); 51 | void stati(struct inode*, struct stat*); 52 | int writei(struct inode*, char*, uint, uint); 53 | 54 | // ide.c 55 | void ideinit(void); 56 | void ideintr(void); 57 | void iderw(struct buf*); 58 | 59 | // ioapic.c 60 | void ioapicenable(int irq, int cpu); 61 | extern uchar ioapicid; 62 | void ioapicinit(void); 63 | 64 | // kalloc.c 65 | char* kalloc(void); 66 | void kfree(char*); 67 | void kinit1(void*, void*); 68 | void kinit2(void*, void*); 69 | 70 | // kbd.c 71 | void kbdintr(void); 72 | 73 | // lapic.c 74 | int cpunum(void); 75 | extern volatile uint* lapic; 76 | void lapiceoi(void); 77 | void lapicinit(void); 78 | void lapicstartap(uchar, uint); 79 | void microdelay(int); 80 | 81 | // log.c 82 | void initlog(void); 83 | void log_write(struct buf*); 84 | void begin_trans(); 85 | void commit_trans(); 86 | 87 | // mp.c 88 | extern int ismp; 89 | int mpbcpu(void); 90 | void mpinit(void); 91 | void mpstartthem(void); 92 | 93 | // apic.c 94 | int acpiinit(void); 95 | 96 | // picirq.c 97 | void picenable(int); 98 | void picinit(void); 99 | 100 | // pipe.c 101 | int pipealloc(struct file**, struct file**); 102 | void pipeclose(struct pipe*, int); 103 | int piperead(struct pipe*, char*, int); 104 | int pipewrite(struct pipe*, char*, int); 105 | 106 | //PAGEBREAK: 16 107 | // proc.c 108 | struct proc* copyproc(struct proc*); 109 | void exit(void); 110 | int fork(void); 111 | int growproc(int); 112 | int kill(int); 113 | void pinit(void); 114 | void procdump(void); 115 | void scheduler(void) __attribute__((noreturn)); 116 | void sched(void); 117 | void sleep(void*, struct spinlock*); 118 | void userinit(void); 119 | int wait(void); 120 | void wakeup(void*); 121 | void yield(void); 122 | 123 | // swtch.S 124 | void swtch(struct context**, struct context*); 125 | 126 | // spinlock.c 127 | void acquire(struct spinlock*); 128 | void getcallerpcs(void*, uintp*); 129 | void getstackpcs(uintp*, uintp*); 130 | int holding(struct spinlock*); 131 | void initlock(struct spinlock*, char*); 132 | void release(struct spinlock*); 133 | void pushcli(void); 134 | void popcli(void); 135 | 136 | // string.c 137 | int memcmp(const void*, const void*, uint); 138 | void* memmove(void*, const void*, uint); 139 | void* memset(void*, int, uint); 140 | char* safestrcpy(char*, const char*, int); 141 | int strlen(const char*); 142 | int strncmp(const char*, const char*, uint); 143 | char* strncpy(char*, const char*, int); 144 | 145 | // syscall.c 146 | int argint(int, int*); 147 | int argptr(int, char**, int); 148 | int argstr(int, char**); 149 | int arguintp(int, uintp*); 150 | int fetchuintp(uintp, uintp*); 151 | int fetchstr(uintp, char**); 152 | void syscall(void); 153 | 154 | // timer.c 155 | void timerinit(void); 156 | 157 | // trap.c 158 | void idtinit(void); 159 | extern uint ticks; 160 | void tvinit(void); 161 | extern struct spinlock tickslock; 162 | 163 | // uart.c 164 | void uartearlyinit(void); 165 | void uartinit(void); 166 | void uartintr(void); 167 | void uartputc(int); 168 | 169 | // vm.c 170 | void seginit(void); 171 | void kvmalloc(void); 172 | void vmenable(void); 173 | pde_t* setupkvm(void); 174 | char* uva2ka(pde_t*, char*); 175 | int allocuvm(pde_t*, uint, uint); 176 | int deallocuvm(pde_t*, uintp, uintp); 177 | void freevm(pde_t*); 178 | void inituvm(pde_t*, char*, uint); 179 | int loaduvm(pde_t*, char*, struct inode*, uint, uint); 180 | pde_t* copyuvm(pde_t*, uint); 181 | void switchuvm(struct proc*); 182 | void switchkvm(void); 183 | int copyout(pde_t*, uint, void*, uint); 184 | void clearpteu(pde_t *pgdir, char *uva); 185 | 186 | // number of elements in fixed-size array 187 | #define NELEM(x) (sizeof(x)/sizeof((x)[0])) 188 | -------------------------------------------------------------------------------- /boot/x86_64/include/memlayout.h: -------------------------------------------------------------------------------- 1 | // Memory layout 2 | 3 | #define EXTMEM 0x100000 // Start of extended memory 4 | #define PHYSTOP 0xE000000 // Top physical memory 5 | #define DEVSPACE 0xFE000000 // Other devices are at high addresses 6 | 7 | // Key addresses for address space layout (see kmap in vm.c for layout) 8 | #if X64 9 | #define KERNBASE 0xFFFFFFFF80000000 // First kernel virtual address 10 | #define DEVBASE 0xFFFFFFFF40000000 // First device virtual address 11 | #else 12 | #define KERNBASE 0x80000000 // First kernel virtual address 13 | #define DEVBASE 0xFE000000 // First device virtual address 14 | #endif 15 | #define KERNLINK (KERNBASE+EXTMEM) // Address where kernel is linked 16 | 17 | #ifndef __ASSEMBLER__ 18 | 19 | static inline uintp v2p(void *a) { return ((uintp) (a)) - ((uintp)KERNBASE); } 20 | static inline void *p2v(uintp a) { return (void *) ((a) + ((uintp)KERNBASE)); } 21 | 22 | #endif 23 | 24 | #define V2P(a) (((uintp) (a)) - KERNBASE) 25 | #define P2V(a) (((void *) (a)) + KERNBASE) 26 | #define IO2V(a) (((void *) (a)) + DEVBASE - DEVSPACE) 27 | 28 | #define V2P_WO(x) ((x) - KERNBASE) // same as V2P, but without casts 29 | #define P2V_WO(x) ((x) + KERNBASE) // same as V2P, but without casts 30 | -------------------------------------------------------------------------------- /boot/x86_64/include/mmu.h: -------------------------------------------------------------------------------- 1 | // This file contains definitions for the 2 | // x86 memory management unit (MMU). 3 | 4 | // Eflags register 5 | #define FL_CF 0x00000001 // Carry Flag 6 | #define FL_PF 0x00000004 // Parity Flag 7 | #define FL_AF 0x00000010 // Auxiliary carry Flag 8 | #define FL_ZF 0x00000040 // Zero Flag 9 | #define FL_SF 0x00000080 // Sign Flag 10 | #define FL_TF 0x00000100 // Trap Flag 11 | #define FL_IF 0x00000200 // Interrupt Enable 12 | #define FL_DF 0x00000400 // Direction Flag 13 | #define FL_OF 0x00000800 // Overflow Flag 14 | #define FL_IOPL_MASK 0x00003000 // I/O Privilege Level bitmask 15 | #define FL_IOPL_0 0x00000000 // IOPL == 0 16 | #define FL_IOPL_1 0x00001000 // IOPL == 1 17 | #define FL_IOPL_2 0x00002000 // IOPL == 2 18 | #define FL_IOPL_3 0x00003000 // IOPL == 3 19 | #define FL_NT 0x00004000 // Nested Task 20 | #define FL_RF 0x00010000 // Resume Flag 21 | #define FL_VM 0x00020000 // Virtual 8086 mode 22 | #define FL_AC 0x00040000 // Alignment Check 23 | #define FL_VIF 0x00080000 // Virtual Interrupt Flag 24 | #define FL_VIP 0x00100000 // Virtual Interrupt Pending 25 | #define FL_ID 0x00200000 // ID flag 26 | 27 | // Control Register flags 28 | #define CR0_PE 0x00000001 // Protection Enable 29 | #define CR0_MP 0x00000002 // Monitor coProcessor 30 | #define CR0_EM 0x00000004 // Emulation 31 | #define CR0_TS 0x00000008 // Task Switched 32 | #define CR0_ET 0x00000010 // Extension Type 33 | #define CR0_NE 0x00000020 // Numeric Errror 34 | #define CR0_WP 0x00010000 // Write Protect 35 | #define CR0_AM 0x00040000 // Alignment Mask 36 | #define CR0_NW 0x20000000 // Not Writethrough 37 | #define CR0_CD 0x40000000 // Cache Disable 38 | #define CR0_PG 0x80000000 // Paging 39 | 40 | #define CR4_PSE 0x00000010 // Page size extension 41 | 42 | #define SEG_KCODE 1 // kernel code 43 | #define SEG_KDATA 2 // kernel data+stack 44 | #define SEG_KCPU 3 // kernel per-cpu data 45 | #define SEG_UCODE 4 // user code 46 | #define SEG_UDATA 5 // user data+stack 47 | #define SEG_TSS 6 // this process's task state 48 | 49 | //PAGEBREAK! 50 | #ifndef __ASSEMBLER__ 51 | // Segment Descriptor 52 | struct segdesc { 53 | uint lim_15_0 : 16; // Low bits of segment limit 54 | uint base_15_0 : 16; // Low bits of segment base address 55 | uint base_23_16 : 8; // Middle bits of segment base address 56 | uint type : 4; // Segment type (see STS_ constants) 57 | uint s : 1; // 0 = system, 1 = application 58 | uint dpl : 2; // Descriptor Privilege Level 59 | uint p : 1; // Present 60 | uint lim_19_16 : 4; // High bits of segment limit 61 | uint avl : 1; // Unused (available for software use) 62 | uint rsv1 : 1; // Reserved 63 | uint db : 1; // 0 = 16-bit segment, 1 = 32-bit segment 64 | uint g : 1; // Granularity: limit scaled by 4K when set 65 | uint base_31_24 : 8; // High bits of segment base address 66 | }; 67 | 68 | // Normal segment 69 | #define SEG(type, base, lim, dpl) (struct segdesc) \ 70 | { ((lim) >> 12) & 0xffff, (uint)(base) & 0xffff, \ 71 | ((uintp)(base) >> 16) & 0xff, type, 1, dpl, 1, \ 72 | (uintp)(lim) >> 28, 0, 0, 1, 1, (uintp)(base) >> 24 } 73 | #define SEG16(type, base, lim, dpl) (struct segdesc) \ 74 | { (lim) & 0xffff, (uintp)(base) & 0xffff, \ 75 | ((uintp)(base) >> 16) & 0xff, type, 1, dpl, 1, \ 76 | (uintp)(lim) >> 16, 0, 0, 1, 0, (uintp)(base) >> 24 } 77 | #endif 78 | 79 | #define DPL_USER 0x3 // User DPL 80 | 81 | // Application segment type bits 82 | #define STA_X 0x8 // Executable segment 83 | #define STA_E 0x4 // Expand down (non-executable segments) 84 | #define STA_C 0x4 // Conforming code segment (executable only) 85 | #define STA_W 0x2 // Writeable (non-executable segments) 86 | #define STA_R 0x2 // Readable (executable segments) 87 | #define STA_A 0x1 // Accessed 88 | 89 | // System segment type bits 90 | #define STS_T16A 0x1 // Available 16-bit TSS 91 | #define STS_LDT 0x2 // Local Descriptor Table 92 | #define STS_T16B 0x3 // Busy 16-bit TSS 93 | #define STS_CG16 0x4 // 16-bit Call Gate 94 | #define STS_TG 0x5 // Task Gate / Coum Transmitions 95 | #define STS_IG16 0x6 // 16-bit Interrupt Gate 96 | #define STS_TG16 0x7 // 16-bit Trap Gate 97 | #define STS_T32A 0x9 // Available 32-bit TSS 98 | #define STS_T32B 0xB // Busy 32-bit TSS 99 | #define STS_CG32 0xC // 32-bit Call Gate 100 | #define STS_IG32 0xE // 32-bit Interrupt Gate 101 | #define STS_TG32 0xF // 32-bit Trap Gate 102 | 103 | // A virtual address 'la' has a three-part structure as follows: 104 | // 105 | // +--------10------+-------10-------+---------12----------+ 106 | // | Page Directory | Page Table | Offset within Page | 107 | // | Index | Index | | 108 | // +----------------+----------------+---------------------+ 109 | // \--- PDX(va) --/ \--- PTX(va) --/ 110 | 111 | // page directory index 112 | #define PDX(va) (((uintp)(va) >> PDXSHIFT) & PXMASK) 113 | 114 | // page table index 115 | #define PTX(va) (((uintp)(va) >> PTXSHIFT) & PXMASK) 116 | 117 | // construct virtual address from indexes and offset 118 | #define PGADDR(d, t, o) ((uintp)((d) << PDXSHIFT | (t) << PTXSHIFT | (o))) 119 | 120 | // Page directory and page table constants. 121 | #if X64 122 | #define NPDENTRIES 512 // # directory entries per page directory 123 | #define NPTENTRIES 512 // # PTEs per page table 124 | #define PGSIZE 4096 // bytes mapped by a page 125 | 126 | #define PGSHIFT 12 // log2(PGSIZE) 127 | #define PTXSHIFT 12 // offset of PTX in a linear address 128 | #define PDXSHIFT 21 // offset of PDX in a linear address 129 | 130 | #define PXMASK 0x1FF 131 | #else 132 | #define NPDENTRIES 1024 // # directory entries per page directory 133 | #define NPTENTRIES 1024 // # PTEs per page table 134 | #define PGSIZE 4096 // bytes mapped by a page 135 | 136 | #define PGSHIFT 12 // log2(PGSIZE) 137 | #define PTXSHIFT 12 // offset of PTX in a linear address 138 | #define PDXSHIFT 22 // offset of PDX in a linear address 139 | 140 | #define PXMASK 0x3FF 141 | #endif 142 | 143 | #define PGROUNDUP(sz) (((sz)+((uintp)PGSIZE-1)) & ~((uintp)(PGSIZE-1))) 144 | #define PGROUNDDOWN(a) (((a)) & ~((uintp)(PGSIZE-1))) 145 | 146 | // Page table/directory entry flags. 147 | #define PTE_P 0x001 // Present 148 | #define PTE_W 0x002 // Writeable 149 | #define PTE_U 0x004 // User 150 | #define PTE_PWT 0x008 // Write-Through 151 | #define PTE_PCD 0x010 // Cache-Disable 152 | #define PTE_A 0x020 // Accessed 153 | #define PTE_D 0x040 // Dirty 154 | #define PTE_PS 0x080 // Page Size 155 | #define PTE_MBZ 0x180 // Bits must be zero 156 | 157 | // Address in page table or page directory entry 158 | #define PTE_ADDR(pte) ((uintp)(pte) & ~0xFFF) 159 | #define PTE_FLAGS(pte) ((uintp)(pte) & 0xFFF) 160 | 161 | #ifndef __ASSEMBLER__ 162 | typedef uintp pte_t; 163 | 164 | // Task state segment format 165 | struct taskstate { 166 | uint link; // Old ts selector 167 | uint esp0; // Stack pointers and segment selectors 168 | ushort ss0; // after an increase in privilege level 169 | ushort padding1; 170 | uint *esp1; 171 | ushort ss1; 172 | ushort padding2; 173 | uint *esp2; 174 | ushort ss2; 175 | ushort padding3; 176 | void *cr3; // Page directory base 177 | uint *eip; // Saved state from last task switch 178 | uint eflags; 179 | uint eax; // More saved state (registers) 180 | uint ecx; 181 | uint edx; 182 | uint ebx; 183 | uint *esp; 184 | uint *ebp; 185 | uint esi; 186 | uint edi; 187 | ushort es; // Even more saved state (segment selectors) 188 | ushort padding4; 189 | ushort cs; 190 | ushort padding5; 191 | ushort ss; 192 | ushort padding6; 193 | ushort ds; 194 | ushort padding7; 195 | ushort fs; 196 | ushort padding8; 197 | ushort gs; 198 | ushort padding9; 199 | ushort ldt; 200 | ushort padding10; 201 | ushort t; // Trap on task switch 202 | ushort iomb; // I/O map base address 203 | }; 204 | 205 | // PAGEBREAK: 12 206 | // Gate descriptors for interrupts and traps 207 | struct gatedesc { 208 | uint off_15_0 : 16; // low 16 bits of offset in segment 209 | uint cs : 16; // code segment selector 210 | uint args : 5; // # args, 0 for interrupt/trap gates 211 | uint rsv1 : 3; // reserved(should be zero I guess) 212 | uint type : 4; // type(STS_{TG,IG32,TG32}) 213 | uint s : 1; // must be 0 (system) 214 | uint dpl : 2; // descriptor(meaning new) privilege level 215 | uint p : 1; // Present 216 | uint off_31_16 : 16; // high bits of offset in segment 217 | }; 218 | 219 | // Set up a normal interrupt/trap gate descriptor. 220 | // - istrap: 1 for a trap (= exception) gate, 0 for an interrupt gate. 221 | // interrupt gate clears FL_IF, trap gate leaves FL_IF alone 222 | // - sel: Code segment selector for interrupt/trap handler 223 | // - off: Offset in code segment for interrupt/trap handler 224 | // - dpl: Descriptor Privilege Level - 225 | // the privilege level required for software to invoke 226 | // this interrupt/trap gate explicitly using an int instruction. 227 | #define SETGATE(gate, istrap, sel, off, d) \ 228 | { \ 229 | (gate).off_15_0 = (uint)(off) & 0xffff; \ 230 | (gate).cs = (sel); \ 231 | (gate).args = 0; \ 232 | (gate).rsv1 = 0; \ 233 | (gate).type = (istrap) ? STS_TG32 : STS_IG32; \ 234 | (gate).s = 0; \ 235 | (gate).dpl = (d); \ 236 | (gate).p = 1; \ 237 | (gate).off_31_16 = (uint)(off) >> 16; \ 238 | } 239 | 240 | #endif 241 | -------------------------------------------------------------------------------- /boot/x86_64/include/param.h: -------------------------------------------------------------------------------- 1 | #define NPROC 64 // maximum number of processes 2 | #define KSTACKSIZE 4096 // size of per-process kernel stack 3 | #define NCPU 8 // maximum number of CPUs 4 | #define NOFILE 16 // open files per process 5 | #define NFILE 100 // open files per system 6 | #define NBUF 10 // size of disk block cache 7 | #define NINODE 50 // maximum number of active i-nodes 8 | #define NDEV 10 // maximum major device number 9 | #define ROOTDEV 1 // device number of file system root disk 10 | #define MAXARG 32 // max exec arguments 11 | #define LOGSIZE 10 // max data sectors in on-disk log 12 | 13 | -------------------------------------------------------------------------------- /boot/x86_64/include/proc.h: -------------------------------------------------------------------------------- 1 | // Segments in proc->gdt. 2 | #define NSEGS 7 3 | 4 | // Per-CPU state 5 | struct cpu { 6 | uchar id; // index into cpus[] below 7 | uchar apicid; // Local APIC ID 8 | struct context *scheduler; // swtch() here to enter scheduler 9 | struct taskstate ts; // Used by x86 to find stack for interrupt 10 | struct segdesc gdt[NSEGS]; // x86 global descriptor table 11 | volatile uint started; // Has the CPU started? 12 | int ncli; // Depth of pushcli nesting. 13 | int intena; // Were interrupts enabled before pushcli? 14 | 15 | // Cpu-local storage variables; see below 16 | #if X64 17 | void *local; 18 | #else 19 | struct cpu *cpu; 20 | struct proc *proc; // The currently-running process. 21 | #endif 22 | }; 23 | 24 | extern struct cpu cpus[NCPU]; 25 | extern int ncpu; 26 | 27 | // Per-CPU variables, holding pointers to the 28 | // current cpu and to the current process. 29 | // The asm suffix tells gcc to use "%gs:0" to refer to cpu 30 | // and "%gs:4" to refer to proc. seginit sets up the 31 | // %gs segment register so that %gs refers to the memory 32 | // holding those two variables in the local cpu's struct cpu. 33 | // This is similar to how thread-local variables are implemented 34 | // in thread libraries such as Linux pthreads. 35 | #if X64 36 | extern __thread struct cpu *cpu; 37 | extern __thread struct proc *proc; 38 | #else 39 | extern struct cpu *cpu asm("%gs:0"); // &cpus[cpunum()] 40 | extern struct proc *proc asm("%gs:4"); // cpus[cpunum()].proc 41 | #endif 42 | 43 | //PAGEBREAK: 17 44 | // Saved registers for kernel context switches. 45 | // Don't need to save all the segment registers (%cs, etc), 46 | // because they are constant across kernel contexts. 47 | // Don't need to save %eax, %ecx, %edx, because the 48 | // x86 convention is that the caller has saved them. 49 | // Contexts are stored at the bottom of the stack they 50 | // describe; the stack pointer is the address of the context. 51 | // The layout of the context matches the layout of the stack in swtch.S 52 | // at the "Switch stacks" comment. Switch doesn't save eip explicitly, 53 | // but it is on the stack and allocproc() manipulates it. 54 | #if X64 55 | struct context { 56 | uintp r15; 57 | uintp r14; 58 | uintp r13; 59 | uintp r12; 60 | uintp r11; 61 | uintp rbx; 62 | uintp ebp; //rbp 63 | uintp eip; //rip; 64 | }; 65 | #else 66 | struct context { 67 | uintp edi; 68 | uintp esi; 69 | uintp ebx; 70 | uintp ebp; 71 | uintp eip; 72 | }; 73 | #endif 74 | 75 | enum procstate { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE }; 76 | 77 | // Per-process state 78 | struct proc { 79 | uintp sz; // Size of process memory (bytes) 80 | pde_t* pgdir; // Page table 81 | char *kstack; // Bottom of kernel stack for this process 82 | enum procstate state; // Process state 83 | volatile int pid; // Process ID 84 | struct proc *parent; // Parent process 85 | struct trapframe *tf; // Trap frame for current syscall 86 | struct context *context; // swtch() here to run process 87 | void *chan; // If non-zero, sleeping on chan 88 | int killed; // If non-zero, have been killed 89 | struct file *ofile[NOFILE]; // Open files 90 | struct inode *cwd; // Current directory 91 | char name[16]; // Process name (debugging) 92 | }; 93 | 94 | // Process memory is laid out contiguously, low addresses first: 95 | // text 96 | // original data and bss 97 | // fixed-size stack 98 | // expandable heap 99 | -------------------------------------------------------------------------------- /boot/x86_64/include/syscall.h: -------------------------------------------------------------------------------- 1 | // System call numbers 2 | #define SYS_fork 1 3 | #define SYS_exit 2 4 | #define SYS_wait 3 5 | #define SYS_pipe 4 6 | #define SYS_read 5 7 | #define SYS_kill 6 8 | #define SYS_exec 7 9 | #define SYS_fstat 8 10 | #define SYS_chdir 9 11 | #define SYS_dup 10 12 | #define SYS_getpid 11 13 | #define SYS_sbrk 12 14 | #define SYS_sleep 13 15 | #define SYS_uptime 14 16 | #define SYS_open 15 17 | #define SYS_write 16 18 | #define SYS_mknod 17 19 | #define SYS_unlink 18 20 | #define SYS_link 19 21 | #define SYS_mkdir 20 22 | #define SYS_close 21 23 | -------------------------------------------------------------------------------- /boot/x86_64/include/traps.h: -------------------------------------------------------------------------------- 1 | // x86 trap and interrupt constants. 2 | 3 | // Processor-defined: 4 | #define T_DIVIDE 0 // divide error 5 | #define T_DEBUG 1 // debug exception 6 | #define T_NMI 2 // non-maskable interrupt 7 | #define T_BRKPT 3 // breakpoint 8 | #define T_OFLOW 4 // overflow 9 | #define T_BOUND 5 // bounds check 10 | #define T_ILLOP 6 // illegal opcode 11 | #define T_DEVICE 7 // device not available 12 | #define T_DBLFLT 8 // double fault 13 | // #define T_COPROC 9 // reserved (not used since 486) 14 | #define T_TSS 10 // invalid task switch segment 15 | #define T_SEGNP 11 // segment not present 16 | #define T_STACK 12 // stack exception 17 | #define T_GPFLT 13 // general protection fault 18 | #define T_PGFLT 14 // page fault 19 | // #define T_RES 15 // reserved 20 | #define T_FPERR 16 // floating point error 21 | #define T_ALIGN 17 // aligment check 22 | #define T_MCHK 18 // machine check 23 | #define T_SIMDERR 19 // SIMD floating point error 24 | 25 | // These are arbitrarily chosen, but with care not to overlap 26 | // processor defined exceptions or interrupt vectors. 27 | #define T_SYSCALL 64 // system call 28 | #define T_DEFAULT 500 // catchall 29 | 30 | #define T_IRQ0 32 // IRQ 0 corresponds to int T_IRQ 31 | 32 | #define IRQ_TIMER 0 33 | #define IRQ_KBD 1 34 | #define IRQ_COM1 4 35 | #define IRQ_IDE 14 36 | #define IRQ_ERROR 19 37 | #define IRQ_SPURIOUS 31 38 | 39 | -------------------------------------------------------------------------------- /boot/x86_64/include/types.h: -------------------------------------------------------------------------------- 1 | typedef unsigned int uint; 2 | typedef unsigned short ushort; 3 | typedef unsigned char uchar; 4 | 5 | typedef unsigned int uint32; 6 | typedef unsigned long uint64; 7 | 8 | #if X64 9 | typedef unsigned long uintp; 10 | #else 11 | typedef unsigned int uintp; 12 | #endif 13 | 14 | typedef uintp pde_t; 15 | -------------------------------------------------------------------------------- /boot/x86_64/include/x86.h: -------------------------------------------------------------------------------- 1 | // Routines to let C code use special x86 instructions. 2 | 3 | static inline uchar 4 | inb(ushort port) 5 | { 6 | uchar data; 7 | 8 | asm volatile("in %1,%0" : "=a" (data) : "d" (port)); 9 | return data; 10 | } 11 | 12 | static inline void 13 | insl(int port, void *addr, int cnt) 14 | { 15 | asm volatile("cld; rep insl" : 16 | "=D" (addr), "=c" (cnt) : 17 | "d" (port), "0" (addr), "1" (cnt) : 18 | "memory", "cc"); 19 | } 20 | 21 | static inline void 22 | outb(ushort port, uchar data) 23 | { 24 | asm volatile("out %0,%1" : : "a" (data), "d" (port)); 25 | } 26 | 27 | static inline void 28 | outw(ushort port, ushort data) 29 | { 30 | asm volatile("out %0,%1" : : "a" (data), "d" (port)); 31 | } 32 | 33 | static inline void 34 | outsl(int port, const void *addr, int cnt) 35 | { 36 | asm volatile("cld; rep outsl" : 37 | "=S" (addr), "=c" (cnt) : 38 | "d" (port), "0" (addr), "1" (cnt) : 39 | "cc"); 40 | } 41 | 42 | static inline void 43 | stosb(void *addr, int data, int cnt) 44 | { 45 | asm volatile("cld; rep stosb" : 46 | "=D" (addr), "=c" (cnt) : 47 | "0" (addr), "1" (cnt), "a" (data) : 48 | "memory", "cc"); 49 | } 50 | 51 | static inline void 52 | stosl(void *addr, int data, int cnt) 53 | { 54 | asm volatile("cld; rep stosl" : 55 | "=D" (addr), "=c" (cnt) : 56 | "0" (addr), "1" (cnt), "a" (data) : 57 | "memory", "cc"); 58 | } 59 | 60 | struct segdesc; 61 | 62 | static inline void 63 | lgdt(struct segdesc *p, int size) 64 | { 65 | volatile ushort pd[5]; 66 | 67 | pd[0] = size-1; 68 | pd[1] = (uintp)p; 69 | pd[2] = (uintp)p >> 16; 70 | #if X64 71 | pd[3] = (uintp)p >> 32; 72 | pd[4] = (uintp)p >> 48; 73 | #endif 74 | asm volatile("lgdt (%0)" : : "r" (pd)); 75 | } 76 | 77 | struct gatedesc; 78 | 79 | static inline void 80 | lidt(struct gatedesc *p, int size) 81 | { 82 | volatile ushort pd[5]; 83 | 84 | pd[0] = size-1; 85 | pd[1] = (uintp)p; 86 | pd[2] = (uintp)p >> 16; 87 | #if X64 88 | pd[3] = (uintp)p >> 32; 89 | pd[4] = (uintp)p >> 48; 90 | #endif 91 | asm volatile("lidt (%0)" : : "r" (pd)); 92 | } 93 | 94 | static inline void 95 | ltr(ushort sel) 96 | { 97 | asm volatile("ltr %0" : : "r" (sel)); 98 | } 99 | 100 | static inline uintp 101 | readeflags(void) 102 | { 103 | uintp eflags; 104 | asm volatile("pushf; pop %0" : "=r" (eflags)); 105 | return eflags; 106 | } 107 | 108 | static inline void 109 | loadgs(ushort v) 110 | { 111 | asm volatile("movw %0, %%gs" : : "r" (v)); 112 | } 113 | 114 | static inline void 115 | cli(void) 116 | { 117 | asm volatile("cli"); 118 | } 119 | 120 | static inline void 121 | sti(void) 122 | { 123 | asm volatile("sti"); 124 | } 125 | 126 | static inline void 127 | hlt(void) 128 | { 129 | asm volatile("hlt"); 130 | } 131 | 132 | static inline uint 133 | xchg(volatile uint *addr, uintp newval) 134 | { 135 | uint result; 136 | 137 | // The + in "+m" denotes a read-modify-write operand. 138 | asm volatile("lock; xchgl %0, %1" : 139 | "+m" (*addr), "=a" (result) : 140 | "1" (newval) : 141 | "cc"); 142 | return result; 143 | } 144 | 145 | static inline uintp 146 | rcr2(void) 147 | { 148 | uintp val; 149 | asm volatile("mov %%cr2,%0" : "=r" (val)); 150 | return val; 151 | } 152 | 153 | static inline void 154 | lcr3(uintp val) 155 | { 156 | asm volatile("mov %0,%%cr3" : : "r" (val)); 157 | } 158 | 159 | //PAGEBREAK: 36 160 | // Layout of the trap frame built on the stack by the 161 | // hardware and by trapasm.S, and passed to trap(). 162 | #if X64 163 | // lie about some register names in 64bit mode to avoid 164 | // clunky ifdefs in proc.c and trap.c. 165 | struct trapframe { 166 | uint64 eax; // rax 167 | uint64 rbx; 168 | uint64 rcx; 169 | uint64 rdx; 170 | uint64 rbp; 171 | uint64 rsi; 172 | uint64 rdi; 173 | uint64 r8; 174 | uint64 r9; 175 | uint64 r10; 176 | uint64 r11; 177 | uint64 r12; 178 | uint64 r13; 179 | uint64 r14; 180 | uint64 r15; 181 | 182 | uint64 trapno; 183 | uint64 err; 184 | 185 | uint64 eip; // rip 186 | uint64 cs; 187 | uint64 eflags; // rflags 188 | uint64 esp; // rsp 189 | uint64 ds; // ss 190 | }; 191 | #else 192 | struct trapframe { 193 | // registers as pushed by pusha 194 | uint edi; 195 | uint esi; 196 | uint ebp; 197 | uint oesp; // useless & ignored 198 | uint ebx; 199 | uint edx; 200 | uint ecx; 201 | uint eax; 202 | 203 | // rest of trap frame 204 | ushort gs; 205 | ushort padding1; 206 | ushort fs; 207 | ushort padding2; 208 | ushort es; 209 | ushort padding3; 210 | ushort ds; 211 | ushort padding4; 212 | uint trapno; 213 | 214 | // below here defined by x86 hardware 215 | uint err; 216 | uint eip; 217 | ushort cs; 218 | ushort padding5; 219 | uint eflags; 220 | 221 | // below here only when crossing rings, such as from user to kernel 222 | uint esp; 223 | ushort ss; 224 | ushort padding6; 225 | }; 226 | #endif 227 | -------------------------------------------------------------------------------- /boot/x86_64/initcode: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckkashyap/rustix/a7df7bb1e2b88993f9e6d0d2f550fe2a8fa8c0e2/boot/x86_64/initcode -------------------------------------------------------------------------------- /boot/x86_64/initcode64.S: -------------------------------------------------------------------------------- 1 | # Initial process execs /init. 2 | 3 | #include "syscall.h" 4 | #include "traps.h" 5 | 6 | 7 | # exec(init, argv) 8 | .globl start 9 | start: 10 | mov $init, %rdi 11 | mov $argv, %rsi 12 | mov $SYS_exec, %rax 13 | int $T_SYSCALL 14 | 15 | # for(;;) exit(); 16 | exit: 17 | mov $SYS_exit, %rax 18 | int $T_SYSCALL 19 | jmp exit 20 | 21 | # char init[] = "/init\0"; 22 | init: 23 | .string "/init\0" 24 | 25 | # char *argv[] = { init, 0 }; 26 | .p2align 2 27 | argv: 28 | .quad init 29 | .quad 0 30 | 31 | -------------------------------------------------------------------------------- /boot/x86_64/kernel64.ld: -------------------------------------------------------------------------------- 1 | /* Simple linker script for the JOS kernel. 2 | See the GNU ld 'info' manual ("info ld") to learn the syntax. */ 3 | 4 | /* OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") */ 5 | OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") 6 | OUTPUT_ARCH(i386:x86-64) 7 | ENTRY(_start) 8 | 9 | mboot_load_addr = 0x00100000; 10 | 11 | SECTIONS 12 | { 13 | /* Link the kernel at this address: "." means the current address */ 14 | /* Must be equal to KERNLINK */ 15 | . = 0xFFFFFFFF80100000; 16 | 17 | PROVIDE(begin = .); 18 | 19 | .text : AT(mboot_load_addr) { 20 | *(.text .rela.text .stub .text.* .gnu.linkonce.t.*) 21 | } 22 | 23 | PROVIDE(etext = .); /* Define the 'etext' symbol to this value */ 24 | 25 | .rodata : { 26 | *(.rodata .rodata.* .gnu.linkonce.r.*) 27 | } 28 | 29 | /* Adjust the address for the data segment to the next page */ 30 | . = ALIGN(0x1000); 31 | 32 | /* Conventionally, Unix linkers provide pseudo-symbols 33 | * etext, edata, and end, at the end of the text, data, and bss. 34 | * For the kernel mapping, we need the address at the beginning 35 | * of the data section, but that's not one of the conventional 36 | * symbols, because the convention started before there was a 37 | * read-only rodata section between text and data. */ 38 | PROVIDE(data = .); 39 | 40 | /* The data segment */ 41 | .data : { 42 | *(.data) 43 | } 44 | 45 | . = ALIGN(0x1000); 46 | 47 | PROVIDE(edata = .); 48 | 49 | .bss : { 50 | *(.bss) 51 | *(COMMON) 52 | } 53 | 54 | . = ALIGN(0x1000); 55 | 56 | PROVIDE(end = .); 57 | 58 | /DISCARD/ : { 59 | *(.eh_frame .rela.eh_frame .note.GNU-stack) 60 | } 61 | } 62 | 63 | mboot_load_end = mboot_load_addr + (edata - begin); 64 | mboot_bss_end = mboot_load_addr + (end - begin); 65 | mboot_entry_addr = mboot_load_addr + (mboot_entry - begin); 66 | -------------------------------------------------------------------------------- /boot/x86_64/main.c: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | #include "defs.h" 3 | #include "param.h" 4 | #include "memlayout.h" 5 | #include "mmu.h" 6 | #include "proc.h" 7 | #include "x86.h" 8 | 9 | static void startothers(void); 10 | static void mpmain(void) __attribute__((noreturn)); 11 | extern pde_t *kpgdir; 12 | extern char end[]; // first address after kernel loaded from ELF file 13 | 14 | void* memset(void* a, int b , unsigned int c){ 15 | return (void *)0; 16 | } 17 | 18 | // Bootstrap processor starts running C code here. 19 | // Allocate a real stack and switch to it, first 20 | // doing some setup required for memory allocator to work. 21 | int 22 | main(void) 23 | { 24 | #if 0 25 | uartearlyinit(); 26 | kinit1(end, P2V(4*1024*1024)); // phys page allocator 27 | kvmalloc(); // kernel page table 28 | if (acpiinit()) // try to use acpi for machine info 29 | mpinit(); // otherwise use bios MP tables 30 | lapicinit(); 31 | seginit(); // set up segments 32 | cprintf("\ncpu%d: starting xv6\n\n", cpu->id); 33 | picinit(); // interrupt controller 34 | ioapicinit(); // another interrupt controller 35 | consoleinit(); // I/O devices & their interrupts 36 | uartinit(); // serial port 37 | pinit(); // process table 38 | tvinit(); // trap vectors 39 | binit(); // buffer cache 40 | fileinit(); // file table 41 | iinit(); // inode cache 42 | ideinit(); // disk 43 | if(!ismp) 44 | timerinit(); // uniprocessor timer 45 | startothers(); // start other processors 46 | kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers() 47 | userinit(); // first user process 48 | // Finish setting up this processor in mpmain. 49 | mpmain(); 50 | #endif 51 | int i; 52 | char *screen=(char*)0xb8000; 53 | char ch = 'A'; 54 | char cl[] = {0x1f, 0x0e, 0x4f}; 55 | int ci=0; 56 | void *endAddress = (void *)end; 57 | cmain(endAddress); 58 | while(1) { 59 | ch='A'; 60 | for (i=0;i<4000;i+=2){ 61 | screen[i]=ch; 62 | ch++; 63 | if(ch>'Z')ch='A'; 64 | screen[i+1]=cl[ci]; 65 | } 66 | ci++; 67 | if(ci==3)ci=0; 68 | } 69 | } 70 | 71 | // Other CPUs jump here from entryother.S. 72 | void 73 | mpenter(void) 74 | { 75 | #if 0 76 | switchkvm(); 77 | seginit(); 78 | lapicinit(); 79 | mpmain(); 80 | #endif 81 | } 82 | 83 | // Common CPU setup code. 84 | static void 85 | mpmain(void) 86 | { 87 | #if 0 88 | cprintf("cpu%d: starting\n", cpu->id); 89 | idtinit(); // load idt register 90 | xchg(&cpu->started, 1); // tell startothers() we're up 91 | scheduler(); // start running processes 92 | #endif 93 | } 94 | 95 | pde_t entrypgdir[]; // For entry.S 96 | void entry32mp(void); 97 | 98 | // Start the non-boot (AP) processors. 99 | static void 100 | startothers(void) 101 | { 102 | #if 0 103 | extern uchar _binary_out_entryother_start[], _binary_out_entryother_size[]; 104 | uchar *code; 105 | struct cpu *c; 106 | char *stack; 107 | 108 | // Write entry code to unused memory at 0x7000. 109 | // The linker has placed the image of entryother.S in 110 | // _binary_entryother_start. 111 | code = p2v(0x7000); 112 | memmove(code, _binary_out_entryother_start, (uintp)_binary_out_entryother_size); 113 | 114 | for(c = cpus; c < cpus+ncpu; c++){ 115 | if(c == cpus+cpunum()) // We've started already. 116 | continue; 117 | 118 | // Tell entryother.S what stack to use, where to enter, and what 119 | // pgdir to use. We cannot use kpgdir yet, because the AP processor 120 | // is running in low memory, so we use entrypgdir for the APs too. 121 | stack = kalloc(); 122 | #if X64 123 | *(uint32*)(code-4) = 0x8000; // just enough stack to get us to entry64mp 124 | *(uint32*)(code-8) = v2p(entry32mp); 125 | *(uint64*)(code-16) = (uint64) (stack + KSTACKSIZE); 126 | #else 127 | *(void**)(code-4) = stack + KSTACKSIZE; 128 | *(void**)(code-8) = mpenter; 129 | *(int**)(code-12) = (void *) v2p(entrypgdir); 130 | #endif 131 | 132 | lapicstartap(c->apicid, v2p(code)); 133 | 134 | // wait for cpu to finish mpmain() 135 | while(c->started == 0) 136 | ; 137 | } 138 | #endif 139 | } 140 | 141 | #ifndef X64 142 | // Boot page table used in entry.S and entryother.S. 143 | // Page directories (and page tables), must start on a page boundary, 144 | // hence the "__aligned__" attribute. 145 | // Use PTE_PS in page directory entry to enable 4Mbyte pages. 146 | __attribute__((__aligned__(PGSIZE))) 147 | pde_t entrypgdir[NPDENTRIES] = { 148 | // Map VA's [0, 4MB) to PA's [0, 4MB) 149 | [0] = (0) | PTE_P | PTE_W | PTE_PS, 150 | // Map VA's [KERNBASE, KERNBASE+4MB) to PA's [0, 4MB) 151 | [KERNBASE>>PDXSHIFT] = (0) | PTE_P | PTE_W | PTE_PS, 152 | }; 153 | #endif 154 | 155 | //PAGEBREAK! 156 | // Blank page. 157 | 158 | -------------------------------------------------------------------------------- /boot/x86_64/main.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckkashyap/rustix/a7df7bb1e2b88993f9e6d0d2f550fe2a8fa8c0e2/boot/x86_64/main.o -------------------------------------------------------------------------------- /kernel/Makefile: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | # 3 | # Copyright (c) 2014 Kashyap 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | include $(SOURCE_ROOT)/Rules.inc 24 | 25 | all: libcompiler-rt.a libmorestack.a 26 | cp -f $(LINUX_RUST_DIR)/lib/rustlib/$(LINUX_TARGET)/lib/libcore-*.rlib libcore.rlib 27 | $(RUSTC) --target=$(LINUX_TARGET) -O -C no-stack-check kernel.rs \ 28 | --extern core=libcore.rlib -L. 29 | 30 | libcore.rlib: 31 | cp $(LINUX_RUST_DIR)/lib/rustlib/$(LINUX_TARGET)/lib/libcore-*.rlib libcore.rlib 32 | 33 | #$(RUSTC) --target=$(TARGET) -C no-stack-check --crate-type lib $(LIB_RS) --crate-name core 34 | 35 | libcompiler-rt.a: 36 | cp $(LINUX_RUST_DIR)/lib/rustlib/$(LINUX_TARGET)/lib/libcompiler-rt.a . 37 | 38 | libmorestack.a: 39 | cp $(LINUX_RUST_DIR)/lib/rustlib/$(LINUX_TARGET)/lib/libmorestack.a . 40 | 41 | clean: 42 | rm -f libkernel.a 43 | -------------------------------------------------------------------------------- /kernel/console.rs: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2014 Kashyap 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | use super::uart::uart_put_str; 24 | 25 | pub fn panic(text: &str) { 26 | uart_put_str(text); 27 | loop {}; 28 | } 29 | -------------------------------------------------------------------------------- /kernel/kalloc.rs: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2015 Kashyap 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | use super::spinlock::{Spinlock, DUMMY_LOCK, init_lock}; 24 | use super::mmu::{Address, PG_SIZE, pg_roundup}; 25 | use super::memlayout::{v2p,PHYSTOP}; 26 | use super::uart::uart_put_str; 27 | use super::console::panic; 28 | use super::rlibc::memset; 29 | 30 | struct KmemT { 31 | lock: Spinlock, 32 | use_lock: u32 , //TODO is u32 the right type? 33 | // TODO struct run *freelist; 34 | } 35 | 36 | 37 | static mut kmem : KmemT = KmemT{ lock: DUMMY_LOCK, use_lock: 0} ; 38 | static mut end : Address = 0; 39 | 40 | pub fn kinit1(vstart: Address, vend: Address) { 41 | unsafe { 42 | init_lock(& mut kmem.lock, "kmem"); 43 | kmem.use_lock = 0; 44 | } 45 | free_range(vstart, vend); 46 | } 47 | 48 | fn free_range(vstart: Address, vend: Address) { 49 | let mut address = pg_roundup(vstart); 50 | 51 | // Keep it around for future debugging 52 | //unsafe { 53 | // asm!("mov $0 , %rax" : /* no outputs */ : "r"(vend) : "eax"); 54 | // asm!("mov $0 , %rbx" : /* no outputs */ : "r"(address) : "eax"); 55 | //} 56 | 57 | unsafe { 58 | end = vstart; 59 | } 60 | 61 | loop { 62 | kfree(address); 63 | address = address + PG_SIZE; 64 | if address > vend { 65 | break; 66 | } 67 | } 68 | } 69 | 70 | fn kfree(v : Address) { 71 | //struct run *r; 72 | 73 | if ((v % PG_SIZE) > 0) || (v2p(v) >= PHYSTOP) { 74 | panic("kfree"); 75 | } 76 | 77 | unsafe { 78 | if v < end { 79 | panic("kfree"); 80 | } 81 | } 82 | 83 | 84 | 85 | unsafe { 86 | // Fill with junk to catch dangling refs. 87 | memset(v as * mut u8, 1, PG_SIZE as usize); 88 | } 89 | // 90 | // if(kmem.use_lock) 91 | // acquire(&kmem.lock); 92 | // r = (struct run*)v; 93 | // r->next = kmem.freelist; 94 | // kmem.freelist = r; 95 | // if(kmem.use_lock) 96 | // release(&kmem.lock); 97 | // 98 | // 99 | // 100 | // */ 101 | } 102 | -------------------------------------------------------------------------------- /kernel/kernel.rs: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2014 Kashyap 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | 24 | 25 | #![crate_name = "kernel"] 26 | #![crate_type = "staticlib"] 27 | #![feature(lang_items, asm, intrinsics)] 28 | #![no_std] 29 | #[lang="sized"] 30 | #[lang="sync"] 31 | 32 | extern crate core; 33 | 34 | mod uart; 35 | mod x86asm; 36 | mod picirq; 37 | mod traps; 38 | mod spinlock; 39 | mod kalloc; 40 | mod mmu; 41 | mod memlayout; 42 | mod rlibc; 43 | mod console; 44 | mod task; 45 | 46 | 47 | fn main (end : u64) { 48 | unsafe { 49 | *((0xb8000 ) as *mut u8) = 65; 50 | *((0xb8001 ) as *mut u8) = 0x6; 51 | asm!("mov $$0xff, %eax" : /* no outputs */ : /* no inputs */ : "eax"); 52 | } 53 | uart::early_init(); 54 | kalloc::kinit1(end, memlayout::P2V(4*1024*1024)); 55 | } 56 | 57 | #[no_mangle] 58 | pub extern "C" fn cmain(end : u64) { 59 | loop { 60 | main(end); 61 | } 62 | //return 255; 63 | } 64 | 65 | 66 | 67 | // Dummy functions to take care of missing libc function 68 | #[no_mangle] 69 | pub extern "C" fn trunc() {console::panic("trunc: console::panic!!!");} 70 | #[no_mangle] 71 | pub extern "C" fn truncf() {console::panic("truncf: console::panic!!!");} 72 | #[no_mangle] 73 | pub extern "C" fn floor() {console::panic("floor: console::panic!!!");} 74 | #[no_mangle] 75 | pub extern "C" fn floorf() {console::panic("floorf: console::panic!!!");} 76 | #[no_mangle] 77 | pub extern "C" fn pow() {console::panic("pow: console::panic!!!");} 78 | #[no_mangle] 79 | pub extern "C" fn powf() {console::panic("powf: console::panic!!!");} 80 | #[no_mangle] 81 | pub extern "C" fn fmod() {console::panic("fmod: console::panic!!!");} 82 | #[no_mangle] 83 | pub extern "C" fn fmodf() {console::panic("fmodf: console::panic!!!");} 84 | #[no_mangle] 85 | pub extern "C" fn log10() {console::panic("log10: console::panic!!!");} 86 | #[no_mangle] 87 | pub extern "C" fn log10f() {console::panic("log10f: console::panic!!!");} 88 | #[no_mangle] 89 | pub extern "C" fn memcpy() {console::panic("memcpy: console::panic!!!");} 90 | #[no_mangle] 91 | pub extern "C" fn memcmp() {console::panic("memcmp: console::panic!!!");} 92 | #[no_mangle] 93 | pub extern "C" fn log() {console::panic("log: console::panic!!!");} 94 | #[no_mangle] 95 | pub extern "C" fn logf() {console::panic("logf: console::panic!!!");} 96 | #[no_mangle] 97 | pub extern "C" fn log2() {console::panic("log2: console::panic!!!");} 98 | #[no_mangle] 99 | pub extern "C" fn log2f() {console::panic("log2f: console::panic!!!");} 100 | #[no_mangle] 101 | pub extern "C" fn round() {console::panic("round: console::panic!!!");} 102 | #[no_mangle] 103 | pub extern "C" fn roundf() {console::panic("roundf: console::panic!!!");} 104 | #[no_mangle] 105 | pub extern "C" fn exp() {console::panic("exp: console::panic!!!");} 106 | #[no_mangle] 107 | pub extern "C" fn expf() {console::panic("expf: console::panic!!!");} 108 | #[no_mangle] 109 | pub extern "C" fn exp2() {console::panic("exp2: console::panic!!!");} 110 | #[no_mangle] 111 | pub extern "C" fn exp2f() {console::panic("exp2f: console::panic!!!");} 112 | #[no_mangle] 113 | pub extern "C" fn ceil() {console::panic("ceil: console::panic!!!");} 114 | #[no_mangle] 115 | pub extern "C" fn ceilf() {console::panic("ceilf: console::panic!!!");} 116 | #[no_mangle] 117 | pub extern "C" fn fma() {console::panic("fma: console::panic!!!");} 118 | #[no_mangle] 119 | pub extern "C" fn fmaf() {console::panic("fmaf: console::panic!!!");} 120 | #[no_mangle] 121 | pub extern "C" fn __powisf2() {console::panic("__powisf2: console::panic!!!");} 122 | #[no_mangle] 123 | pub extern "C" fn __powidf2() {console::panic("__powidf2: console::panic!!!");} 124 | 125 | 126 | 127 | #[lang = "stack_exhausted"] extern fn stack_exhausted() { loop {} } 128 | #[lang = "eh_personality"] extern fn eh_personality() {loop {} } 129 | #[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} } 130 | -------------------------------------------------------------------------------- /kernel/lapic.rs: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2015 Kashyap 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | 24 | // TODO 25 | pub fn cpunum() -> isize { 26 | return 0i; 27 | } 28 | -------------------------------------------------------------------------------- /kernel/memlayout.rs: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2015 Kashyap 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | use super::mmu::Address; 24 | 25 | pub const KERNBASE : Address = 0xFFFFFFFF80000000; 26 | pub const PHYSTOP : Address = 0xE000000; 27 | 28 | //TODO - in C this is a macro - need to figure out the right thing in RUST 29 | pub fn P2V(address : Address) -> Address { 30 | address + KERNBASE 31 | } 32 | 33 | pub fn v2p(address : Address) -> Address { 34 | address - KERNBASE 35 | } 36 | -------------------------------------------------------------------------------- /kernel/mmu.rs: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2015 Kashyap 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | use super::spinlock::{Spinlock, DUMMY_LOCK, init_lock}; 24 | use super::uart::uart_put_str; 25 | 26 | pub type Address = u64; 27 | pub const PG_SIZE: Address = 4096; 28 | 29 | pub fn pg_roundup(sz: Address) -> Address { 30 | sz + (PG_SIZE - 1) & ! (PG_SIZE - 1) 31 | } 32 | 33 | // Eflags register 34 | pub const FL_IF: Address = 0x00000200; 35 | -------------------------------------------------------------------------------- /kernel/picirq.rs: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2015 Kashyap 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | use super::x86asm::outb; 24 | use super::x86asm::inb; 25 | 26 | const IO_PIC1 : u16 = 0x20;// Master (IRQs 0-7) 27 | const IO_PIC2 : u16 = 0xA0;// Slave (IRQs 8-15) 28 | 29 | const IRQ_SLAVE : u16 = 2;// IRQ at which slave connects to master 30 | 31 | static mut irq_mask : u16 = 0xFFFF & !( 1 << (IRQ_SLAVE as usize)); 32 | 33 | pub fn pic_setmask(mask : u16) 34 | { 35 | unsafe { 36 | irq_mask = mask; 37 | } 38 | outb(IO_PIC1+1, mask as u8); // TODO - check out a better way to do it 39 | outb(IO_PIC2+1, (mask >> 8) as u8); 40 | } 41 | 42 | 43 | 44 | pub fn pic_enable(irq : u8) 45 | { 46 | unsafe { 47 | pic_setmask(irq_mask & !(1 << irq as usize)); 48 | } 49 | } 50 | 51 | 52 | -------------------------------------------------------------------------------- /kernel/rlibc.rs: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2014 Kashyap 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | 24 | // Pick and chose from https://github.com/rust-lang/rlibc/blob/master/src/lib.rs 25 | 26 | use core::prelude::*; 27 | 28 | #[no_mangle] 29 | pub unsafe extern fn memset(s: *mut u8, c: i32, n: usize) -> *mut u8 { 30 | let mut i = 0; 31 | while i < n { 32 | *s.offset(i as isize) = c as u8; 33 | i += 1; 34 | } 35 | return s; 36 | } 37 | -------------------------------------------------------------------------------- /kernel/spinlock.rs: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2015 Kashyap 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | use core::str::StrExt; 24 | use task::Cpu; 25 | use x86asm::{read_eflags, cli}; 26 | use mmu::FL_IF; 27 | use console::panic; 28 | 29 | pub struct Spinlock { 30 | locked: u32, 31 | name: &'static str, 32 | cpu: *mut Cpu 33 | } 34 | 35 | pub const DUMMY_LOCK: Spinlock = Spinlock{locked: 0, name: "", cpu: 0 as (*mut Cpu)}; 36 | 37 | pub fn init_lock(lk: &mut Spinlock, name : &'static str) { 38 | lk.name = name; 39 | lk.locked = 0; 40 | lk.cpu = 0 as (*mut Cpu); 41 | } 42 | 43 | impl Spinlock { 44 | pub fn holding(&self) -> bool { 45 | self.locked == 1u32 // TODO: cpu 46 | } 47 | } 48 | 49 | fn pushcli() { 50 | let eflags = read_eflags(); 51 | cli(); 52 | } 53 | 54 | fn popcli() { 55 | // if (readeflags() & FL_IF) { 56 | // panic("popcli - interruptible"); 57 | // } 58 | // if(--cpu->ncli < 0) 59 | // panic("popcli"); 60 | // if(cpu->ncli == 0 && cpu->intena) 61 | // sti(); 62 | } 63 | -------------------------------------------------------------------------------- /kernel/task.rs: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2015 Kashyap 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | use core::str::StrExt; 24 | use core::marker::Copy; 25 | use super::spinlock::{Spinlock, DUMMY_LOCK, init_lock}; 26 | 27 | pub const TASK_NUM: usize = 1024; 28 | 29 | pub struct Cpu { 30 | id: usize, // Local APIC ID; index to cpus[] below 31 | started: usize, // Has the CPU started? 32 | ncli: isize, // Depth of pushcli nesting. 33 | intena: isize, // Were interrupts enabled before pushcli? 34 | cpu: *mut Cpu, // 35 | task: *mut Task // The currently-running process. 36 | } 37 | 38 | 39 | pub enum ProcState { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE } 40 | 41 | pub struct Task { 42 | sz: usize, 43 | pid: usize, 44 | killed: isize, 45 | state: ProcState, 46 | name: &'static str 47 | } 48 | 49 | impl Copy for ProcState {} 50 | impl Copy for Task {} 51 | 52 | struct TaskTable { 53 | lock: Spinlock, 54 | procs: &'static [Task; TASK_NUM] 55 | } 56 | 57 | static mut procs : TaskTable = TaskTable{ 58 | lock: DUMMY_LOCK, 59 | procs: &[ 60 | Task { 61 | sz: 0us, 62 | pid: 0us, 63 | killed: 0is, 64 | state: ProcState::UNUSED, 65 | name: "undef" 66 | }; TASK_NUM] 67 | }; 68 | 69 | pub fn init_proc() { 70 | unsafe { 71 | init_lock(&mut procs.lock, "task_table"); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /kernel/traps.rs: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2015 Kashyap 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | 24 | pub const IRQ_COM1 : u16 = 4; 25 | 26 | 27 | -------------------------------------------------------------------------------- /kernel/uart.rs: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2014 Kashyap 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | use super::x86asm::outb; 24 | use super::x86asm::inb; 25 | use super::picirq::pic_enable; 26 | use super::traps::IRQ_COM1; 27 | 28 | use core::prelude::*; 29 | 30 | 31 | 32 | const COM1 : u16 = 0x3f8; 33 | static mut uart_initialized : bool = false; 34 | 35 | 36 | pub fn early_init () { 37 | outb(COM1+2 , 0); 38 | outb(COM1+3, 0x80); // Unlock divisor 39 | outb(COM1+0, 12); 40 | outb(COM1+1, 0); 41 | outb(COM1+3, 0x03); // Lock divisor, 8 data bits. 42 | outb(COM1+4, 0); 43 | outb(COM1+1, 0x01); // Enable receive interrupts. 44 | 45 | 46 | if inb(COM1+5) == 0xff { 47 | return; 48 | } 49 | 50 | unsafe { 51 | uart_initialized = true; 52 | } 53 | 54 | uart_put_str("xv6 initizing...\n"); 55 | } 56 | 57 | 58 | 59 | fn uartinit() 60 | { 61 | unsafe { 62 | if !uart_initialized { 63 | return; 64 | } 65 | } 66 | 67 | // Acknowledge pre-existing interrupt conditions; 68 | // enable interrupts. 69 | inb(COM1+2); 70 | inb(COM1+0); 71 | pic_enable(IRQ_COM1 as u8); 72 | //ioapicenable(IRQ_COM1, 0); 73 | } 74 | 75 | 76 | pub fn uart_put_str(text: &str) { 77 | for b in text.bytes() { 78 | outb(COM1, b); 79 | } 80 | let x = [65, 66, 67, 10]; 81 | for e in x.iter() { 82 | uart_putc(*e as u8); 83 | } 84 | } 85 | 86 | fn uart_putc(byte : u8) { 87 | outb(COM1, byte); 88 | } 89 | -------------------------------------------------------------------------------- /kernel/x86asm.rs: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2014 Kashyap 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | 24 | pub fn outb (port: u16, value: u8) { 25 | unsafe { 26 | asm!("out %al, %dx":: "{al}"(value), "{dx}"(port)); 27 | } 28 | } 29 | 30 | pub fn inb(port: u16) -> u8 { 31 | let ret: u8; 32 | unsafe { 33 | asm!("inb %dx, %al": "={ax}"(ret) : "{dx}"(port)); 34 | } 35 | return ret; 36 | } 37 | 38 | pub fn cli() { 39 | unsafe { 40 | asm!("cli"); 41 | } 42 | } 43 | 44 | pub fn sti() { 45 | unsafe { 46 | asm!("sti"); 47 | } 48 | } 49 | 50 | 51 | pub fn read_eflags() -> u64 { //TODO 64 bit hard coded 52 | let ret : u64; 53 | unsafe { 54 | asm!("pushf; pop $0" : "=r"(ret) : ); 55 | } 56 | return ret; 57 | } 58 | -------------------------------------------------------------------------------- /staging/Makefile: -------------------------------------------------------------------------------- 1 | # http://wiki.osdev.org/64-bit_Higher_Half_Kernel_with_GRUB_2 2 | 3 | include $(SOURCE_ROOT)/Rules.inc 4 | 5 | ISO := os.iso 6 | 7 | all: 8 | rm -rf temp 9 | mkdir temp 10 | cd temp && $(AR) x $(SOURCE_ROOT)/kernel/libkernel.a 11 | cd temp && $(AR) x $(SOURCE_ROOT)/kernel/libcompiler-rt.a 12 | cd temp && $(AR) x $(SOURCE_ROOT)/kernel/libmorestack.a 13 | cd temp && $(AR) x $(SOURCE_ROOT)/kernel/libcore.rlib 14 | $(LD) -m elf_x86_64 -nodefaultlibs -T $(SOURCE_ROOT)/boot/x86_64/kernel64.ld -o kernel.sys $(SOURCE_ROOT)/boot/x86_64/entry64.o $(SOURCE_ROOT)/boot/x86_64/main.o temp/kernel.o temp/core-*.o temp/morestack*.o -b binary $(SOURCE_ROOT)/boot/x86_64/initcode $(SOURCE_ROOT)/boot/x86_64/entryother 15 | #$(LD) -nodefaultlibs -z max-page-size=0x1000 -Tlinker.ld -o kernel.sys --start-group $(OBJECTS) --end-group 16 | 17 | 18 | iso: 19 | cp kernel.sys iso/boot 20 | grub-mkrescue -o $(ISO) iso 21 | 22 | clean: 23 | @rm -f $(ISO) iso/boot/kernel.sys kernel.sys 24 | -------------------------------------------------------------------------------- /staging/iso/boot/grub/grub.cfg: -------------------------------------------------------------------------------- 1 | set timeout=3 2 | set default=0 3 | 4 | menuentry "My Os" { 5 | multiboot2 /boot/kernel.sys 6 | boot 7 | } 8 | -------------------------------------------------------------------------------- /staging/linker.ld: -------------------------------------------------------------------------------- 1 | ENTRY(EntryPoint) 2 | 3 | /*KERNEL_VMA = 0x100000;*/ 4 | KERNEL_VMA = 0xFFFFFFFF80000000; 5 | 6 | SECTIONS 7 | { 8 | 9 | . = 0x100000; 10 | 11 | .boot : 12 | { 13 | *(.mbhdr) 14 | _loadStart = .; 15 | *(.boot) 16 | . = ALIGN(4096); 17 | Pml4 = .; 18 | . += 0x1000; 19 | Pdpt = .; 20 | . += 0x1000; 21 | Pd = .; 22 | . += 0x1000; 23 | . += 0x8000; 24 | Stack = .; 25 | } 26 | 27 | . += KERNEL_VMA; 28 | 29 | .text : AT(ADDR(.text) - KERNEL_VMA) 30 | { 31 | _code = .; 32 | *(.text) 33 | *(.rodata*) 34 | . = ALIGN(4096); 35 | } 36 | 37 | .data : AT(ADDR(.data) - KERNEL_VMA) 38 | { 39 | _data = .; 40 | *(.data) 41 | . = ALIGN(4096); 42 | } 43 | 44 | .eh_frame : AT(ADDR(.eh_frame) - KERNEL_VMA) 45 | { 46 | _ehframe = .; 47 | *(.eh_frame) 48 | . = ALIGN(4096); 49 | } 50 | 51 | _loadEnd = . - KERNEL_VMA; 52 | 53 | .bss : AT(ADDR(.bss) - KERNEL_VMA) 54 | { 55 | _bss = .; 56 | *(.bss) 57 | 58 | /* 59 | * You usually need to include generated COMMON symbols 60 | * under kernel BSS section or use gcc's -fno-common 61 | */ 62 | 63 | *(COMMON) 64 | . = ALIGN(4096); 65 | } 66 | 67 | _bssEnd = . - KERNEL_VMA; 68 | _end = .; 69 | 70 | /DISCARD/ : 71 | { 72 | *(.comment) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /tools/Makefile: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | # 3 | # Copyright (c) 2014 Kashyap 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | include $(SOURCE_ROOT)/Rules.inc 24 | 25 | 26 | reinstall_rust: 27 | $(AT)curl -s https://static.rust-lang.org/rustup.sh | sudo sh -s -- --uninstall 28 | $(AT)curl -s https://static.rust-lang.org/rustup.sh | sudo sh 29 | rm -rf $(SOURCE_ROOT)/tools/rust-nightly* 30 | cd $(SOURCE_ROOT)/tools && wget https://static.rust-lang.org/dist/rust-nightly.tar.gz && tar xzf rust-nightly.tar.gz 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /tools/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | curl -s https://static.rust-lang.org/rustup.sh | sudo sh 4 | -------------------------------------------------------------------------------- /tools/uninstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | curl -s https://static.rust-lang.org/rustup.sh | sudo sh -s -- --uninstall 4 | -------------------------------------------------------------------------------- /xv62rustx.map: -------------------------------------------------------------------------------- 1 | Symbols 2 | ======= 3 | 4 | 5 | Files 6 | ===== 7 | 8 | proc.c -> task.rs (proc seems to be conflicting with some in-built rust stuff) 9 | --------------------------------------------------------------------------------