diff --git a/.gitignore b/.gitignore index df1a3c9..e422e8b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ -all -all.raw -all.raw.gz +kernel +kernel.raw +kernel.raw.gz uimage *.o *.cc diff --git a/Makefile b/Makefile index 4d29c03..8703515 100644 --- a/Makefile +++ b/Makefile @@ -1,57 +1,54 @@ -load = 0x80000000 +# Iris: micro-kernel for a capability-based operating system. +# Makefile: build rules +# Copyright 2009 Bas Wijnen +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . -CXXFLAGS = -Wno-unused-parameter -fno-strict-aliasing -fno-builtin -nostdinc -DNUM_THREADS=2 -I/usr/include -CPPFLAGS = -O5 -Wa,-mips32 -CROSS = mipsel-linux-gnu- +# Define some variables. +CXXFLAGS = -Wno-unused-parameter -fno-strict-aliasing -fno-builtin -nostdinc $(ARCH_CXXFLAGS) +CPPFLAGS = -O5 $(ARCH_CPPFLAGS) CC = $(CROSS)gcc LD = $(CROSS)ld OBJCOPY = $(CROSS)objcopy -OBJDUMP = $(CROSS)objdump STRIP = $(CROSS)strip -kernel_sources = interrupts.cc panic.cc data.cc test.cc alloc.cc arch.cc invoke.cc schedule.cc -boot_sources = init.cc +headers = kernel.hh iris.h $(arch_headers) +kernel_sources = panic.cc data.cc alloc.cc invoke.cc schedule.cc $(arch_kernel_sources) BUILT_SOURCES = $(kernel_sources) $(boot_sources) +# Include arch-specific rules. +include Makefile.arch + +# Disable implicit rules. +%.o: %.S +%.o: %.cc + PYPP = /usr/bin/pypp %.cc: %.ccp $(PYPP) --name $< < $< > $@ -%.hh: %.hhp boot-programs/sos.h +%.hh: %.hhp $(PYPP) --name $< < $< > $@ -# Transform ':' into ';' so vim doesn't think there are errors. -uimage: all.raw Makefile - mkimage -A MIPS -O Linux -C none -a $(load) -e 0x$(shell /bin/sh -c '$(OBJDUMP) -t all | grep __start$$ | cut -b-8') -n "Shevek's kernel" -d $< $@ | sed -e 's/:/;/g' +%.o:%.cc Makefile Makefile.arch $(headers) + $(CC) $(CPPFLAGS) $(TARGET_FLAGS) $(CXXFLAGS) -c $< -o $@ -arch.hh: mips.hh - ln -s $< $@ || true -arch.cc: mips.cc - ln -s $< $@ || true - -%.o:%.cc Makefile kernel.hh arch.hh boot-programs/sos.h - $(CC) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@ - -entry.o: thread0 thread1 - -%.o:%.S Makefile arch.hh - $(CC) $(CPPFLAGS) -DKERNEL_STACK_SIZE=0x2000 -c $< -o $@ - -%: boot-helper.o boot-programs/%.o +%: boot-programs/init.o boot-programs/%.o $(LD) $^ -o $@ $(STRIP) $@ - -# entry.o must be the first file. boot.o must be the first of the init objects (which can be dumped after loading). -all: entry.o $(subst .cc,.o,$(kernel_sources)) boot.o $(subst .cc,.o,$(boot_sources)) - $(LD) --omagic -Ttext $(load) $^ -o $@ - -junk = mdebug.abi32 reginfo comment pdr -%.raw: % - $(OBJCOPY) -S $(addprefix --remove-section=.,$(junk)) -Obinary $< $@ - -%.gz: % - gzip < $< > $@ + $(OBJCOPY) -S $(OBJCOPYFLAGS) $@ clean: - rm -f all uimage *.o boot-programs/*.o all.raw.gz arch.hh arch.cc + rm -f *.o boot-programs/*.o kernel kernel.raw kernel.raw.gz $(BUILT_SOURCES) $(ARCH_CLEAN_FILES) .PHONY: clean diff --git a/Makefile.arch b/Makefile.arch new file mode 120000 index 0000000..6165523 --- /dev/null +++ b/Makefile.arch @@ -0,0 +1 @@ +mips/Makefile.arch \ No newline at end of file diff --git a/alloc.ccp b/alloc.ccp index 3de2665..8efe396 100644 --- a/alloc.ccp +++ b/alloc.ccp @@ -1,4 +1,21 @@ #pypp 0 +// Iris: micro-kernel for a capability-based operating system. +// alloc.ccp: Allocation of kernel structures. +// Copyright 2009 Bas Wijnen +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + #include "kernel.hh" #define PREV(x) (((Object_base **)(x))[-2]) diff --git a/boot-helper.S b/boot-helper.S deleted file mode 100644 index 7dae1e4..0000000 --- a/boot-helper.S +++ /dev/null @@ -1,28 +0,0 @@ - .globl __start - -__start: - bal 1f - .word _gp -1: - lw $gp, 0($ra) - la $v0, __my_receiver - sw $a0, ($v0) - la $v0, __my_thread - sw $a1, ($v0) - la $v0, __my_memory - sw $a2, ($v0) - la $v0, __my_call - sw $a3, ($v0) - la $t9, main - la $ra, 1f - jr $t9 - nop - -1: - // Generate an address fault. - lw $a0, -4($zero) - - .comm __my_receiver, 4 - .comm __my_thread, 4 - .comm __my_memory, 4 - .comm __my_call, 4 diff --git a/boot-programs/init.S b/boot-programs/init.S new file mode 100644 index 0000000..032742b --- /dev/null +++ b/boot-programs/init.S @@ -0,0 +1,47 @@ +// Iris: micro-kernel for a capability-based operating system. +// init.S: Startup code for initial Threads. +// Copyright 2009 Bas Wijnen +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + + .globl __start + .set noreorder + +__start: + bal 1f + .word _gp +1: + lw $gp, 0($ra) + la $v0, __my_receiver + sw $a0, ($v0) + la $v0, __my_thread + sw $a1, ($v0) + la $v0, __my_memory + sw $a2, ($v0) + la $v0, __my_call + sw $a3, ($v0) + la $t9, main + la $ra, 1f + jr $t9 + nop + +1: + // This should not be reached: generate an address fault. + b 1b + lw $a0, -4($zero) + + .comm __my_receiver, 4 + .comm __my_thread, 4 + .comm __my_memory, 4 + .comm __my_call, 4 diff --git a/boot-programs/thread0.ccp b/boot-programs/thread0.ccp index f6be2c2..f077a30 100644 --- a/boot-programs/thread0.ccp +++ b/boot-programs/thread0.ccp @@ -1,5 +1,22 @@ #pypp 0 -#include "sos.h" +// Iris: micro-kernel for a capability-based operating system. +// thread0.ccp: Testing userspace thread. +// Copyright 2009 Bas Wijnen +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "iris.h" int main (): while true: diff --git a/boot-programs/thread1.ccp b/boot-programs/thread1.ccp index 7252ec3..9cd032a 100644 --- a/boot-programs/thread1.ccp +++ b/boot-programs/thread1.ccp @@ -1,5 +1,22 @@ #pypp 0 -#include "sos.h" +// Iris: micro-kernel for a capability-based operating system. +// thread1.ccp: Testing userspace thread. +// Copyright 2009 Bas Wijnen +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "iris.h" int main (): while true: diff --git a/boot.S b/boot.S deleted file mode 100644 index d4a25d3..0000000 --- a/boot.S +++ /dev/null @@ -1,51 +0,0 @@ - // The kernel stack. - .lcomm kernel_stack, KERNEL_STACK_SIZE - - .globl __start - .globl thread_start - .set noreorder - -#define Status 12 -#define Config 16 - -__start: - bal 1f - nop - .word _gp -// For some reason the disassembler considers everything -// after __start non-code until the next label. So I add a label. -start_hack_for_disassembler: -1: lw $gp, 0($ra) - - la $sp, kernel_stack + KERNEL_STACK_SIZE - - // Disable interrupts during bootstrap. - mtc0 $zero, $Status - - // TODO: flush cache and optionally refill it. - - // Set kseg0 cachable. - li $k0, 0x3 - mtc0 $k0, $Config, 0 - - // Jump into cached code. - la $t9, 1f - jr $t9 - nop -1: - - // Clear .bss - la $a0, _edata - la $a1, _end -1: sw $zero, 0($a0) - bne $a1, $a0, 1b - addu $a0, 4 - - la $t9, init - jr $t9 - nop - -thread_start: - .word thread0 - .word thread1 - .word thread2 diff --git a/data.ccp b/data.ccp index d68cffc..33af2d0 100644 --- a/data.ccp +++ b/data.ccp @@ -1,8 +1,27 @@ #pypp 0 +// Iris: micro-kernel for a capability-based operating system. +// data.ccp: Allocation of kernel structures. +// Copyright 2009 Bas Wijnen +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// All variables are defined in kernel.hhp as "EXTERN", which is normally +// defined as "extern". By defining it empty, space is allocated for them. +// This must happen exactly once in all files linked into the kernel. #define EXTERN #include "kernel.hh" -// This is needed to make gcc happy to compile c++ code without -// its standard library. +// This is needed to make gcc compile c++ code without its standard library. char __gxx_personality_v0[] = "hack" diff --git a/invoke.ccp b/invoke.ccp index 6f6a6c2..be482eb 100644 --- a/invoke.ccp +++ b/invoke.ccp @@ -1,4 +1,21 @@ #pypp 0 +// Iris: micro-kernel for a capability-based operating system. +// invoke.ccp: Capability invocation and kernel responses. +// Copyright 2009 Bas Wijnen +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + #include "kernel.hh" Capability *Memory::find_capability (unsigned code, bool *copy): diff --git a/boot-programs/sos.h b/iris.h similarity index 93% rename from boot-programs/sos.h rename to iris.h index 1069d70..4336b53 100644 --- a/boot-programs/sos.h +++ b/iris.h @@ -1,5 +1,22 @@ -#ifndef __SOS_H -#define __SOS_H +/* Iris: micro-kernel for a capability-based operating system. + * iris.h: C header file for userspace programs. + * Copyright 2009 Bas Wijnen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __IRIS_H +#define __IRIS_H #ifdef __cplusplus extern "C" { diff --git a/kernel.hhp b/kernel.hhp index 160bac3..a7de36f 100644 --- a/kernel.hhp +++ b/kernel.hhp @@ -1,14 +1,38 @@ #pypp 0 +// Iris: micro-kernel for a capability-based operating system. +// kernel.hhp: Header for all kernel sources. +// Copyright 2009 Bas Wijnen +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + #ifndef _KERNEL_HH #define _KERNEL_HH +// Include definitions which are shared with user space. #define __KERNEL -#include "boot-programs/sos.h" +#include "iris.h" +// Normally define all variables in this file as extern. +// Exactly once (in data.ccp), EXTERN is predefined empty. +// That results in space being allocated in its object file. #ifndef EXTERN #define EXTERN extern #endif +// Without the standard library, we don't have this definition. +// I preferred ((void*)0), but C++ has too strict type-checking to +// make that work. #define NULL 0 struct Object_base @@ -38,6 +62,7 @@ struct Free : public Object : bool Object_base::is_free (): return ((Free *)this)->marker == ~0 +// Include architecture-specific parts. #include "arch.hh" struct Thread : public Object : @@ -167,7 +192,7 @@ EXTERN Thread *current unsigned raw_zalloc () void raw_pfree (unsigned page) -// Defined in arch.cc +// Defined by architecture-specific files. void Thread_arch_init (Thread *thread) void Thread_arch_receive (Thread *thread, unsigned d[4], Capability *c[4]) void Thread_arch_receive_fail (Thread *thread) diff --git a/mips/Makefile.arch b/mips/Makefile.arch new file mode 100644 index 0000000..a816fae --- /dev/null +++ b/mips/Makefile.arch @@ -0,0 +1,59 @@ +# Iris: micro-kernel for a capability-based operating system. +# mips/Makefile.arch: mips-specific parts of the build rules +# Copyright 2009 Bas Wijnen +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +load = 0x80000000 + +ARCH_CXXFLAGS = -DNUM_THREADS=2 +ARCH_CPPFLAGS = -Imips -Wa,-mips32 +CROSS = mipsel-linux-gnu- +OBJDUMP = $(CROSS)objdump +junk = mdebug.abi32 reginfo comment pdr +OBJCOPYFLAGS = $(addprefix --remove-section=.,$(junk)) + +arch_kernel_sources = mips/interrupts.cc mips/test.cc mips/arch.cc +boot_sources = mips/init.cc +BUILT_SOURCES = $(kernel_sources) $(boot_sources) +arch_headers = mips/arch.hh +boot_threads = thread0 thread1 + +uimage: + +mips/entry.o: $(boot_threads) +mips/init.o: TARGET_FLAGS = -I/usr/include +$(boot_threads): TARGET_FLAGS = -I. + +# Transform ':' into ';' so vim doesn't think there are errors. +uimage: kernel.raw.gz Makefile mips/Makefile.arch + mkimage -A MIPS -O Linux -C gzip -a $(load) -e 0x$(shell /bin/sh -c '$(OBJDUMP) -t kernel | grep __start$$ | cut -b-8') -n "Shevek's kernel" -d $< $@ | sed -e 's/:/;/g' + +elf.h: /usr/include/elf.h + ln -s $< $@ + +%.o:%.S Makefile mips/Makefile.arch mips/arch.hh + $(CC) $(CPPFLAGS) $(TARGET_FLAGS) -DKERNEL_STACK_SIZE=0x2000 -c $< -o $@ + +# entry.o must be the first file. boot.o must be the first of the init objects (which can be freed after loading). +kernel: mips/entry.o $(subst .cc,.o,$(kernel_sources)) mips/boot.o $(subst .cc,.o,$(boot_sources)) + $(LD) --omagic -Ttext $(load) $^ -o $@ + +%.raw: % + $(OBJCOPY) -S $(addprefix --remove-section=.,$(junk)) -Obinary $< $@ + +%.gz: % + gzip < $< > $@ + +ARCH_CLEAN_FILES = uimage kernel kernel.raw kernel.raw.gz elf.h $(boot_threads) mips/*.o diff --git a/mips.ccp b/mips/arch.ccp similarity index 92% rename from mips.ccp rename to mips/arch.ccp index 3fcc2e4..18da85f 100644 --- a/mips.ccp +++ b/mips/arch.ccp @@ -1,6 +1,23 @@ #pypp 0 +// Iris: micro-kernel for a capability-based operating system. +// mips/arch.ccp: Most mips-specific parts. +// Copyright 2009 Bas Wijnen +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + #define ARCH -#include "kernel.hh" +#include "../kernel.hh" void Thread_arch_init (Thread *thread): thread->arch.at = 0 diff --git a/mips.hhp b/mips/arch.hhp similarity index 83% rename from mips.hhp rename to mips/arch.hhp index 1e96f7e..296c3df 100644 --- a/mips.hhp +++ b/mips/arch.hhp @@ -1,4 +1,21 @@ #pypp 0 +// Iris: micro-kernel for a capability-based operating system. +// mips/arch.hhp: mips-specific declarations and type definitions. +// Copyright 2009 Bas Wijnen +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + #ifndef _ARCH_HH #define _ARCH_HH diff --git a/mips/boot.S b/mips/boot.S new file mode 100644 index 0000000..1446d32 --- /dev/null +++ b/mips/boot.S @@ -0,0 +1,68 @@ +// Iris: micro-kernel for a capability-based operating system. +// mips/boot.S: Kernel entry point, called by the boot loader. +// Copyright 2009 Bas Wijnen +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + + // The kernel stack. + .lcomm kernel_stack, KERNEL_STACK_SIZE + + .globl __start + .globl thread_start + .set noreorder + +#define Status 12 +#define Config 16 + +__start: + bal 1f + nop + .word _gp +// For some reason the disassembler considers everything +// after __start non-code until the next label. So I add a label. +start_hack_for_disassembler: +1: lw $gp, 0($ra) + + la $sp, kernel_stack + KERNEL_STACK_SIZE + + // Disable interrupts during bootstrap. + mtc0 $zero, $Status + + // TODO: flush cache and optionally refill it. + + // Set kseg0 cachable. + li $k0, 0x3 + mtc0 $k0, $Config, 0 + + // Jump into cached code. + la $t9, 1f + jr $t9 + nop +1: + + // Clear .bss + la $a0, _edata + la $a1, _end +1: sw $zero, 0($a0) + bne $a1, $a0, 1b + addu $a0, 4 + + la $t9, init + jr $t9 + nop + +thread_start: + .word thread0 + .word thread1 + .word thread2 diff --git a/entry.S b/mips/entry.S similarity index 82% rename from entry.S rename to mips/entry.S index 6e663f6..6dc278c 100644 --- a/entry.S +++ b/mips/entry.S @@ -1,3 +1,20 @@ +// Iris: micro-kernel for a capability-based operating system. +// mips/entry.S: Routines which are entered from user space. +// Copyright 2009 Bas Wijnen +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + // The kernel stack. .lcomm kernel_stack, KERNEL_STACK_SIZE diff --git a/init.ccp b/mips/init.ccp similarity index 90% rename from init.ccp rename to mips/init.ccp index 1e1f0c8..38629c3 100644 --- a/init.ccp +++ b/mips/init.ccp @@ -1,9 +1,26 @@ #pypp 0 +// Iris: micro-kernel for a capability-based operating system. +// init.ccp: mips-specific boot code. +// Copyright 2009 Bas Wijnen +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + // Also declare things which only work during kernel init. #define INIT #define ARCH -#include "kernel.hh" -#include "elf.h" +#include "../kernel.hh" +#include static void init_idle (): // initialize idle task as if it is currently running. diff --git a/interrupts.ccp b/mips/interrupts.ccp similarity index 80% rename from interrupts.ccp rename to mips/interrupts.ccp index 08e0c0f..5baf340 100644 --- a/interrupts.ccp +++ b/mips/interrupts.ccp @@ -1,6 +1,23 @@ #pypp 0 +// Iris: micro-kernel for a capability-based operating system. +// interrupts.ccp: Functions called by mips/entry.S. +// Copyright 2009 Bas Wijnen +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + #define ARCH -#include "kernel.hh" +#include "../kernel.hh" /// A TLB miss has occurred. This is the slow version. It is only used /// when k0 or k1 is not 0, or when an error occurs. diff --git a/test.ccp b/mips/test.ccp similarity index 76% rename from test.ccp rename to mips/test.ccp index 6473161..f6d4655 100644 --- a/test.ccp +++ b/mips/test.ccp @@ -1,5 +1,22 @@ #pypp 0 -#include "kernel.hh" +// Iris: micro-kernel for a capability-based operating system. +// test.ccp: Telling the user things with LEDs. +// Copyright 2009 Bas Wijnen +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "../kernel.hh" #define REG32(addr) *((volatile unsigned int *)(addr)) diff --git a/panic.ccp b/panic.ccp index 66f96d0..834659b 100644 --- a/panic.ccp +++ b/panic.ccp @@ -1,4 +1,21 @@ #pypp 0 +// Iris: micro-kernel for a capability-based operating system. +// panic.ccp: Stop running and try to notify the user of the problem. +// Copyright 2009 Bas Wijnen +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + #include "kernel.hh" void panic (unsigned n, char const *message): diff --git a/report/cross-compiler.tex b/report/cross-compiler.tex index ce945e9..34045b4 100644 --- a/report/cross-compiler.tex +++ b/report/cross-compiler.tex @@ -1,3 +1,20 @@ +% Iris: micro-kernel for a capability-based operating system. +% cross-compiler.tex: Cross-compiler building instructions. +% Copyright 2009 Bas Wijnen +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . + \documentclass{shevek} \begin{document} \title{Setting up a cross-compiler} diff --git a/report/kernel.tex b/report/kernel.tex index 7663a0c..fb56974 100644 --- a/report/kernel.tex +++ b/report/kernel.tex @@ -1,16 +1,33 @@ +% Iris: micro-kernel for a capability-based operating system. +% kernel.tex: Description of Iris. +% Copyright 2009 Bas Wijnen +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . + \documentclass{shevek} \begin{document} -\title{Overview of my kernel} +\title{Overview of Iris} \author{Bas Wijnen} \date{\today} \maketitle \begin{abstract} -This document briefly describes the inner workings of my kernel, including the -reasons for the choices that were made. It is meant to be understandable (with -effort) for people who know nothing of operating systems. On the other hand, -it should also be readable for people who know about computer architecture, but -want to know about this kernel. It is probably better suited for the latter -category. +This document briefly describes the inner workings of my kernel, Iris, +including the reasons for the choices that were made. It is meant to be +understandable (with effort) for people who know nothing of operating systems. +On the other hand, it should also be readable for people who know about +computer architecture, but want to know about this kernel. It is probably +better suited for the latter category. \end{abstract} \tableofcontents @@ -20,7 +37,7 @@ This section describes what the purpose of an operating system is, and defines what I call an ``operating system''\footnote{Different people use very different definitions, so this is not as trivial as it sounds.}. It also goes into some detail about microkernels and capabilities. If you already know, you -can safely skip this section. It contains no information about my kernel. +can safely skip this section. It contains no information about Iris. \subsection{The goal of an operating system} In the 1980s, a computer could only run one program at a time. When the @@ -160,8 +177,8 @@ into the hands of the user (as far as allowed by the system administrator). This is a very good thing. \section{Kernel objects} -This section describes all the kernel objects, and the operations that can be -performed on them. One operation is possible on any kernel object (except a +This section describes all kernel objects of Iris, and the operations that can +be performed on them. One operation is possible on any kernel object (except a message and reply and call Capabilities). This operation is \textit{degrade}. It creates a copy of the capability with some rights removed. This can be useful when giving away a capability. @@ -191,13 +208,13 @@ Receiver's queues. \item Get and set the limit, which is checked when allocating pages for this Memory or any sub-structure. \item Drop a capability. This can only be done by Threads owned by the Memory, -because only they can present capabilities owned by it.\footnote{The kernel -checks if presented capabilities are owned by the Thread's Memory. If they -aren't, no capability is passed instead. The destroy operation destroys an -object that a capability points to. Drop destroys the capability itself. If a -Thread from an other Memory would try to drop a capability, the kernel would -refuse to send it in the message, or it would not be dropped because it would -be owned by a different Memory.} +because only they can present capabilities owned by it.\footnote{Iris checks if +presented capabilities are owned by the Thread's Memory. If they aren't, no +capability is passed instead. The destroy operation destroys an object that a +capability points to. Drop destroys the capability itself. If a Thread from +an other Memory would try to drop a capability, Iris would refuse to send it in +the message, or it would not be dropped because it would be owned by a +different Memory.} \end{itemize} \subsection{Receiver} @@ -249,15 +266,15 @@ flags (whether the process is running or waiting for a message, setting these flags is a way to control this for other Threads), the program counter and the stack pointer. This call is also used to get the contents of processor registers and possibly other information which is different per Thread. -\item Let the kernel schedule the next process. This is not thread-specific. +\item Let Iris schedule the next process. This is not thread-specific. \item Get the top Memory object. This is not thread-specific. Most Threads are not allowed to perform this operation. It is given to the initial Threads. They can pass it on to Threads that need it (mostly device drivers). \item In the same category, register a Receiver for an interrupt. Upon registration, the interrupt is enabled. When the interrupt arrives, the -registered Receiver gets a message from the kernel and the interrupt is -disabled again. After the Thread has handled the interrupt, it must reregister -it in order to enable it again. +registered Receiver gets a message from Iris and the interrupt is disabled +again. After the Thread has handled the interrupt, it must reregister it in +order to enable it again. \item And similarly, allow these priviledged operations (or some of them) in an other thread. This is a property of the caller, because the target thread normally doesn't have the permission to do this (otherwise the call would not @@ -286,8 +303,8 @@ all flags can be set in all cases. \end{itemize} \subsection{Capability} -A capability object can be invoked to send a message to a receiver or the -kernel. The owner cannot see from the capability where it points. This is +A capability object can be invoked to send a message to a receiver or to Iris +itself. The owner cannot see from the capability where it points. This is important, because the user must be able to substitute the capability for a different one, without the program noticing. In some cases, it is needed to say things about capabilities. For example, a Memory can list the Capabilities diff --git a/report/making-of.tex b/report/making-of.tex index e87799f..ab71962 100644 --- a/report/making-of.tex +++ b/report/making-of.tex @@ -1,3 +1,19 @@ +% Iris: micro-kernel for a capability-based operating system. +% making-of.tex: Description of the process of writing Iris. +% Copyright 2009 Bas Wijnen +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . \documentclass{shevek} \begin{document} \title{Writing a kernel from scratch} @@ -5,13 +21,13 @@ \date{\today} \maketitle \begin{abstract} -This is a report of the process of writing a kernel from scratch for +This is a report of the process of writing a kernel (Iris) from scratch for the cheap (€150) Trendtac laptop. In a following report I shall write about -the operating system on top of it. It is written while writing the system, so -that no steps are forgotten. Choices are explained and problems (and their -solutions) are shown. After reading this, you should have a thorough -understanding of the kernel, and (with significant effort) be able to write a -similar kernel yourself. This document assumes a working Debian system with +the operating system on top of it. This document is written while writing the +system, so that no steps are forgotten. Choices are explained and problems +(and their solutions) are shown. After reading this, you should have a +thorough understanding of Iris, and (with significant effort) be able to write +a similar kernel yourself. This document assumes a working Debian system with root access (for installing packages), and some knowledge about computer architectures. (If you lack that knowledge, you can try to read it anyway and check other sources when you see something new.) @@ -67,7 +83,9 @@ mapped (meaning it accesses physical, not virtual, memory) except that is is not cached. \item kseg2 runs from 0xc0000000 to the top. It is mapped like user memory, differently for each process, and can be cached. It is intended for -per-address space kernel structures. I shall not use it in my kernel. +per-address space kernel structures. I shall not use it in Iris.\footnote{I +thought I wouldn't use kseg2. However, I needed to use it for kernel entry +code, as you can read below.} \end{itemize} U-boot has some standard commands. It can load the image from the SD card at 0x80600000. Even though the Linux image seems to use a different address, I'll @@ -181,7 +199,7 @@ It explains that memory accesses to the lower 2GB are (almost always) mapped through a TLB (translation lookaside buffer). This is an array of some records where virtual to physical address mappings are stored. In case of a TLB-miss (the virtual address cannot be found in the table), an exception is generated -and the kernel must insert the mapping into the TLB. +and Iris must insert the mapping into the TLB. This is very flexible, because I get to decide how I write the kernel. I shall use something similar to the hardware implementation of the IBM PC: a page @@ -197,16 +215,16 @@ what is more expensive. I'll initially go for the cpu time wasting approach. \section{Kernel entry} Now that I have an idea of how a process looks in memory, I need to implement -kernel entry and exit. A process is preempted or makes a request, then the -kernel responds, and then a process (possibly the same) is started again. +kernel entry and exit. A process is preempted or makes a request, then Iris +responds, and then a process (possibly the same) is started again. The main problem of kernel entry is to save all registers in the kernel structure which is associated with the thread. In case of the MIPS processor, there is a simple solution: there are two registers, k0 and k1, which cannot be used by the thread. So they can be set before starting the thread, and will -still have their values when the kernel is entered again. By pointing one of -them to the place to save the data, it becomes easy to perform the save and -restore. +still have their values when the kernel is entered again.\footnote{This is not +true, see below.} By pointing one of them to the place to save the data, it +becomes easy to perform the save and restore. As with the bootstrap process, this must be done in assembly. In this case this is because the user stack must not be used, and a C function will use the @@ -221,12 +239,12 @@ easiest way. Now I've reached the point where I need to create some memory structures. To do that, I first need to decide how to organize the memory. There's one very simple rule in my system: everyone must pay for what they use. For memory, -this means that a process brings its own memory where the kernel can write -things about it. The kernel does not need its own allocation system, because -it always works for some process. If the process doesn't provide the memory, -the operation will fail.\footnote{There are some functions with \textit{alloc} -in their name. However, they allocate pieces of memory which is owned by the -calling process. The kernel never allocates anything for itself, except during +this means that a process brings its own memory where Iris can write things +about it. Iris does not need her own allocation system, because she always +works for some process. If the process doesn't provide the memory, the +operation will fail.\footnote{There are some functions with \textit{alloc} in +their name. However, they allocate pieces of memory which is owned by the +calling process. Iris never allocates anything for herself, except during boot.} Memory will be organized hierarchically. It belongs to a container, which I @@ -235,11 +253,11 @@ Memory, its parent. This is true for all but one, which is the top level Memory. The top level Memory owns all memory in the system. Some of it directly, most of it through other Memories. -The kernel will have a list of unclaimed pages. For optimization, it actually -has two lists: one with pages containing only zeroes, one with pages containing -junk. When idle, the junk pages can be filled with zeroes. +Iris will have a list of unclaimed pages. For optimization, she actually +has two lists: one with pages containing only zeroes, and one with pages +containing junk. When idle, the junk pages can be filled with zeroes. -Because the kernel starts at address 0, building up the list of pages is very +Because Iris starts at address 0, building up the list of pages is very easy: starting from the first page above the top of the kernel, everything is free space. Initially, all pages are added to the junk list. @@ -251,7 +269,7 @@ task, and then jumping to it. There are two options for the idle task, again with their own drawbacks. The idle task can run in kernel mode. This is easy, it doesn't need any paging -machinery then. However, this means that the kernel must read-modify-write the +machinery then. However, this means that Iris must read-modify-write the Status register of coprocessor 0, which contains the operating mode, on every context switch. That's quite an expensive operation for such a critical path. @@ -286,16 +304,17 @@ first switch off all interrupts by writing 0 to the Status register of CP0. This also reminded me that I need to flush the cache, so that I can be sure everything is correct. For that reason, I need to start at 0xa0000000, not 0x80000000, so that the startup code is not cached. It should be fine to load -the kernel at 0x80000000, but jump in at the non-cached location anyway, if I +Iris at 0x80000000, but jump in at the non-cached location anyway, if I make sure the initial code, which clears the cache, can handle it. After that, I jump to the cached region, and everything should be fine. However, at this -moment I first link the kernel at the non-cached address, so I don't need to -worry about it. +moment I first link Iris at the non-cached address, so I don't need to +worry about it.\footnote{Actually, it seems that the cache is working fine, and +I'm using the cached address. They are used for kernel entry in any case.} Finally, I read in the books that k0 and k1 are in fact normal general purpose registers. So while they are by convention used for kernel purposes, and -compilers will likely not touch them, the kernel can't actually rely on them -not being changed by user code. So I'll need to use a different approach for +compilers will likely not touch them, Iris can't actually rely on them not +being changed by user code. So I'll need to use a different approach for saving the processor state. The solution is trivial: use k1 as before, but first load it from a fixed memory location. To be able to store k1 itself, a page must be mapped in kseg3 (wired into the tlb), which can then be accessed @@ -350,15 +369,15 @@ So now I need to accept calls from programs and handle them. For this, I need to decide what such a call looks like. It will need to send a capability to invoke, and a number of capabilities and numbers as arguments. I chose to send four capabilities (so five in total) and also four numbers. The way to send -these is by setting registers before making a system call. Similarly, when the -kernel returns a message, it sets the registers before returing to the program. +these is by setting registers before making a system call. Similarly, when +Iris returns a message, she sets the registers before returing to the program. I wrote one file with assembly for receiving interrupts and exceptions (including system calls) and one file with functions called from this assembly to do most of the work. For syscall, I call an arch-specific\footnote{I split off all arch-specific parts into a limited number of files. While I am -currently writing the kernel only for the Trendtac, I'm trying to make it easy -to port it to other machines later.} invoke function, which reads the message, +currently writing Iris only for the Trendtac, I'm trying to make it easy to +port her to other machines later.} invoke function, which reads the message, puts it in variables, and calls the real invoke function. The real invoke function analyzes the called capability: if it is in page 0 @@ -449,9 +468,9 @@ but can be reused. Another nice optimization is \textit{copy on write}: a page is shared read-only, and when a page-fault happens, the kernel will copy the contents, so that the other owner(s) don't see the changes. For the moment, I don't -implemnt this. I'm not sure if I want it in the kernel at all. It can well be -implemented using an exception handler in user space, and is not used enough to -spend kernel space on, I think. But I can change my mind on that later. +implemnt this. I'm not sure if I want it in Iris at all. It can well be +implemented using an exception handler in user space, and may not be used +enough to spend kernel space on. But I can change my mind on that later. \section{Memory listing} The last thing to do for now is allowing a memory to be listed. That is, @@ -459,4 +478,14 @@ having a suitably priviledged capability to a Memory should allow a program to see what's in it. In particular, what objects it holds, and where pages are mapped. Probably also what messages are in a receiver's queue. +\section{A name for the kernel} +However, at this point I am publishing the existence of the kernel, and so I +need to give it a name. I like Greek mythology, so I decided to make it a +Greek god. Because the kernel is mostly doing communication between programs, +while the programs do the real work on the system, I thought of Hermes, the +messenger of the gods. However, I don't really like his name, and I want a +logo which is furrier than a winged boot or staff. So I chose Iris, who is +also a messenger of gods, but she has a rainbow symbol. This is much nicer for +creating a logo. + \end{document} diff --git a/schedule.ccp b/schedule.ccp index 1ebbb90..2415ab4 100644 --- a/schedule.ccp +++ b/schedule.ccp @@ -1,4 +1,21 @@ #pypp 0 +// Iris: micro-kernel for a capability-based operating system. +// schedule.ccp: Thread scheduling. +// Copyright 2009 Bas Wijnen +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + #include "kernel.hh" void Thread::run ():