├── .cproject ├── .gitignore ├── .project ├── Include └── multiboot.h ├── Kernel.doxyfile ├── Makefile ├── apic.c ├── apic.h ├── cdi ├── audio.h ├── bios.h ├── cache.c ├── cache.h ├── cdi-osdep.h ├── cdi.c ├── cdi.h ├── cmos.h ├── dma.h ├── fs.c ├── fs.h ├── io.h ├── lists.c ├── lists.h ├── mem.c ├── mem.h ├── mempool.h ├── misc.c ├── misc.h ├── net.h ├── pci.c ├── pci.h ├── scsi.c ├── scsi.h ├── storage.c ├── storage.h ├── usb-structures.h ├── usb.h └── usb_hcd.h ├── cmos.c ├── cmos.h ├── config.h ├── console.c ├── console.h ├── cpu.c ├── cpu.h ├── devicemng.c ├── devicemng.h ├── display.c ├── display.h ├── driver ├── ahci │ ├── ahci.h │ ├── disk.c │ └── main.c ├── ata │ ├── ata.c │ ├── atapi.c │ ├── device.c │ ├── device.h │ ├── main.c │ └── request.c ├── ext2 │ ├── dir.c │ ├── ext2_cdi.h │ ├── file.c │ ├── init.c │ ├── libext2 │ │ ├── directory.c │ │ ├── file.c │ │ ├── fs.c │ │ ├── include │ │ │ ├── blockgroup.h │ │ │ ├── directory.h │ │ │ ├── ext2.h │ │ │ ├── file.h │ │ │ ├── inode.h │ │ │ ├── superblock.h │ │ │ └── symlink.h │ │ ├── inode.c │ │ ├── superblock.c │ │ └── symlink.c │ ├── libext2_cache.c │ ├── main.c │ ├── res.c │ ├── resources.c │ └── symlinks.c ├── iso9660 │ ├── dir.c │ ├── directory_record.h │ ├── file.c │ ├── init.c │ ├── iso9660_cdi.h │ ├── iso9660def.h │ ├── main.c │ ├── res.c │ ├── resources.c │ ├── rockridge.c │ ├── rockridge.h │ ├── sector.c │ ├── volume_descriptor.c │ └── volume_descriptor.h └── random │ ├── main.c │ ├── mt.c │ ├── mt.h │ ├── random.c │ └── random.h ├── drivermanager.c ├── drivermanager.h ├── gdt.c ├── gdt.h ├── idt.c ├── idt.h ├── include ├── assert.h ├── bits │ ├── error.h │ ├── sys_types.h │ ├── syscall_numbers.h │ └── types.h ├── complex.h ├── ctype.h ├── dirent.h ├── errno.h ├── fenv.h ├── limits.h ├── lock.h ├── math.h ├── path.h ├── setjmp.h ├── signal.h ├── stdarg.h ├── stdbool.h ├── stddef.h ├── stdint.h ├── stdio.h ├── stdlib.h ├── string.h ├── sys │ └── types.h ├── syscall.h ├── time.h ├── unistd.h └── userlib.h ├── interrupts.S ├── isr.c ├── isr.h ├── kernel.ld ├── keyboard.c ├── keyboard.h ├── lib ├── Makefile ├── lock.c ├── path.c ├── posix │ ├── dirent.c │ └── unistd.c ├── start.S └── stdlibc │ ├── assert.c │ ├── ctype.c │ ├── errno.c │ ├── fenv.c │ ├── math.c │ ├── setjmp.S │ ├── signal.c │ ├── stdio.c │ ├── stdlib.c │ ├── string.c │ ├── syscall.c │ ├── time.c │ └── userlib.c ├── loader ├── elf.c ├── elf.h ├── loader.c └── loader.h ├── main.c ├── mm ├── memory.h ├── mm.c ├── mm.h ├── paging.c ├── paging.h ├── pmm.c ├── pmm.h ├── vmm.c └── vmm.h ├── partition.c ├── partition.h ├── pci.c ├── pci.h ├── pic.c ├── pic.h ├── pit.c ├── pit.h ├── sound.c ├── sound.h ├── start.S ├── syscalls.c ├── syscalls.h ├── tasks ├── cleaner.c ├── cleaner.h ├── dispatcher.c ├── dispatcher.h ├── pm.c ├── pm.h ├── scheduler.c ├── scheduler.h ├── thread.c └── thread.h ├── tss.c ├── tss.h ├── util ├── avl.c ├── avl.h ├── bit.h ├── debug.c ├── debug.h ├── disasm.c ├── disasm.h ├── hash_helpers.c ├── hash_helpers.h ├── hashmap.c ├── hashmap.h ├── list.c ├── list.h ├── mutex.c ├── mutex.h ├── queue.c ├── queue.h ├── refcount.c ├── refcount.h ├── ring.c ├── ring.h ├── semaphore.c ├── semaphore.h ├── stack.c ├── stack.h ├── system.c ├── system.h ├── util.c └── util.h ├── version.c ├── version.h └── vfs ├── cdifs.c ├── cdifs.h ├── devfs.c ├── devfs.h ├── node.c ├── node.h ├── vfs.c └── vfs.h /.gitignore: -------------------------------------------------------------------------------- 1 | /doc 2 | /build 3 | /lib/build 4 | /.metadata/ 5 | /.vscode/ 6 | /.settings/ -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Kernel 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | ?name? 14 | 15 | 16 | 17 | org.eclipse.cdt.make.core.append_environment 18 | true 19 | 20 | 21 | org.eclipse.cdt.make.core.autoBuildTarget 22 | all 23 | 24 | 25 | org.eclipse.cdt.make.core.buildArguments 26 | 27 | 28 | 29 | org.eclipse.cdt.make.core.buildCommand 30 | make 31 | 32 | 33 | org.eclipse.cdt.make.core.buildLocation 34 | ${workspace_loc:/V0.1/Debug} 35 | 36 | 37 | org.eclipse.cdt.make.core.cleanBuildTarget 38 | clean 39 | 40 | 41 | org.eclipse.cdt.make.core.contents 42 | org.eclipse.cdt.make.core.activeConfigSettings 43 | 44 | 45 | org.eclipse.cdt.make.core.enableAutoBuild 46 | false 47 | 48 | 49 | org.eclipse.cdt.make.core.enableCleanBuild 50 | true 51 | 52 | 53 | org.eclipse.cdt.make.core.enableFullBuild 54 | true 55 | 56 | 57 | org.eclipse.cdt.make.core.fullBuildTarget 58 | all 59 | 60 | 61 | org.eclipse.cdt.make.core.stopOnError 62 | true 63 | 64 | 65 | org.eclipse.cdt.make.core.useDefaultBuildCmd 66 | true 67 | 68 | 69 | 70 | 71 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 72 | full,incremental, 73 | 74 | 75 | 76 | 77 | 78 | org.eclipse.cdt.core.cnature 79 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 80 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 81 | 82 | 83 | -------------------------------------------------------------------------------- /Include/multiboot.h: -------------------------------------------------------------------------------- 1 | /* 2 | * multiboot.h 3 | * 4 | * Created on: 02.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef MULTIBOOT_H_ 9 | #define MULTIBOOT_H_ 10 | 11 | #include "stdint.h" 12 | 13 | typedef struct 14 | { 15 | uint32_t mod_start; //Startaddresse des Moduls 16 | uint32_t mod_end; //Endaddresse des Moduls 17 | uint32_t name; //Name des Moduls (0 terminierter ASCII-String) 18 | uint32_t reserved; //Reserviert (0) 19 | }mods; 20 | 21 | typedef struct{ 22 | uint32_t size; //Gibt die Grösse des Eintrag - 4 an 23 | uint64_t base_addr; //Basisadresse des Speicherbereichs 24 | uint64_t length; //Länge des Speicherbereichs 25 | uint32_t type; //Typ des Speicherbereichs (1 = frei, ansonsten belegt) 26 | }__attribute__((packed)) mmap; 27 | 28 | typedef struct 29 | { //Gültig wenn mbs_flags[x] gesetzt 30 | uint32_t mbs_flags; //immer 31 | uint32_t mbs_mem_lower; //0 32 | uint32_t mbs_mem_upper; //0 33 | uint32_t mbs_bootdevice; //1 34 | uint32_t mbs_cmdline; //2 35 | uint32_t mbs_mods_count; //3 36 | uint32_t mbs_mods_addr; //3 37 | uint32_t mbs_syms[4]; //4 oder 5 38 | uint32_t mbs_mmap_length; //6 39 | uint32_t mbs_mmap_addr; //6 40 | uint32_t mbs_drives_length; //7 41 | uint32_t mbs_drives_addr; //7 42 | uint32_t mbs_config_table; //8 43 | uint32_t mbs_boot_loader_name; //9 44 | uint32_t mbs_apm_table; //10 45 | uint32_t mbs_vbe_control_info; //11 46 | uint32_t mbs_vbe_mode_info; //11 47 | uint16_t mbs_vbe_mode; //11 48 | uint16_t mbs_vbe_interface_seg; //11 49 | uint16_t mbs_vbe_interface_off; //11 50 | uint16_t mbs_vbe_interface_len; //11 51 | }multiboot_structure; 52 | 53 | #endif /* MULTIBOOT_H_ */ 54 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC = x86_64-elf-gcc 2 | LD = x86_64-elf-gcc 3 | AS = x86_64-elf-as 4 | RM = rm -rf 5 | 6 | OUTPUT_DIR = build 7 | 8 | CPPFLAGS += -I"./include" -I"./cdi" -I"./driver" -I"./Include" -I"./loader" -I"./mm" -I"./tasks" -I"./util" -I"./vfs" -I"." 9 | CFLAGS += -gdwarf-4 -Wall -Wextra -fmessage-length=0 -ffreestanding -fno-stack-protector -mno-red-zone -fno-omit-frame-pointer -std=gnu99 -mcx16 -mno-sse 10 | LDFLAGS += -nostdlib -static -T./kernel.ld -z max-page-size=0x1000 11 | C_SRCS = $(shell find -name '*.c' ! -path './lib/stdlibc/math.c') 12 | S_SRCS = ./interrupts.S ./start.S 13 | 14 | C_OBJS = $(patsubst ./%,$(OUTPUT_DIR)/%,$(C_SRCS:.c=.o)) 15 | S_OBJS = $(patsubst ./%,$(OUTPUT_DIR)/%,$(S_SRCS:.S=.o)) 16 | OBJS := $(C_OBJS) $(S_OBJS) 17 | DEPS := $(OBJS:.o=.d) 18 | 19 | ifeq ($(BUILD_CONFIG), release) 20 | CFLAGS += -O3 21 | else 22 | CFLAGS += -Og 23 | endif 24 | 25 | 26 | #get git information 27 | DIRTY= 28 | ifneq ($(shell git diff --shortstat 2> /dev/null),) 29 | DIRTY=-dirty 30 | endif 31 | GIT_COMMIT_ID=$(shell git rev-parse HEAD)$(DIRTY) 32 | GIT_BRANCH=$(shell git rev-parse --abbrev-ref HEAD) 33 | 34 | .PHONY: all 35 | all: kernel libc 36 | 37 | .PHONY: release 38 | release: 39 | $(MAKE) BUILD_CONFIG=$@ 40 | 41 | .PHONY: install-headers 42 | install-headers: 43 | $(MAKE) -C lib install-headers 44 | 45 | .PHONY: install-libc 46 | install-libc: 47 | $(MAKE) -C lib install 48 | 49 | .PHONY: libc 50 | libc: 51 | $(MAKE) BUILD_CONFIG=$(BUILD_CONFIG) -C lib 52 | 53 | .PHONY: kernel 54 | kernel: $(OUTPUT_DIR)/kernel 55 | 56 | #Pull in dependency info for *existing* .o files 57 | -include $(DEPS) 58 | 59 | $(OUTPUT_DIR)/kernel: CPPFLAGS += -DBUILD_KERNEL 60 | $(OUTPUT_DIR)/kernel: $(OBJS) 61 | $(LD) $(LDFLAGS) -o $@ $^ 62 | 63 | $(OUTPUT_DIR)/driver/ext2/%: CPPFLAGS += -I"./driver/ext2/libext2/include" 64 | 65 | $(OUTPUT_DIR)/version.o: force_build 66 | $(OUTPUT_DIR)/version.o: CPPFLAGS += -DGIT_BRANCH=$(GIT_BRANCH) -DGIT_COMMIT_ID=$(GIT_COMMIT_ID) 67 | 68 | $(OUTPUT_DIR)/%.o: %.c 69 | @mkdir -p $(@D) 70 | $(CC) $(CFLAGS) $(CPPFLAGS) -MMD -MP -MT $@ -c $< -o $@ 71 | 72 | $(OUTPUT_DIR)/%.o: %.S 73 | @mkdir -p $(@D) 74 | $(AS) -64 --defsym BUILD_KERNEL= -o $@ $< 75 | 76 | .PHONY: clean 77 | clean: clean-kernel clean-libc 78 | 79 | .PHONY: clean-kernel 80 | clean-kernel: 81 | -$(RM) $(OUTPUT_DIR) 82 | 83 | .PHONY: clean-libc 84 | clean-libc: 85 | -$(MAKE) -C lib clean 86 | 87 | force_build: 88 | -------------------------------------------------------------------------------- /apic.c: -------------------------------------------------------------------------------- 1 | /* 2 | * apic.c 3 | * 4 | * Created on: 18.02.2015 5 | * Author: pascal 6 | */ 7 | 8 | #include "apic.h" 9 | #include "cpu.h" 10 | #include "memory.h" 11 | #include "vmm.h" 12 | #include "pmm.h" 13 | 14 | #define APIC_BASE_MSR 0x1B 15 | 16 | #define APIC_REG_SPIV 0xF0 17 | #define APIC_REG_ICR_LOW 0x300 18 | #define APIC_REG_ICR_HIGH 0x310 19 | #define APIC_REG_DIV_CONFIG 0x3E0 20 | #define APIC_REG_LVT_TIMER 0x320 21 | #define APIC_REG_LVT_THERM 0x330 22 | #define APIC_REG_LVT_PERFMON 0x340 23 | #define APIC_REG_LVT_LINT0 0x350 24 | #define APIC_REG_LVT_LINT1 0x360 25 | #define APIC_REG_LVT_ERROR 0x370 26 | 27 | typedef struct{ 28 | paddr_t physBase; 29 | void *virtBase; 30 | }apic_info_t; 31 | 32 | static apic_info_t apic_info; 33 | 34 | bool apic_available() 35 | { 36 | return (cpu_cpuid(0x00000001).edx >> 9) & 1; 37 | } 38 | 39 | void apic_Init() 40 | { 41 | //Basisaddresse auslesen 42 | apic_info.physBase = cpu_MSRread(APIC_BASE_MSR); 43 | 44 | //Speicherbereich mappen 45 | apic_info.virtBase = vmm_Map(&kernel_context, NULL, apic_info.physBase, 1, VMM_FLAGS_GLOBAL | VMM_FLAGS_NX | VMM_FLAGS_WRITE | VMM_FLAGS_NO_CACHE); 46 | 47 | //APIC aktivieren 48 | apic_Write(APIC_REG_SPIV, 1 << 8); 49 | } 50 | 51 | /* 52 | * Ein APIC-Register auslesen 53 | * 54 | * Parameter: offset = Offset der Speicherstelle 55 | * 56 | * Rückgabe: Wert der Speicherstelle 57 | */ 58 | uint32_t apic_Read(uintptr_t offset) 59 | { 60 | uint32_t *ptr = apic_info.virtBase + offset; 61 | return *ptr; 62 | } 63 | 64 | /* 65 | * In ein APIC-Register schreiben 66 | * 67 | * Parameter: offset = Offset der Speicherstelle 68 | * value = Wert der geschrieben werden soll 69 | */ 70 | void apic_Write(uintptr_t offset, uint32_t value) 71 | { 72 | uint32_t *ptr = apic_info.virtBase + offset; 73 | *ptr = value; 74 | } 75 | -------------------------------------------------------------------------------- /apic.h: -------------------------------------------------------------------------------- 1 | /* 2 | * apic.h 3 | * 4 | * Created on: 18.02.2015 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef APIC_H_ 9 | #define APIC_H_ 10 | 11 | #include "stdbool.h" 12 | #include "stdint.h" 13 | 14 | void apic_Init(); 15 | bool apic_available(); 16 | uint32_t apic_Read(uintptr_t offset); 17 | void apic_Write(uintptr_t offset, uint32_t value); 18 | 19 | #endif /* APIC_H_ */ 20 | -------------------------------------------------------------------------------- /cdi/bios.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008 Mathias Gottschlag 3 | * 4 | * This program is free software. It comes without any warranty, to 5 | * the extent permitted by applicable law. You can redistribute it 6 | * and/or modify it under the terms of the Do What The Fuck You Want 7 | * To Public License, Version 2, as published by Sam Hocevar. See 8 | * http://sam.zoy.org/projects/COPYING.WTFPL for more details. 9 | */ 10 | 11 | #ifndef _CDI_BIOS_H_ 12 | #define _CDI_BIOS_H_ 13 | 14 | #include 15 | 16 | #include 17 | 18 | struct cdi_bios_registers { 19 | uint16_t ax; 20 | uint16_t bx; 21 | uint16_t cx; 22 | uint16_t dx; 23 | uint16_t si; 24 | uint16_t di; 25 | uint16_t ds; 26 | uint16_t es; 27 | }; 28 | 29 | /** 30 | * Struktur zum Zugriff auf Speicherbereiche des 16bit-Prozesses 31 | */ 32 | struct cdi_bios_memory { 33 | /** 34 | * Virtuelle Addresse im Speicher des 16bit-Prozesses. Muss unterhalb von 35 | * 0xC0000 liegen. 36 | */ 37 | uintptr_t dest; 38 | /** 39 | * Pointer auf reservierten Speicher für die Daten des Speicherbereichs. Wird 40 | * beim Start des Tasks zum Initialisieren des Bereichs benutzt und erhaelt 41 | * auch wieder die Daten nach dem BIOS-Aufruf. 42 | */ 43 | void *src; 44 | /** 45 | * Laenge des Speicherbereichs 46 | */ 47 | uint16_t size; 48 | }; 49 | 50 | #ifdef __cplusplus 51 | extern "C" { 52 | #endif 53 | 54 | /** 55 | * Ruft den BIOS-Interrupt 0x10 auf. 56 | * @param registers Pointer auf eine Register-Struktur. Diese wird beim Aufruf 57 | * in die Register des Tasks geladen und bei Beendigung des Tasks wieder mit den 58 | * Werten des Tasks gefuellt. 59 | * @param memory Speicherbereiche, die in den Bios-Task kopiert und bei Beendigung 60 | * des Tasks wieder zurueck kopiert werden sollen. Die Liste ist vom Typ struct 61 | * cdi_bios_memory. 62 | * @return 0, wenn der Aufruf erfolgreich war, -1 bei Fehlern 63 | */ 64 | int cdi_bios_int10(struct cdi_bios_registers *registers, cdi_list_t memory); 65 | 66 | #ifdef __cplusplus 67 | }; // extern "C" 68 | #endif 69 | 70 | #endif 71 | 72 | -------------------------------------------------------------------------------- /cdi/cmos.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008 Matthew Iselin 3 | * 4 | * This program is free software. It comes without any warranty, to 5 | * the extent permitted by applicable law. You can redistribute it 6 | * and/or modify it under the terms of the Do What The Fuck You Want 7 | * To Public License, Version 2, as published by Sam Hocevar. See 8 | * http://sam.zoy.org/projects/COPYING.WTFPL for more details. 9 | */ 10 | 11 | #ifndef _CDI_CMOS_H_ 12 | #define _CDI_CMOS_H_ 13 | 14 | #include 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | /** 21 | * Performs CMOS reads 22 | * @param index Index within CMOS RAM to read from. 23 | * @return Result of reading CMOS RAM at specified index. 24 | */ 25 | uint8_t cdi_cmos_read(uint8_t index); 26 | 27 | /** 28 | * Performs CMOS writes 29 | * @param index Index within CMOS RAM to write to. 30 | * @param value Value to write to the CMOS 31 | */ 32 | void cdi_cmos_write(uint8_t index, uint8_t value); 33 | 34 | #ifdef __cplusplus 35 | }; // extern "C" 36 | #endif 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /cdi/dma.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 Antoine Kaufmann 3 | * 4 | * This program is free software. It comes without any warranty, to 5 | * the extent permitted by applicable law. You can redistribute it 6 | * and/or modify it under the terms of the Do What The Fuck You Want 7 | * To Public License, Version 2, as published by Sam Hocevar. See 8 | * http://sam.zoy.org/projects/COPYING.WTFPL for more details. 9 | */ 10 | 11 | #ifndef _CDI_DMA_H_ 12 | #define _CDI_DMA_H_ 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | 19 | struct cdi_dma_handle { 20 | uint8_t channel; 21 | size_t length; 22 | uint8_t mode; 23 | void* buffer; 24 | 25 | cdi_dma_osdep meta; 26 | }; 27 | 28 | // Geraet => Speicher 29 | #define CDI_DMA_MODE_READ (1 << 2) 30 | // Speicher => Geraet 31 | #define CDI_DMA_MODE_WRITE (2 << 2) 32 | #define CDI_DMA_MODE_ON_DEMAND (0 << 6) 33 | #define CDI_DMA_MODE_SINGLE (1 << 6) 34 | #define CDI_DMA_MODE_BLOCK (2 << 6) 35 | 36 | 37 | #ifdef __cplusplus 38 | extern "C" { 39 | #endif 40 | 41 | /** 42 | * Initialisiert einen Transport per DMA 43 | * 44 | * @return 0 bei Erfolg, -1 im Fehlerfall 45 | */ 46 | int cdi_dma_open(struct cdi_dma_handle* handle, uint8_t channel, uint8_t mode, 47 | size_t length, void* buffer); 48 | 49 | /** 50 | * Liest Daten per DMA ein 51 | * 52 | * @return 0 bei Erfolg, -1 im Fehlerfall 53 | */ 54 | int cdi_dma_read(struct cdi_dma_handle* handle); 55 | 56 | /** 57 | * Schreibt Daten per DMA 58 | * 59 | * @return 0 bei Erfolg, -1 im Fehlerfall 60 | */ 61 | int cdi_dma_write(struct cdi_dma_handle* handle); 62 | 63 | /** 64 | * Schliesst das DMA-Handle wieder 65 | * 66 | * @return 0 bei Erfolg, -1 im Fehlerfall 67 | */ 68 | int cdi_dma_close(struct cdi_dma_handle* handle); 69 | 70 | #ifdef __cplusplus 71 | }; // extern "C" 72 | #endif 73 | 74 | #endif 75 | 76 | -------------------------------------------------------------------------------- /cdi/fs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * fs.c 3 | * 4 | * Created on: 13.08.2013 5 | * Author: pascal 6 | */ 7 | 8 | #include "fs.h" 9 | #include "vfs.h" 10 | 11 | /** 12 | * Dateisystemtreiber-Struktur initialisieren 13 | * 14 | * @param driver Zeiger auf den Treiber 15 | */ 16 | void cdi_fs_driver_init(struct cdi_fs_driver* driver) 17 | { 18 | driver->drv.type = CDI_FILESYSTEM; 19 | cdi_driver_init((struct cdi_driver*)driver); 20 | } 21 | 22 | /** 23 | * Dateisystemtreiber-Struktur zerstoeren 24 | * 25 | * @param driver Zeiger auf den Treiber 26 | */ 27 | void cdi_fs_driver_destroy(struct cdi_fs_driver* driver) 28 | { 29 | cdi_driver_destroy((struct cdi_driver*)driver); 30 | } 31 | 32 | /** 33 | * Quelldateien fuer ein Dateisystem lesen 34 | * XXX Brauchen wir hier auch noch irgendwas errno-Maessiges? 35 | * 36 | * @param fs Pointer auf die FS-Struktur des Dateisystems 37 | * @param start Position von der an gelesen werden soll 38 | * @param size Groesse des zu lesenden Datenblocks 39 | * @param buffer Puffer in dem die Daten abgelegt werden sollen 40 | * 41 | * @return die Anzahl der gelesenen Bytes 42 | */ 43 | size_t cdi_fs_data_read(struct cdi_fs_filesystem* fs, uint64_t start, 44 | size_t size, void* buffer) 45 | { 46 | return vfs_Read(fs->osdep.fp, start, size, buffer); 47 | } 48 | 49 | /** 50 | * Quellmedium eines Dateisystems beschreiben 51 | * XXX Brauchen wir hier auch noch irgendwas errno-Maessiges? 52 | * 53 | * @param fs Pointer auf die FS-Struktur des Dateisystems 54 | * @param start Position an die geschrieben werden soll 55 | * @param size Groesse des zu schreibenden Datenblocks 56 | * @param buffer Puffer aus dem die Daten gelesen werden sollen 57 | * 58 | * @return die Anzahl der geschriebenen Bytes 59 | */ 60 | size_t cdi_fs_data_write(struct cdi_fs_filesystem* fs, uint64_t start, 61 | size_t size, const void* buffer) 62 | { 63 | return vfs_Write(fs->osdep.fp, start, size, buffer); 64 | } 65 | -------------------------------------------------------------------------------- /cdi/io.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 Kevin Wolf 3 | * 4 | * This program is free software. It comes without any warranty, to 5 | * the extent permitted by applicable law. You can redistribute it 6 | * and/or modify it under the terms of the Do What The Fuck You Want 7 | * To Public License, Version 2, as published by Sam Hocevar. See 8 | * http://sam.zoy.org/projects/COPYING.WTFPL for more details. 9 | */ 10 | 11 | #ifndef _CDI_IO_H_ 12 | #define _CDI_IO_H_ 13 | 14 | #include 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | static inline uint16_t cdi_inw(uint16_t _port) 21 | { 22 | uint16_t result; 23 | asm volatile ("inw %1, %0" : "=a" (result) : "Nd" (_port)); 24 | return result; 25 | } 26 | 27 | static inline uint8_t cdi_inb(uint16_t _port) 28 | { 29 | uint8_t result; 30 | asm volatile ("inb %1, %0" : "=a" (result) : "Nd" (_port)); 31 | return result; 32 | } 33 | 34 | static inline uint32_t cdi_inl(uint16_t _port) 35 | { 36 | uint32_t result; 37 | asm volatile("inl %1, %0" : "=a" (result) : "Nd" (_port)); 38 | return result; 39 | } 40 | 41 | 42 | 43 | static inline void cdi_outw(uint16_t _port, uint16_t _data) 44 | { 45 | asm volatile ("outw %0, %1" : : "a" (_data), "Nd" (_port)); 46 | } 47 | 48 | static inline void cdi_outb(uint16_t _port, uint8_t _data) 49 | { 50 | asm volatile ("outb %0, %1" : : "a" (_data), "Nd" (_port)); 51 | } 52 | 53 | static inline void cdi_outl(uint16_t _port, uint32_t _data) 54 | { 55 | asm volatile ("outl %0, %1" : : "a"(_data), "Nd" (_port)); 56 | } 57 | 58 | #ifdef __cplusplus 59 | }; // extern "C" 60 | #endif 61 | 62 | #endif 63 | 64 | -------------------------------------------------------------------------------- /cdi/mempool.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (c) 2009 Kevin Wolf * 3 | * * 4 | * Permission is hereby granted, free of charge, to any person obtaining a * 5 | * copy of this software and associated documentation files (the "Software"), * 6 | * to deal in the Software without restriction, including without limitation * 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 8 | * and/or sell copies of the Software, and to permit persons to whom the * 9 | * Software is furnished to do so, subject to the following conditions: * 10 | * * 11 | * The above copyright notice and this permission notice shall be included in * 12 | * all copies or substantial portions of the Software. * 13 | * * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * 17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * 20 | * DEALINGS IN THE SOFTWARE. * 21 | *****************************************************************************/ 22 | 23 | #ifndef CDI_MEMPOOL_H 24 | #define CDI_MEMPOOL_H 25 | 26 | #include 27 | #include 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | struct cdi_mempool; 34 | 35 | struct cdi_mempool* cdi_mempool_create(size_t pool_size, size_t object_size); 36 | int cdi_mempool_get(struct cdi_mempool* pool, void** obj, uintptr_t* phys_obj); 37 | int cdi_mempool_put(struct cdi_mempool* pool, void* obj); 38 | 39 | #ifdef __cplusplus 40 | }; // extern "C" 41 | #endif 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /cdi/net.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007 Kevin Wolf 3 | * 4 | * This program is free software. It comes without any warranty, to 5 | * the extent permitted by applicable law. You can redistribute it 6 | * and/or modify it under the terms of the Do What The Fuck You Want 7 | * To Public License, Version 2, as published by Sam Hocevar. See 8 | * http://sam.zoy.org/projects/COPYING.WTFPL for more details. 9 | */ 10 | 11 | /** 12 | * Treiber fuer Netzwerkkarten 13 | * \defgroup net 14 | */ 15 | /*\@{*/ 16 | 17 | #ifndef _CDI_NET_H_ 18 | #define _CDI_NET_H_ 19 | 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | struct cdi_net_device { 26 | struct cdi_device dev; 27 | uint64_t mac : 48; 28 | int number; 29 | }; 30 | 31 | struct cdi_net_driver { 32 | struct cdi_driver drv; 33 | 34 | void (*send_packet) 35 | (struct cdi_net_device* device, void* data, size_t size); 36 | }; 37 | 38 | 39 | #ifdef __cplusplus 40 | extern "C" { 41 | #endif 42 | 43 | /** 44 | * Initialisiert die Datenstrukturen fuer einen Netzerktreiber 45 | * (erzeugt die devices-Liste) 46 | */ 47 | void cdi_net_driver_init(struct cdi_net_driver* driver); 48 | 49 | /** 50 | * Deinitialisiert die Datenstrukturen fuer einen Netzwerktreiber 51 | * (gibt die devices-Liste frei) 52 | */ 53 | void cdi_net_driver_destroy(struct cdi_net_driver* driver); 54 | 55 | /** 56 | * Initialisiert eine neue Netzwerkkarte 57 | */ 58 | void cdi_net_device_init(struct cdi_net_device* device); 59 | 60 | /** 61 | * Wird von Netzwerktreibern aufgerufen, wenn ein Netzwerkpaket 62 | * empfangen wurde. 63 | */ 64 | void cdi_net_receive( 65 | struct cdi_net_device* device, void* buffer, size_t size); 66 | 67 | #ifdef __cplusplus 68 | }; // extern "C" 69 | #endif 70 | 71 | #endif 72 | 73 | /*\@}*/ 74 | 75 | -------------------------------------------------------------------------------- /cdi/scsi.c: -------------------------------------------------------------------------------- 1 | /* 2 | * scsi.c 3 | * 4 | * Created on: 02.08.2013 5 | * Author: pascal 6 | */ 7 | 8 | #include "scsi.h" 9 | #include "stdlib.h" 10 | #include "devicemng.h" 11 | 12 | /** 13 | * Initialisiert die Datenstrukturen fuer einen SCSI-Treiber 14 | */ 15 | void cdi_scsi_driver_init(struct cdi_scsi_driver* driver) 16 | { 17 | driver->drv.type = CDI_SCSI; 18 | cdi_driver_init((struct cdi_driver*)driver); 19 | } 20 | 21 | /** 22 | * Deinitialisiert die Datenstrukturen fuer einen SCSI-Treiber 23 | */ 24 | void cdi_scsi_driver_destroy(struct cdi_scsi_driver* driver) 25 | { 26 | cdi_driver_destroy((struct cdi_driver*)driver); 27 | } 28 | 29 | /** 30 | * Initialisiert ein neues SCSI-Geraet 31 | * 32 | * Der Typ der Geraetes muss bereits gesetzt sein 33 | */ 34 | void cdi_scsi_device_init(struct cdi_scsi_device* device) 35 | { 36 | device->dev.bus_data = malloc(sizeof(struct cdi_bus_data)); 37 | device->dev.bus_data->bus_type = CDI_SCSI; 38 | dmng_registerDevice((struct cdi_device*)device); 39 | } 40 | -------------------------------------------------------------------------------- /cdi/scsi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008 Janosch Graef 3 | * 4 | * This program is free software. It comes without any warranty, to 5 | * the extent permitted by applicable law. You can redistribute it 6 | * and/or modify it under the terms of the Do What The Fuck You Want 7 | * To Public License, Version 2, as published by Sam Hocevar. See 8 | * http://sam.zoy.org/projects/COPYING.WTFPL for more details. 9 | */ 10 | 11 | /** 12 | * Treiber fuer SCSI-Geraete 13 | * \defgroup scsi 14 | */ 15 | /*\@{*/ 16 | 17 | #ifndef _CDI_SCSI_H_ 18 | #define _CDI_SCSI_H_ 19 | 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | /// SCSI-Paket 26 | struct cdi_scsi_packet { 27 | /// LUN to address 28 | int lun; 29 | 30 | /// Buffer zum Senden oder Empfangen von Daten 31 | void *buffer; 32 | 33 | /// Groesse des Buffers 34 | size_t bufsize; 35 | 36 | /// Ob gelesen oder geschrieben werden soll 37 | enum { 38 | CDI_SCSI_NODATA, 39 | CDI_SCSI_READ, 40 | CDI_SCSI_WRITE, 41 | } direction; 42 | 43 | /// SCSI-Befehl 44 | uint8_t command[16]; 45 | 46 | /// Groesse des SCSI-Befehls 47 | size_t cmdsize; 48 | }; 49 | 50 | /// SCSI-Geraet 51 | struct cdi_scsi_device { 52 | 53 | struct cdi_device dev; 54 | 55 | /// Geraetetyp, der ueber SCSI angesteuert wird 56 | cdi_device_type_t type; 57 | 58 | /// Number of LUNs 59 | int lun_count; 60 | }; 61 | 62 | /// SCSI-Treiber 63 | struct cdi_scsi_driver { 64 | 65 | struct cdi_driver drv; 66 | 67 | /** 68 | * Sendet ein SCSI-Paket an das Geraet. 69 | * 70 | * @return SCSI-Fehlerstatus nach der Ausfuehrung des Befehls 71 | */ 72 | int (*request)(struct cdi_scsi_device *device, 73 | struct cdi_scsi_packet *packet); 74 | }; 75 | 76 | #ifdef __cplusplus 77 | extern "C" { 78 | #endif 79 | 80 | /** 81 | * Ein SCSI-Paket allozieren 82 | * 83 | * @param size Benoetigte Groesse 84 | * 85 | * @return Pointer auf das Paket oder NULL im Fehlerfall 86 | */ 87 | struct cdi_scsi_packet* cdi_scsi_packet_alloc(size_t size); 88 | 89 | /** 90 | * Ein SCSI-Paket freigeben 91 | * 92 | * @param packet Pointer auf das Paket 93 | */ 94 | void cdi_scsi_packet_free(struct cdi_scsi_packet* packet); 95 | 96 | /** 97 | * Initialisiert die Datenstrukturen fuer einen SCSI-Treiber 98 | */ 99 | void cdi_scsi_driver_init(struct cdi_scsi_driver* driver); 100 | 101 | /** 102 | * Deinitialisiert die Datenstrukturen fuer einen SCSI-Treiber 103 | */ 104 | void cdi_scsi_driver_destroy(struct cdi_scsi_driver* driver); 105 | 106 | /** 107 | * Registiert einen SCSI-Treiber 108 | */ 109 | void cdi_scsi_driver_register(struct cdi_scsi_driver* driver); 110 | 111 | /** 112 | * Initialisiert ein neues SCSI-Geraet 113 | * 114 | * Der Typ der Geraetes muss bereits gesetzt sein 115 | */ 116 | void cdi_scsi_device_init(struct cdi_scsi_device* device); 117 | 118 | #ifdef __cplusplus 119 | }; // extern "C" 120 | #endif 121 | 122 | #endif 123 | 124 | /*\@}*/ 125 | -------------------------------------------------------------------------------- /cdi/storage.c: -------------------------------------------------------------------------------- 1 | /* 2 | * storage.c 3 | * 4 | * Created on: 02.08.2013 5 | * Author: pascal 6 | */ 7 | 8 | #include "storage.h" 9 | #include "stdlib.h" 10 | #include "devicemng.h" 11 | 12 | /** 13 | * \german 14 | * Initialisiert die Datenstrukturen fuer einen Massenspeichertreiber 15 | * (erzeugt die devices-Liste). Diese Funktion muss während der 16 | * Initialisierung eines Massenspeichertreibers aufgerufen werden. 17 | * \endgerman 18 | * \english 19 | * Initialises the data structures for a mass storage device. This function 20 | * must be called during initialisation of a mass storage driver. 21 | * \endenglish 22 | * 23 | */ 24 | void cdi_storage_driver_init(struct cdi_storage_driver* driver) 25 | { 26 | driver->drv.type = CDI_STORAGE; 27 | cdi_driver_init((struct cdi_driver*)driver); 28 | } 29 | 30 | /** 31 | * \german 32 | * Deinitialisiert die Datenstrukturen fuer einen Massenspeichertreiber 33 | * (gibt die devices-Liste frei) 34 | * \endgerman 35 | * \english 36 | * Deinitialises the data structures for a mass storage driver 37 | * \endenglish 38 | */ 39 | void cdi_storage_driver_destroy(struct cdi_storage_driver* driver) 40 | { 41 | cdi_driver_destroy((struct cdi_driver*)driver); 42 | } 43 | 44 | /** 45 | * \german 46 | * Meldet ein Massenspeichergerät beim Betriebssystem an. Diese Funktion muss 47 | * aufgerufen werden, nachdem ein Massenspeichertreiber alle notwendigen 48 | * Initialisierungen durchgeführt hat. 49 | * 50 | * Das Betriebssystem kann dann beispielsweise nach Partitionen auf dem Gerät 51 | * suchen und Gerätedateien verfügbar machen. 52 | * \endgerman 53 | * \english 54 | * Registers a mass storage device with the operating system. This function 55 | * must be called once a mass storage driver has completed all required 56 | * initialisations. 57 | * 58 | * The operation system may react to this e.g. with scanning the device for 59 | * partitions or creating device nodes for the user. 60 | * \endenglish 61 | */ 62 | void cdi_storage_device_init(struct cdi_storage_device* device) 63 | { 64 | device->dev.bus_data = malloc(sizeof(struct cdi_bus_data)); 65 | device->dev.bus_data->bus_type = CDI_STORAGE; 66 | dmng_registerDevice((struct cdi_device*)device); 67 | } 68 | -------------------------------------------------------------------------------- /cmos.h: -------------------------------------------------------------------------------- 1 | /* 2 | * cmos.h 3 | * 4 | * Created on: 30.06.2013 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef CMOS_H_ 9 | #define CMOS_H_ 10 | 11 | #include "stdint.h" 12 | #include 13 | 14 | typedef struct{ 15 | uint8_t Second, Minute, Hour; 16 | } Time_t; 17 | 18 | typedef struct{ 19 | uint8_t DayOfWeek, DayOfMonth, Month, Year; 20 | } Date_t; 21 | 22 | void cmos_Init(void); 23 | Time_t *cmos_GetTime(Time_t *Time); 24 | Date_t *cmos_GetDate(Date_t *Date); 25 | 26 | void cmos_Reboot(void); 27 | 28 | //Syscalls 29 | time_t cmos_syscall_timestamp(); 30 | 31 | #endif /* CMOS_H_ */ 32 | -------------------------------------------------------------------------------- /config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * config.h 3 | * 4 | * Created on: 12.03.2013 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef CONFIG_H_ 9 | #define CONFIG_H_ 10 | 11 | //Configuration File 12 | //#define DEBUGMODE 13 | 14 | #endif /* CONFIG_H_ */ 15 | -------------------------------------------------------------------------------- /console.h: -------------------------------------------------------------------------------- 1 | /* 2 | * console.h 3 | * 4 | * Created on: 27.01.2015 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef CONSOLE_H_ 9 | #define CONSOLE_H_ 10 | 11 | #include "stddef.h" 12 | #include "stdint.h" 13 | #include "stdbool.h" 14 | #include "lock.h" 15 | #include "queue.h" 16 | #include "keyboard.h" 17 | 18 | #define CONSOLE_AUTOREFRESH 1 19 | #define CONSOLE_AUTOSCROLL 2 20 | #define CONSOLE_RAW (1 << 2) 21 | #define CONSOLE_ECHO (1 << 3) 22 | 23 | typedef struct{ 24 | uint8_t x, y; 25 | }cursor_t; 26 | 27 | typedef struct{ 28 | KEY_t key; 29 | bool shift, altgr; 30 | }console_key_status_t; 31 | 32 | typedef struct{ 33 | uint8_t id; 34 | char *name; 35 | uint8_t flags; 36 | 37 | void* waitingThread; 38 | 39 | lock_t lock; 40 | 41 | void *buffer; 42 | void *screenBuffer; 43 | size_t usedRows, currentRow; 44 | uint16_t height, width; 45 | uint8_t color; 46 | cursor_t cursor; 47 | 48 | unsigned char ansi_buf[16]; 49 | uint8_t ansi_buf_ofs; 50 | cursor_t saved_cursor; 51 | 52 | console_key_status_t *inputBuffer; 53 | size_t inputBufferSize, inputBufferStart, inputBufferEnd; 54 | char *currentInputBuffer; 55 | size_t currentInputBufferSize; 56 | 57 | queue_t *outputBuffer; 58 | char *currentOutputBuffer; 59 | size_t currentOutputBufferPos; 60 | }console_t; 61 | 62 | extern console_t initConsole; 63 | 64 | void console_Init(); 65 | console_t *console_create(char *name, uint8_t color); 66 | console_t *console_getByName(char *name); 67 | void console_ansi_write(console_t *console, unsigned char c); 68 | void console_write(console_t *console, unsigned char c); 69 | void console_switch(uint8_t page); 70 | void console_changeColor(console_t *console, uint8_t color); 71 | void console_setCursor(console_t *console, cursor_t cursor); 72 | 73 | #endif /* CONSOLE_H_ */ 74 | -------------------------------------------------------------------------------- /devicemng.h: -------------------------------------------------------------------------------- 1 | /* 2 | * devicemng.h 3 | * 4 | * Created on: 16.08.2013 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef DEVICEMNG_H_ 9 | #define DEVICEMNG_H_ 10 | 11 | #include "cdi.h" 12 | #include "list.h" 13 | #include "stdint.h" 14 | #include "stddef.h" 15 | #include "vfs.h" 16 | #include "semaphore.h" 17 | 18 | typedef struct{ 19 | struct cdi_device *device; 20 | list_t partitions; 21 | semaphore_t semaphore; 22 | }device_t; 23 | 24 | void dmng_Init(void); 25 | void dmng_registerDevice(struct cdi_device *dev); 26 | 27 | #endif /* DEVICEMNG_H_ */ 28 | -------------------------------------------------------------------------------- /display.c: -------------------------------------------------------------------------------- 1 | /* 2 | * display.c 3 | * 4 | * Created on: 07.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #include "display.h" 9 | #include "util.h" 10 | #include "string.h" 11 | #include "console.h" 12 | #include "pm.h" 13 | #include "stdio.h" 14 | #include "cpu.h" 15 | 16 | #define GRAFIKSPEICHER 0xB8000 17 | 18 | uint8_t Spalte, Zeile; 19 | 20 | void Display_Init() 21 | { 22 | Display_Clear(); 23 | setColor(BG_BLACK | CL_WHITE); 24 | /*uint8_t Register; 25 | inb(0x3D8, Register); 26 | Register &= 0xDF; 27 | outb(0x3D8, Register);*/ 28 | } 29 | 30 | void display_refresh(const uint16_t *buffer, uint8_t cursor_x, uint8_t cursor_y) 31 | { 32 | memcpy((void*)GRAFIKSPEICHER, buffer, DISPLAY_COLS * DISPLAY_ROWS * sizeof(uint16_t)); 33 | setCursor(cursor_x, cursor_y); 34 | } 35 | 36 | void __attribute__((deprecated)) setColor(uint8_t Color) 37 | { 38 | //console_changeColor(pm_getConsole(), Color); 39 | } 40 | 41 | void setCursor(uint8_t x, uint8_t y) 42 | { 43 | //Diese Funktion kann auch extern aufgerufen werden, deshalb müssen hier die 44 | //Variablen "Spalte" und "Zeile" auch gesetzt werden. 45 | Spalte = (x <= 79) ? x : 79; 46 | Zeile = (y <= 24) ? y : 24; 47 | //Cursorposition verändern 48 | uint16_t CursorAddress = Zeile * 80 + Spalte; 49 | outb(0x3D4, 15); //Lowbyte der Cursorposition an Grafikkarte senden 50 | outb(0x3D5, CursorAddress & 0xFF); 51 | outb(0x3D4, 14); //Highbyte der Cursorposition an GK senden 52 | outb(0x3D5, CursorAddress >> 8); 53 | } 54 | 55 | void SysLog(char *Device, char *Text) 56 | { 57 | printf("[ \e[32m%s\e[37m ] %s\n", Device, Text); 58 | } 59 | 60 | void SysLogError(char *Device, char *Text) 61 | { 62 | printf("[ \e[31m%s\e[37m ] \e[31m%s\e[37m\n", Device, Text); 63 | } 64 | 65 | /* 66 | * Löscht den Bildschirminhalt 67 | */ 68 | void Display_Clear() 69 | { 70 | int i; 71 | char *gs = (char*)GRAFIKSPEICHER; 72 | for(i = 0; i < 4096; i++) 73 | gs[i] = 0; 74 | Zeile = Spalte = 0; 75 | } 76 | 77 | /* 78 | * Gibt eine Fehlermeldung aus und hält die CPU an (für immer). 79 | */ 80 | void Panic(char *Device, char *Text) 81 | { 82 | printf("\e[41;37m[ %s ] %s", Device, Text); 83 | console_switch(0); 84 | CPU_STOP(); 85 | } 86 | 87 | void hideCursor() 88 | { 89 | outb(0x3D4, 10); 90 | outb(0x3D5, 0x32); //Cursor deaktiviert 91 | } 92 | 93 | void showCursor() 94 | { 95 | outb(0x3D4, 10); 96 | outb(0x3D5, 0x64); //Cursor aktiviert 97 | } 98 | -------------------------------------------------------------------------------- /display.h: -------------------------------------------------------------------------------- 1 | /* 2 | * display.h 3 | * 4 | * Created on: 07.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef DISPLAY_H_ 9 | #define DISPLAY_H_ 10 | 11 | #include "stdint.h" 12 | #include "stddef.h" 13 | 14 | //Hintergrundfarben 15 | #define BG_BLACK 0x00 16 | #define BG_BLUE 0x10 17 | #define BG_GREEN 0x20 18 | #define BG_CYAN 0x30 19 | #define BG_RED 0x40 20 | #define BG_MAGENTA 0x50 21 | #define BG_BRAUN 0x60 22 | #define BG_LIGHT_GREY 0x70 23 | 24 | //Textfarben 25 | #define CL_BLACK 0x0 //Schwarz 26 | #define CL_BLUE 0x1 //Blau 27 | #define CL_GREEN 0x2 //Grün 28 | #define CL_CYAN 0x3 //Cyan 29 | #define CL_RED 0x4 //Rot 30 | #define CL_MAGENTA 0x5 //Magenta 31 | #define CL_BRAUN 0x6 //Braun 32 | #define CL_LIGHT_GREY 0x7 //Hellgrau 33 | #define CL_DARK_GREY 0x8 //Dunkelgrau 34 | #define CL_LIGHT_BLUE 0x9 //Hellblau 35 | #define CL_LIGHT_GREEN 0xA //Hellgrün 36 | #define CL_LIGHT_CYAN 0xB //Hellcyan 37 | #define CL_LIGHT_RED 0xC //Hellrot 38 | #define CL_LIGHT_MAGENTA 0xD //Hellmagenta 39 | #define CL_YELLOW 0xE //Gelb 40 | #define CL_WHITE 0xF //Weiss 41 | 42 | #define DISPLAY_ROWS 25 43 | #define DISPLAY_COLS 80 44 | 45 | extern uint8_t Spalte, Zeile; 46 | 47 | void Display_Init(void); 48 | void display_refresh(const uint16_t *buffer, uint8_t cursor_x, uint8_t cursor_y); 49 | void setColor(uint8_t Color); 50 | void putch(unsigned char c); 51 | void setCursor(uint8_t x, uint8_t y); 52 | void SysLog(char *Device, char *Text); 53 | void SysLogError(char *Device, char *Text); 54 | void Display_Clear(void); 55 | void Panic(char *Device, char *Text) __attribute__((noreturn)); 56 | void hideCursor(void); 57 | void showCursor(void); 58 | 59 | size_t Display_FileHandler(char *name, uint64_t start, size_t length, const void *buffer); 60 | 61 | #endif /* DISPLAY_H_ */ 62 | -------------------------------------------------------------------------------- /driver/ext2/dir.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008 The tyndur Project. All rights reserved. 3 | * 4 | * This code is derived from software contributed to the tyndur Project 5 | * by Antoine Kaufmann. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 3. All advertising materials mentioning features or use of this software 16 | * must display the following acknowledgement: 17 | * This product includes software developed by the tyndur Project 18 | * and its contributors. 19 | * 4. Neither the name of the tyndur Project nor the names of its 20 | * contributors may be used to endorse or promote products derived 21 | * from this software without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 25 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR 27 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 30 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 31 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 32 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 33 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | */ 35 | #include 36 | 37 | #include "ext2_cdi.h" 38 | 39 | 40 | cdi_list_t ext2_fs_dir_list(struct cdi_fs_stream* stream) 41 | { 42 | return stream->res->children; 43 | } 44 | 45 | int ext2_fs_dir_create_child(struct cdi_fs_stream* stream, const char* name, 46 | struct cdi_fs_res* parent) 47 | { 48 | struct ext2_fs_res* res = malloc(sizeof(*res)); 49 | struct ext2_fs_res* parent_res = (struct ext2_fs_res*) parent; 50 | 51 | memset(res, 0, sizeof(*res)); 52 | 53 | res->res.loaded = 1; 54 | 55 | res->res.name = strdup(name); 56 | res->res.res = &ext2_fs_res; 57 | 58 | cdi_list_push(parent_res->res.children, res); 59 | res->res.parent = parent; 60 | 61 | stream->res = (struct cdi_fs_res*) res; 62 | return 1; 63 | } 64 | 65 | -------------------------------------------------------------------------------- /driver/ext2/file.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008 The tyndur Project. All rights reserved. 3 | * 4 | * This code is derived from software contributed to the tyndur Project 5 | * by Antoine Kaufmann. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 3. All advertising materials mentioning features or use of this software 16 | * must display the following acknowledgement: 17 | * This product includes software developed by the tyndur Project 18 | * and its contributors. 19 | * 4. Neither the name of the tyndur Project nor the names of its 20 | * contributors may be used to endorse or promote products derived 21 | * from this software without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 25 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR 27 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 30 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 31 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 32 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 33 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | */ 35 | 36 | #include "ext2_cdi.h" 37 | 38 | size_t ext2_fs_file_read(struct cdi_fs_stream* stream, uint64_t start, 39 | size_t size, void* data) 40 | { 41 | struct ext2_fs_res* res = (struct ext2_fs_res*) stream->res; 42 | 43 | if (ext2_inode_readdata(res->inode, start, size, data)) { 44 | return size; 45 | } 46 | 47 | //TODO: error in stream setzen 48 | return 0; 49 | } 50 | 51 | size_t ext2_fs_file_write(struct cdi_fs_stream* stream, uint64_t start, 52 | size_t size, const void* data) 53 | { 54 | 55 | struct ext2_fs_res* res = (struct ext2_fs_res*) stream->res; 56 | 57 | //TODO: data muesste in writedata const werden 58 | if (ext2_inode_writedata(res->inode, start, size, (void*) data)) { 59 | ext2_inode_update(res->inode); 60 | return size; 61 | } 62 | 63 | //TODO: error in stream setzen 64 | return 0; 65 | } 66 | 67 | int ext2_fs_file_truncate(struct cdi_fs_stream* stream, uint64_t size) 68 | { 69 | struct ext2_fs_res* res = (struct ext2_fs_res*) stream->res; 70 | 71 | if (res->inode->raw->size == 0) { 72 | return 1; 73 | } 74 | 75 | // TODO: Vergroessern tut damit nicht 76 | return ext2_inode_truncate(res->inode, size); 77 | } 78 | 79 | -------------------------------------------------------------------------------- /driver/ext2/libext2/file.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008 The tyndur Project. All rights reserved. 3 | * 4 | * This code is derived from software contributed to the tyndur Project 5 | * by Antoine Kaufmann. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 3. All advertising materials mentioning features or use of this software 16 | * must display the following acknowledgement: 17 | * This product includes software developed by the tyndur Project 18 | * and its contributors. 19 | * 4. Neither the name of the tyndur Project nor the names of its 20 | * contributors may be used to endorse or promote products derived 21 | * from this software without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 25 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR 27 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 30 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 31 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 32 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 33 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | */ 35 | 36 | #include "ext2.h" 37 | 38 | int ext2_file_create(ext2_inode_t* parent, const char* name, 39 | ext2_inode_t* newi) 40 | { 41 | // Neuen Inode alloziern 42 | if (!ext2_inode_alloc(parent->fs, newi)) { 43 | return 0; 44 | } 45 | 46 | newi->raw->deletion_time = 0; 47 | newi->raw->mode = EXT2_INODE_MODE_FILE | 0777; 48 | 49 | // Verzeichniseintrag anlegen 50 | if (!ext2_dir_link(parent, newi, name)) { 51 | goto fail; 52 | } 53 | 54 | if (!ext2_inode_update(newi) || 55 | !ext2_inode_update(parent)) 56 | { 57 | return 0; 58 | } 59 | 60 | return 1; 61 | 62 | fail: 63 | ext2_inode_free(newi); 64 | return 0; 65 | } 66 | 67 | -------------------------------------------------------------------------------- /driver/ext2/libext2/include/file.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008 The tyndur Project. All rights reserved. 3 | * 4 | * This code is derived from software contributed to the tyndur Project 5 | * by Antoine Kaufmann. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 3. All advertising materials mentioning features or use of this software 16 | * must display the following acknowledgement: 17 | * This product includes software developed by the tyndur Project 18 | * and its contributors. 19 | * 4. Neither the name of the tyndur Project nor the names of its 20 | * contributors may be used to endorse or promote products derived 21 | * from this software without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 25 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR 27 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 30 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 31 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 32 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 33 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | */ 35 | 36 | #ifndef _FILE_H_ 37 | #define _FILE_H_ 38 | 39 | /** 40 | * Neues Datei anlegen 41 | * 42 | * @param parent Inode des Elternverzeichnisses 43 | * @param name Name der neuen Datei 44 | * @param newi Speicher fuer Inode der neuen Datei 45 | * 46 | * @return 1 bei Erfolg, 0 sonst 47 | */ 48 | int ext2_file_create(ext2_inode_t* parent, const char* name, 49 | ext2_inode_t* newi); 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /driver/ext2/libext2/include/symlink.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008 The tyndur Project. All rights reserved. 3 | * 4 | * This code is derived from software contributed to the tyndur Project 5 | * by Kevin Wolf. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 3. All advertising materials mentioning features or use of this software 16 | * must display the following acknowledgement: 17 | * This product includes software developed by the tyndur Project 18 | * and its contributors. 19 | * 4. Neither the name of the tyndur Project nor the names of its 20 | * contributors may be used to endorse or promote products derived 21 | * from this software without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 25 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR 27 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 30 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 31 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 32 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 33 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | */ 35 | 36 | #ifndef _SYMLINK_H_ 37 | #define _SYMLINK_H_ 38 | 39 | /** 40 | * Pfad aus einem Symlink in einen frisch allozierten Buffer auslesen. 41 | * Der Aufrufer ist dafuer zustaendig, den Buffer wieder freizugeben. 42 | * 43 | * @param inode Inode des auszulesenden Symlinks 44 | */ 45 | char* ext2_symlink_read(ext2_inode_t* inode); 46 | 47 | /** 48 | * Neuen Symlink erstellen 49 | * 50 | * @param parent Inode des Elternverzeichnisses 51 | * @param name Name des neuen Symlinks 52 | * @param target Ziel des neuen Symlinks 53 | * @param newi Neu anzulegender Inode 54 | * 55 | * @return 1 bei Erfolg, 0 im Fehlerfall 56 | */ 57 | int ext2_symlink_create(ext2_inode_t* parent, 58 | const char* name, const char* target, ext2_inode_t* newi); 59 | 60 | /** 61 | * Pfad in einem Symlink aendern 62 | * 63 | * @param inode Inode des zu schreibenden Symlinks 64 | * @param path Neuer Pfad 65 | * 66 | * @return 1 bei Erfolg 0 sonst 67 | */ 68 | int ext2_symlink_write(ext2_inode_t* inode, const char* path); 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /driver/ext2/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008 The tyndur Project. All rights reserved. 3 | * 4 | * This code is derived from software contributed to the tyndur Project 5 | * by Antoine Kaufmann. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 3. All advertising materials mentioning features or use of this software 16 | * must display the following acknowledgement: 17 | * This product includes software developed by the tyndur Project 18 | * and its contributors. 19 | * 4. Neither the name of the tyndur Project nor the names of its 20 | * contributors may be used to endorse or promote products derived 21 | * from this software without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 25 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR 27 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 30 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 31 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 32 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 33 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | */ 35 | 36 | #include 37 | #include 38 | #include 39 | 40 | #include "cdi/fs.h" 41 | 42 | #include "ext2_cdi.h" 43 | 44 | #define DRIVER_NAME "ext2" 45 | 46 | static struct cdi_fs_driver ext2_driver; 47 | 48 | /** 49 | * Initialisiert die Datenstrukturen fuer den ext2-Treiber 50 | */ 51 | static int ext2_driver_init(void) 52 | { 53 | // Konstruktor der Vaterklasse 54 | cdi_fs_driver_init((struct cdi_fs_driver*) &ext2_driver); 55 | return 0; 56 | } 57 | 58 | /** 59 | * Deinitialisiert die Datenstrukturen fuer den sis900-Treiber 60 | */ 61 | static int ext2_driver_destroy(void) 62 | { 63 | cdi_fs_driver_destroy(&ext2_driver); 64 | return 0; 65 | } 66 | 67 | 68 | static struct cdi_fs_driver ext2_driver = { 69 | .drv = { 70 | .type = CDI_FILESYSTEM, 71 | .name = DRIVER_NAME, 72 | .init = ext2_driver_init, 73 | .destroy = ext2_driver_destroy, 74 | }, 75 | .fs_probe = ext2_fs_probe, 76 | .fs_init = ext2_fs_init, 77 | .fs_destroy = ext2_fs_destroy, 78 | }; 79 | 80 | CDI_DRIVER(DRIVER_NAME, ext2_driver) 81 | -------------------------------------------------------------------------------- /driver/ext2/resources.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008 The tyndur Project. All rights reserved. 3 | * 4 | * This code is derived from software contributed to the tyndur Project 5 | * by Antoine Kaufmann. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 3. All advertising materials mentioning features or use of this software 16 | * must display the following acknowledgement: 17 | * This product includes software developed by the tyndur Project 18 | * and its contributors. 19 | * 4. Neither the name of the tyndur Project nor the names of its 20 | * contributors may be used to endorse or promote products derived 21 | * from this software without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 25 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR 27 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 30 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 31 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 32 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 33 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | */ 35 | 36 | #include "ext2_cdi.h" 37 | 38 | struct cdi_fs_res_res ext2_fs_res = { 39 | .load = ext2_fs_res_load, 40 | .unload = ext2_fs_res_unload, 41 | .remove = ext2_fs_res_remove, 42 | 43 | .meta_read = ext2_fs_res_meta_read, 44 | .meta_write = ext2_fs_res_meta_write, 45 | 46 | .assign_class = ext2_fs_res_assign_class, 47 | .remove_class = ext2_fs_res_remove_class, 48 | }; 49 | 50 | struct cdi_fs_res_file ext2_fs_file = { 51 | // Prinzipiell haben wir nur ausfuehrbare Dateien, der Rest wird mit den 52 | // Berechtigungen geregelt 53 | .executable = 1, 54 | 55 | .read = ext2_fs_file_read, 56 | .write = ext2_fs_file_write, 57 | .truncate = ext2_fs_file_truncate 58 | }; 59 | 60 | struct cdi_fs_res_dir ext2_fs_dir = { 61 | .list = ext2_fs_dir_list, 62 | .create_child = ext2_fs_dir_create_child 63 | }; 64 | 65 | struct cdi_fs_res_link ext2_fs_link = { 66 | .read_link = ext2_fs_link_read, 67 | .write_link = ext2_fs_link_write 68 | }; 69 | 70 | -------------------------------------------------------------------------------- /driver/ext2/symlinks.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008 The tyndur Project. All rights reserved. 3 | * 4 | * This code is derived from software contributed to the tyndur Project 5 | * by Antoine Kaufmann. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 3. All advertising materials mentioning features or use of this software 16 | * must display the following acknowledgement: 17 | * This product includes software developed by the tyndur Project 18 | * and its contributors. 19 | * 4. Neither the name of the tyndur Project nor the names of its 20 | * contributors may be used to endorse or promote products derived 21 | * from this software without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 25 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR 27 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 30 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 31 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 32 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 33 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | */ 35 | 36 | #include 37 | 38 | #include "ext2_cdi.h" 39 | 40 | const char* ext2_fs_link_read(struct cdi_fs_stream* stream) 41 | { 42 | return stream->res->link_path; 43 | } 44 | 45 | 46 | int ext2_fs_link_write(struct cdi_fs_stream* stream, const char* path) 47 | { 48 | struct ext2_fs_res* res = (struct ext2_fs_res*) stream->res; 49 | int result; 50 | 51 | result = ext2_symlink_write(res->inode, path); 52 | 53 | if (result) { 54 | if (res->res.link_path) { 55 | free(res->res.link_path); 56 | } 57 | res->res.link_path = strdup(path); 58 | 59 | ext2_inode_update(res->inode); 60 | } 61 | 62 | return result; 63 | } 64 | 65 | 66 | -------------------------------------------------------------------------------- /driver/iso9660/directory_record.h: -------------------------------------------------------------------------------- 1 | /* 2 | iso9660 - An iso9660 CDI driver with Rockridge support 3 | Copyright (C) 2008 Janosch Gräf 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #ifndef _DIRECTORY_RECORD_H_ 20 | #define _DIRECTORY_RECORD_H_ 21 | 22 | #include 23 | 24 | // Date from ISO9660 directory entry 25 | struct iso9660_dirrec_date { 26 | // Number of years since 1900 27 | uint8_t year; 28 | 29 | // Month (1=January, 2=February) 30 | uint8_t month; 31 | 32 | // Day of month 33 | uint8_t day; 34 | 35 | // Hour 36 | uint8_t hour; 37 | 38 | // Minute 39 | uint8_t minute; 40 | 41 | // Second 42 | uint8_t second; 43 | 44 | // GMT offset (in 15min intervals) 45 | int8_t gmtoff; 46 | } __attribute__ ((packed)); 47 | 48 | #define ISO9660_DIRREC_HIDDEN 1 49 | #define ISO9660_DIRREC_DIR 2 50 | #define ISO9660_DIRREC_ASSOC 4 51 | #define ISO9660_DIRREC_RECFMT 8 52 | #define ISO9660_DIRREC_PERM 16 53 | #define ISO9660_DIRREC_NOTFINAL 128 54 | 55 | // ISO9660 directory entry 56 | struct iso9660_dirrec { 57 | // Size of this record (must be even) 58 | uint8_t record_size; 59 | 60 | // Number of sectors in extended attribute record 61 | uint8_t num_sectors_extattrrec; 62 | 63 | // First sector for file/directory data (0 if empty) 64 | uint32_t data_sector; 65 | uint32_t data_sector_be; 66 | 67 | // File/directory data size 68 | uint32_t data_size; 69 | uint32_t data_size_be; 70 | 71 | // Date of creation 72 | struct iso9660_dirrec_date date_creation; 73 | 74 | // File flags 75 | uint8_t flags; 76 | 77 | // Unit size for interleaved files (should be 0) 78 | uint8_t interleaved_unit_size; 79 | 80 | // Gap size for interleaved files (should be 0) 81 | uint8_t interleaved_gap_size; 82 | 83 | // Volume sequence number 84 | uint16_t volume_seq; 85 | uint16_t volume_seq_be; 86 | 87 | // Identifier length 88 | uint8_t identifier_length; 89 | 90 | // Identifier 91 | uint8_t identifier[1]; 92 | } __attribute__ ((packed)); 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /driver/iso9660/file.c: -------------------------------------------------------------------------------- 1 | /* 2 | iso9660 - An iso9660 CDI driver with Rockridge support 3 | Copyright (C) 2008 Janosch Gräf 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include "cdi/fs.h" 20 | #include "cdi/cache.h" 21 | 22 | #include "iso9660_cdi.h" 23 | 24 | /** 25 | * Reads from file 26 | * @param stream CDI FS stream 27 | * @param start Offset in flie 28 | * @param size How many bytes to read 29 | * @param buffer Buffer to store data in 30 | * @return How many bytes read 31 | */ 32 | size_t iso9660_fs_file_read(struct cdi_fs_stream *stream,uint64_t start,size_t size,void *buffer) { 33 | debug("iso9660_fs_file_read(0x%x,0x%x,0x%x,0x%x,0x%x)\n",stream,start,size,buffer); 34 | struct iso9660_fs_res *res = (struct iso9660_fs_res*)stream->res; 35 | 36 | if (start>res->data_size) return 0; 37 | if (start+size>res->data_size) size = res->data_size-start; 38 | 39 | iso9660_read(res,start,size,buffer); 40 | //cdi_cache_entry_read(res->cache_entry,start,size,buffer); 41 | return size; 42 | } 43 | -------------------------------------------------------------------------------- /driver/iso9660/init.c: -------------------------------------------------------------------------------- 1 | /* 2 | iso9660 - An iso9660 CDI driver with Rockridge support 3 | Copyright (C) 2008 Janosch Gräf 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include "cdi/fs.h" 24 | #include "cdi/cache.h" 25 | 26 | #include "iso9660_cdi.h" 27 | 28 | #include "volume_descriptor.h" 29 | 30 | int iso9660_fs_probe(struct cdi_fs_filesystem* cdi_fs, char** volname) 31 | { 32 | struct iso9660_voldesc_prim voldesc; 33 | size_t len; 34 | int ret; 35 | 36 | ret = iso9660_voldesc_load(cdi_fs, ISO9660_VOLDESC_PRIM, &voldesc); 37 | if (ret != 0) { 38 | return 0; 39 | } 40 | 41 | len = sizeof(voldesc.volume_identifier); 42 | *volname = malloc(len + 1); 43 | memcpy(*volname, voldesc.volume_identifier, len); 44 | (*volname)[len] = '\0'; 45 | 46 | /* Remove padding */ 47 | while (--len && (*volname)[len] == ' ') { 48 | (*volname)[len] = '\0'; 49 | } 50 | 51 | return 1; 52 | } 53 | 54 | /** 55 | * Initializes a ISO9660 filesystem 56 | * @param fs Filesystem to initialize 57 | * @return If initialization was successful 58 | */ 59 | int iso9660_fs_init(struct cdi_fs_filesystem *fs) { 60 | debug("iso9660_fs_init(0x%p)\n",fs); 61 | struct iso9660_voldesc_prim *voldesc = malloc(sizeof(struct iso9660_voldesc_prim)); 62 | if (iso9660_voldesc_load(fs,ISO9660_VOLDESC_PRIM,voldesc)!=-1) { 63 | struct iso9660_fs_res *root_res = iso9660_dirrec_load(&voldesc->root_dir,NULL,voldesc); 64 | root_res->cache = cdi_cache_create(voldesc->sector_size,0,iso9660_sector_read_cache,NULL,fs); 65 | fs->root_res = (struct cdi_fs_res*)root_res; 66 | return 1; 67 | } 68 | else return 0; 69 | } 70 | 71 | /** 72 | * Destroys a FS 73 | * @param fs Filesystem to destroy 74 | * @return If destroy was successful 75 | */ 76 | int iso9660_fs_destroy(struct cdi_fs_filesystem *fs) { 77 | fprintf(stderr,"iso9660_fs_destroy(0x%p)\n",fs); 78 | struct iso9660_fs_res *root_res = (struct iso9660_fs_res*)(fs->root_res); 79 | free(root_res->voldesc); 80 | cdi_cache_destroy(root_res->cache); 81 | return iso9660_fs_res_destroy(root_res); 82 | } 83 | -------------------------------------------------------------------------------- /driver/iso9660/iso9660_cdi.h: -------------------------------------------------------------------------------- 1 | /* 2 | iso9660 - An iso9660 CDI driver with Rockridge support 3 | Copyright (C) 2008 Janosch Gräf 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #ifndef _ISO9660_CDI_H_ 20 | #define _ISO9660_CDI_H_ 21 | 22 | #include 23 | #include 24 | 25 | #include "cdi/fs.h" 26 | #include "cdi/cache.h" 27 | #include "cdi/lists.h" 28 | 29 | #include "iso9660def.h" 30 | #include "volume_descriptor.h" 31 | 32 | // ISO9660 Resource 33 | struct iso9660_fs_res { 34 | struct cdi_fs_res res; 35 | 36 | // Creation time 37 | uint64_t ctime; 38 | 39 | // Access time 40 | uint64_t atime; 41 | 42 | // Modification time 43 | uint64_t mtime; 44 | 45 | // First sector with resource data 46 | uint64_t data_sector; 47 | 48 | // Size of resource data 49 | uint32_t data_size; 50 | 51 | // File class 52 | cdi_fs_res_class_t class; 53 | 54 | // Primary volume descriptor 55 | struct iso9660_voldesc_prim *voldesc; 56 | 57 | // Cache 58 | struct cdi_cache *cache; 59 | }; 60 | 61 | // init.c 62 | int iso9660_fs_probe(struct cdi_fs_filesystem* cdi_fs, char** volname); 63 | int iso9660_fs_init(struct cdi_fs_filesystem *fs); 64 | int iso9660_fs_destroy(struct cdi_fs_filesystem *fs); 65 | 66 | // res.c 67 | struct iso9660_fs_res *iso9660_fs_res_create(const char *name,struct iso9660_fs_res *parent,cdi_fs_res_class_t class,cdi_fs_res_type_t type); 68 | int iso9660_fs_res_destroy(struct iso9660_fs_res *res); 69 | int iso9660_fs_res_load(struct cdi_fs_stream *stream); 70 | int iso9660_fs_res_unload(struct cdi_fs_stream *stream); 71 | int64_t iso9660_fs_res_meta_read(struct cdi_fs_stream *stream,cdi_fs_meta_t meta); 72 | 73 | // file.c 74 | size_t iso9660_fs_file_read(struct cdi_fs_stream *stream,uint64_t start,size_t size,void *buffer); 75 | 76 | // dir.c 77 | cdi_list_t iso9660_dir_load(struct iso9660_fs_res *res); 78 | struct iso9660_fs_res *iso9660_dirrec_load(struct iso9660_dirrec *dirrec,struct iso9660_fs_res *parent,struct iso9660_voldesc_prim *voldesc); 79 | cdi_list_t iso9660_fs_dir_list(struct cdi_fs_stream *stream); 80 | 81 | // sector.c 82 | #define iso9660_sector_read(fs,start,size,buffer) cdi_fs_data_read(fs,start,size,buffer) 83 | size_t iso9660_read(struct iso9660_fs_res *res,size_t pos,size_t size,void *buffer); 84 | int iso9660_sector_read_cache(struct cdi_cache *cache,uint64_t block,size_t count,void *dest,void *prv); 85 | 86 | // resources.c 87 | extern struct cdi_fs_res_res iso9660_fs_res_res; 88 | extern struct cdi_fs_res_file iso9660_fs_res_file; 89 | extern struct cdi_fs_res_dir iso9660_fs_res_dir; 90 | 91 | // Debug 92 | int debug(const char *fmt,...); 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /driver/iso9660/iso9660def.h: -------------------------------------------------------------------------------- 1 | /* 2 | iso9660 - An iso9660 CDI driver with Rockridge support 3 | Copyright (C) 2008 Janosch Gräf 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #ifndef _ISO9660DEF_H_ 20 | #define _ISO9660DEF_H_ 21 | 22 | // Default sector size. Used to load volume descriptors 23 | #define ISO9660_DEFAULT_SECTOR_SIZE 2048 24 | 25 | // Number of first used sector (first volume descriptor) 26 | #define ISO9660_FIRST_SECTOR 16 27 | 28 | // Define if you want to use lower filenames 29 | // (if you don't use an extension that supports lower filenames) 30 | #define ISO9660_LOWER_FILENAMES 31 | 32 | #ifndef ISO9660_USE_ROCKRIDGE 33 | // Define if you want to use Rockridge extension 34 | #define ISO9660_USE_ROCKRIDGE 35 | #endif 36 | 37 | #ifndef DEBUG 38 | //#define DEBUG stderr 39 | #endif 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /driver/iso9660/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | iso9660 - An iso9660 CDI driver with Rockridge support 3 | Copyright (C) 2008 Janosch Gräf 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include "cdi/fs.h" 23 | 24 | #include "iso9660_cdi.h" 25 | #include "iso9660def.h" 26 | 27 | #define DRIVER_NAME "iso9660" 28 | 29 | static struct cdi_fs_driver iso9660_driver; 30 | 31 | /** 32 | * Initializes the data structures for the iso9660 driver 33 | */ 34 | static int iso9660_driver_init(void) { 35 | // Konstruktor der Vaterklasse 36 | cdi_fs_driver_init(&iso9660_driver); 37 | 38 | return 0; 39 | } 40 | 41 | /** 42 | * Deinitialize the data structures for the iso9660 driver 43 | */ 44 | static int iso9660_driver_destroy(void) 45 | { 46 | cdi_fs_driver_destroy(&iso9660_driver); 47 | return 0; 48 | } 49 | 50 | /** 51 | * If DEBUG is definded, it outputs the debug message onto the stream 52 | * defined with DEBUG 53 | * @param fmt Format (see printf) 54 | * @param ... Parameters 55 | * @return Amount of output characters 56 | */ 57 | int debug(const char *fmt,...) { 58 | #ifdef DEBUG 59 | va_list args; 60 | va_start(args,fmt); 61 | int ret = vfprintf(DEBUG,fmt,args); 62 | va_end(args); 63 | return ret; 64 | #else 65 | return 0; 66 | #endif 67 | } 68 | 69 | 70 | static struct cdi_fs_driver iso9660_driver = { 71 | .drv = { 72 | .type = CDI_FILESYSTEM, 73 | .name = DRIVER_NAME, 74 | .init = iso9660_driver_init, 75 | .destroy = iso9660_driver_destroy, 76 | }, 77 | .fs_init = iso9660_fs_init, 78 | .fs_destroy = iso9660_fs_destroy, 79 | .fs_probe = iso9660_fs_probe, 80 | }; 81 | 82 | CDI_DRIVER(DRIVER_NAME, iso9660_driver) 83 | -------------------------------------------------------------------------------- /driver/iso9660/resources.c: -------------------------------------------------------------------------------- 1 | /* 2 | iso9660 - An iso9660 CDI driver with Rockridge support 3 | Copyright (C) 2008 Janosch Gräf 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include "iso9660_cdi.h" 20 | 21 | struct cdi_fs_res_res iso9660_fs_res_res = { 22 | .load = iso9660_fs_res_load, 23 | .unload = iso9660_fs_res_unload, 24 | .meta_read = iso9660_fs_res_meta_read, 25 | }; 26 | 27 | struct cdi_fs_res_file iso9660_fs_res_file = { 28 | // Prinzipiell haben wir nur ausfuehrbare Dateien, der Rest wird mit den 29 | // Berechtigungen geregelt 30 | .executable = 1, 31 | 32 | .read = iso9660_fs_file_read, 33 | }; 34 | 35 | struct cdi_fs_res_dir iso9660_fs_res_dir = { 36 | .list = iso9660_fs_dir_list, 37 | }; 38 | -------------------------------------------------------------------------------- /driver/iso9660/rockridge.c: -------------------------------------------------------------------------------- 1 | /* 2 | iso9660 - An iso9660 CDI driver with Rockridge support 3 | Copyright (C) 2008 Janosch Gräf 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include "iso9660def.h" 20 | #ifdef ISO9660_USE_ROCKRIDGE 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "cdi/lists.h" 29 | 30 | #include "rockridge.h" 31 | #include "directory_record.h" 32 | 33 | /** 34 | * Scans system use area in directory record for rockridge entries 35 | * @param dirrec Directory record 36 | * @param _name Reference for POSIX name 37 | * @param mode Reference for file mode 38 | * @param uid Reference for UID 39 | * @param gid Reference for GID 40 | * @param nlink Reference for number of hardlinks 41 | * @param atime Reference for access time 42 | * @param ctime Reference for createtion time 43 | * @param mtime Reference for modification time 44 | * @return 0=success; -1=failure 45 | */ 46 | int iso9660_rockridge_scan(struct iso9660_dirrec *dirrec,char **_name,mode_t *mode,uid_t *uid,gid_t *gid,nlink_t *nlink,uint64_t *atime,uint64_t *ctime,uint64_t *mtime) { 47 | struct iso9660_rockridge *sue = ((void*)(dirrec->identifier))+dirrec->identifier_length; 48 | if ((((uintptr_t)sue)&1)==1) sue = ((void*)sue)+1; 49 | 50 | if (sue->sig!=ISO9660_ROCKRIDGE_SIG_RR) return -1; 51 | 52 | char *name = NULL; 53 | size_t name_size = 0; 54 | 55 | while (sue->sig!=ISO9660_ROCKRIDGE_SIG_ST && sue->sig!=0 && ((uintptr_t)sue-(uintptr_t)dirrec)+4record_size) { 56 | if (sue->sig==ISO9660_ROCKRIDGE_SIG_PX) { 57 | struct iso9660_rockridge_px *sue_px = (struct iso9660_rockridge_px*)sue; 58 | if (mode!=NULL) *mode = sue_px->mode; 59 | if (nlink!=NULL) *nlink = sue_px->nlink; 60 | if (uid!=NULL) *uid = sue_px->uid; 61 | if (gid!=NULL) *gid = sue_px->gid; 62 | } 63 | else if (sue->sig==ISO9660_ROCKRIDGE_SIG_NM) { 64 | struct iso9660_rockridge_nm *sue_nm = (struct iso9660_rockridge_nm*)sue; 65 | if (sue_nm->flags&ISO9660_ROCKRIDGE_NAMEFLAG_CURRENT) *_name = strdup("."); 66 | else if (sue_nm->flags&ISO9660_ROCKRIDGE_NAMEFLAG_PARENT) *_name = strdup(".."); 67 | else { 68 | size_t part_size = sue->size-offsetof(struct iso9660_rockridge_nm,name); 69 | name = realloc(name,name_size+part_size+1); 70 | memcpy(name+name_size,sue_nm->name,part_size); 71 | name_size += part_size; 72 | } 73 | } 74 | sue = ((void*)sue)+sue->size; 75 | } 76 | 77 | if (name!=NULL) { 78 | if (_name!=NULL) { 79 | name[name_size] = 0; 80 | *_name = name; 81 | } 82 | else free(name); 83 | } 84 | 85 | return 0; 86 | } 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /driver/iso9660/sector.c: -------------------------------------------------------------------------------- 1 | /* 2 | iso9660 - An iso9660 CDI driver with Rockridge support 3 | Copyright (C) 2008 Janosch Gräf 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include "cdi/fs.h" 23 | #include "cdi/cache.h" 24 | 25 | #include "iso9660def.h" 26 | 27 | #include "iso9660_cdi.h" 28 | 29 | #define MIN(a,b) ((a) > (b) ? (b) : (a)) 30 | 31 | /** 32 | * Reads data from device for cache 33 | * @param cache CDI cache 34 | * @param block Block to read 35 | * @param count How many blocks to read 36 | * @param dest Buffer to store data in 37 | * @param prv Private data (CDI filesystem) 38 | */ 39 | int iso9660_sector_read_cache(struct cdi_cache *cache,uint64_t block,size_t count,void *dest,void *prv) { 40 | debug("iso9660_sector_read_cache(0x%x,0x%x,0x%x,0x%x,0x%x,0x%x)\n",cache,block,count,dest,prv); 41 | uint64_t start = ((uint64_t)block)*ISO9660_DEFAULT_SECTOR_SIZE; 42 | size_t size = count*ISO9660_DEFAULT_SECTOR_SIZE; 43 | return iso9660_sector_read(prv,start,size,dest)/ISO9660_DEFAULT_SECTOR_SIZE; 44 | } 45 | 46 | /** 47 | * Read data from resource 48 | * @param res Resource to read data from 49 | * @param pos Position in resource 50 | * @param size How many bytes to read 51 | * @param Buffer Buffer to store data in 52 | * @return How many bytes read 53 | */ 54 | size_t iso9660_read(struct iso9660_fs_res *res,size_t pos,size_t size,void *buffer) { 55 | size_t block = pos/res->voldesc->sector_size; 56 | size_t offset = pos%res->voldesc->sector_size; 57 | size_t rem_size = size; 58 | 59 | while (rem_size>0) { 60 | //debug("Block: 0x%x\n",res->data_sector+block++); 61 | struct cdi_cache_block* cache_block; 62 | size_t cur_size; 63 | 64 | cache_block = cdi_cache_block_get(res->cache, res->data_sector + block, 0); 65 | if (cache_block == NULL) { 66 | break; 67 | } 68 | 69 | cur_size = MIN(rem_size, res->voldesc->sector_size - offset); 70 | 71 | memcpy(buffer,cache_block->data+offset,cur_size); 72 | cdi_cache_block_release(res->cache,cache_block); 73 | 74 | block++; 75 | buffer += cur_size; 76 | rem_size -= cur_size; 77 | offset = 0; 78 | } 79 | 80 | return size - rem_size; 81 | } 82 | 83 | -------------------------------------------------------------------------------- /driver/iso9660/volume_descriptor.c: -------------------------------------------------------------------------------- 1 | /* 2 | iso9660 - An iso9660 CDI driver with Rockridge support 3 | Copyright (C) 2008 Janosch Gräf 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include "cdi/fs.h" 23 | 24 | #include "iso9660_cdi.h" 25 | 26 | #include "iso9660def.h" 27 | #include "volume_descriptor.h" 28 | 29 | /** 30 | * Checks signature of volume descriptor 31 | * @param sig Signature 32 | * @return If signature is right 33 | */ 34 | static int iso9660_voldesc_checksig(uint8_t sig[6]) { 35 | return 1; 36 | //char right[6] = {'C','D','0','0','1',1}; 37 | //return memcmp(right,sig,6)==0; 38 | } 39 | 40 | /** 41 | * Loads a volume descriptor 42 | * @param fs Filesystem 43 | * @param type Type of volume descriptor 44 | * @param buf Buffer for volume descriptor 45 | * @return 0=success; -1=failure 46 | */ 47 | int iso9660_voldesc_load(struct cdi_fs_filesystem *fs,iso9660_voldesc_type_t type,void *buf) { 48 | debug("iso9660_voldesc_load(0x%x,%d,0x%x)\n",fs,type,buf); 49 | struct iso9660_voldesc header; 50 | size_t i; 51 | 52 | for (i=ISO9660_FIRST_SECTOR;header.type!=type && header.type!=ISO9660_VOLDESC_TERM;i++) { 53 | iso9660_sector_read(fs,i*ISO9660_DEFAULT_SECTOR_SIZE,sizeof(header),&header); 54 | if (!iso9660_voldesc_checksig(header.signature)) return -1; 55 | } 56 | i--; 57 | 58 | if (header.type==type) { 59 | iso9660_sector_read(fs,i*ISO9660_DEFAULT_SECTOR_SIZE,sizeof(struct iso9660_voldesc_prim),buf); 60 | return 0; 61 | } 62 | else { 63 | debug("Volume Descriptor: Wrong type: %d\n",header.type); 64 | return -1; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /driver/random/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * main.c 3 | * 4 | * Created on: 16.12.2015 5 | * Author: pascal 6 | */ 7 | 8 | #include "cdi/storage.h" 9 | #include "random.h" 10 | #include "mt.h" 11 | #include 12 | #include "cpu.h" 13 | 14 | #define DRIVER_NAME "random" 15 | 16 | static struct cdi_storage_driver random_driver; 17 | 18 | /* 19 | * Prüft, ob die Funktion rdrand verfügbar ist 20 | * Rückgabe: 0, wenn die Funktion nicht unterstützt wird 21 | * !0, wenn die Funktion unterstützt wird 22 | */ 23 | static bool check_rdrand() 24 | { 25 | return cpuInfo.rdrand; 26 | } 27 | 28 | static int random_driver_init(void) 29 | { 30 | struct random_device *dev; 31 | //Konstruktor der Vaterklasse 32 | cdi_storage_driver_init(&random_driver); 33 | 34 | if(check_rdrand()) 35 | { 36 | dev = random_device_init((struct cdi_driver*)&random_driver, "rdrand", read_rdrand, NULL); 37 | cdi_list_push(random_driver.drv.devices, dev); 38 | } 39 | 40 | dev = random_device_init((struct cdi_driver*)&random_driver, "urandom", randomMT, (seed_func)seedMT); 41 | 42 | return 0; 43 | } 44 | 45 | static int random_driver_destroy(void) 46 | { 47 | //Destruktor der Vaterklasse 48 | cdi_storage_driver_destroy(&random_driver); 49 | return 0; 50 | } 51 | 52 | static struct cdi_storage_driver random_driver = { 53 | .drv = { 54 | .type = CDI_STORAGE, 55 | .name = DRIVER_NAME, 56 | .init = random_driver_init, 57 | .destroy = random_driver_destroy 58 | }, 59 | .read_blocks = random_read_blocks, 60 | .write_blocks = random_write_blocks 61 | }; 62 | 63 | CDI_DRIVER(DRIVER_NAME, random_driver); 64 | -------------------------------------------------------------------------------- /driver/random/mt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * mt.c 3 | * 4 | * Created on: 17.12.2015 5 | * Author: pascal 6 | */ 7 | 8 | #include "mt.h" 9 | 10 | #define NN 312 11 | #define MM 156 12 | #define MATRIX_A 0xB5026F5AA96619E9ULL 13 | #define UM 0xFFFFFFFF80000000ULL 14 | #define LM 0x7FFFFFFFULL 15 | 16 | static unsigned long long mt[NN]; 17 | static int mti=NN+1; 18 | 19 | void seedMT(unsigned long long seed) 20 | { 21 | mt[0] = seed; 22 | for (mti=1; mti> 62)) + mti); 24 | } 25 | 26 | uint64_t randomMT(void) 27 | { 28 | int i; 29 | unsigned long long x; 30 | static unsigned long long mag01[2]={0ULL, MATRIX_A}; 31 | 32 | if (mti >= NN) { /* generate NN words at one time */ 33 | 34 | /* if seedMT() has not been called, */ 35 | /* a default initial seed is used */ 36 | if (mti == NN+1) 37 | seedMT(5489ULL); 38 | 39 | for (i=0;i>1) ^ mag01[(int)(x&1ULL)]; 42 | } 43 | for (;i>1) ^ mag01[(int)(x&1ULL)]; 46 | } 47 | x = (mt[NN-1]&UM)|(mt[0]&LM); 48 | mt[NN-1] = mt[MM-1] ^ (x>>1) ^ mag01[(int)(x&1ULL)]; 49 | 50 | mti = 0; 51 | } 52 | 53 | x = mt[mti++]; 54 | 55 | x ^= (x >> 29) & 0x5555555555555555ULL; 56 | x ^= (x << 17) & 0x71D67FFFEDA60000ULL; 57 | x ^= (x << 37) & 0xFFF7EEE000000000ULL; 58 | x ^= (x >> 43); 59 | 60 | return (uint64_t)x; 61 | } 62 | -------------------------------------------------------------------------------- /driver/random/mt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * mt.h 3 | * 4 | * Created on: 17.12.2015 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef MT_H_ 9 | #define MT_H_ 10 | 11 | #include 12 | 13 | void seedMT(unsigned long long seed); 14 | uint64_t randomMT(void); 15 | 16 | #endif /* MT_H_ */ 17 | -------------------------------------------------------------------------------- /driver/random/random.c: -------------------------------------------------------------------------------- 1 | /* 2 | * random.c 3 | * 4 | * Created on: 16.12.2015 5 | * Author: pascal 6 | */ 7 | 8 | #include "random.h" 9 | #include 10 | #include 11 | #include 12 | #include "cpu.h" 13 | 14 | struct random_device *random_device_init(struct cdi_driver *driver, const char *name, rand_func rand, seed_func seed) 15 | { 16 | struct random_device *dev = calloc(1, sizeof(struct random_device)); 17 | if(dev != NULL) 18 | { 19 | dev->dev.dev.driver = driver; 20 | dev->dev.dev.name = strdup(name); 21 | dev->dev.block_size = sizeof(__typeof(rand_func)); 22 | dev->dev.block_count = -1ul; 23 | dev->rand = rand; 24 | dev->seed = seed; 25 | 26 | cdi_storage_device_init(&dev->dev); 27 | } 28 | return dev; 29 | } 30 | 31 | int random_read_blocks(struct cdi_storage_device *device, uint64_t block __attribute__((unused)), uint64_t count, void *buffer) 32 | { 33 | size_t i; 34 | struct random_device *dev = (struct random_device*)device; 35 | uint64_t *buf = (uint64_t*)buffer; 36 | 37 | for(i = 0; i < count; i++) 38 | { 39 | buf[i] = dev->rand(); 40 | } 41 | 42 | return 0; 43 | } 44 | 45 | int random_write_blocks(struct cdi_storage_device *device, uint64_t block __attribute__((unused)), uint64_t count, void *buffer) 46 | { 47 | struct random_device *dev = (struct random_device*)device; 48 | uint64_t *buf = (uint64_t*)buffer; 49 | 50 | if(dev->seed) 51 | { 52 | dev->seed(buf[count - 1]); 53 | } 54 | 55 | return 0; 56 | } 57 | 58 | __attribute__((target("rdrnd"))) 59 | uint64_t read_rdrand() { 60 | uint64_t res; 61 | while (!_rdrand64_step(&res)) CPU_PAUSE(); 62 | return res; 63 | } 64 | -------------------------------------------------------------------------------- /driver/random/random.h: -------------------------------------------------------------------------------- 1 | /* 2 | * random.h 3 | * 4 | * Created on: 16.12.2015 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef RANDOM_H_ 9 | #define RANDOM_H_ 10 | 11 | #include "stdint.h" 12 | #include "cdi/storage.h" 13 | 14 | typedef uint64_t(*rand_func)(); 15 | typedef void(*seed_func)(uint64_t); 16 | 17 | struct random_device { 18 | struct cdi_storage_device dev; 19 | rand_func rand; 20 | seed_func seed; 21 | }; 22 | 23 | struct random_device *random_device_init(struct cdi_driver *driver, const char *name, rand_func rand, seed_func seed); 24 | int random_read_blocks(struct cdi_storage_device *device, uint64_t block, uint64_t count, void *buffer); 25 | int random_write_blocks(struct cdi_storage_device *device, uint64_t block, uint64_t count, void *buffer); 26 | 27 | uint64_t read_rdrand(); 28 | 29 | #endif /* RANDOM_H_ */ 30 | -------------------------------------------------------------------------------- /drivermanager.c: -------------------------------------------------------------------------------- 1 | /* 2 | * drivermanager.c 3 | * 4 | * Created on: 05.04.2017 5 | * Author: pascal 6 | */ 7 | 8 | #include "drivermanager.h" 9 | #include "list.h" 10 | #include "assert.h" 11 | #include "stddef.h" 12 | #include "string.h" 13 | #include "stdbool.h" 14 | #include "cdifs.h" 15 | 16 | static list_t drivers; 17 | 18 | void drivermanager_init() 19 | { 20 | drivers = list_create(); 21 | assert(drivers != NULL); 22 | } 23 | 24 | void drivermanager_registerDriver(struct cdi_driver *drv) 25 | { 26 | assert(drv != NULL); 27 | list_push(drivers, drv); 28 | if(drv->type == CDI_FILESYSTEM) 29 | cdifs_registerFilesystemDriver((struct cdi_fs_driver*)drv); 30 | } 31 | 32 | struct cdi_driver *drivermanager_getDriver(const char *name) 33 | { 34 | struct cdi_driver *drv; 35 | size_t i = 0; 36 | 37 | assert(name != NULL); 38 | 39 | while((drv = list_get(drivers, i++)) != NULL) 40 | { 41 | if(strcmp(name, drv->name) == 0) 42 | return drv; 43 | } 44 | 45 | return drv; 46 | } 47 | 48 | struct cdi_driver *drivermanager_getNextDeviceDriver(cdi_device_type_t bus, struct cdi_driver *prev) 49 | { 50 | struct cdi_driver *drv; 51 | size_t i = 0; 52 | bool prev_found = prev == NULL; 53 | 54 | while((drv = list_get(drivers, i++)) != NULL) 55 | { 56 | if(prev_found && drv->bus == bus) 57 | return drv; 58 | if(drv == prev) 59 | prev_found = true; 60 | } 61 | 62 | return drv; 63 | } 64 | -------------------------------------------------------------------------------- /drivermanager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * drivermanager.h 3 | * 4 | * Created on: 05.04.2017 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef DRIVERMANAGER_H_ 9 | #define DRIVERMANAGER_H_ 10 | 11 | #include "cdi.h" 12 | 13 | /** 14 | * \brief Initializes the driver manager. 15 | */ 16 | void drivermanager_init(); 17 | 18 | /** 19 | * \brief Registers a driver in the driver manager. 20 | * 21 | * @param drv Driver to be registered 22 | */ 23 | void drivermanager_registerDriver(struct cdi_driver *drv); 24 | 25 | /** 26 | * \brief Gets the driver with the specified name. 27 | * 28 | * @param name Name of the driver 29 | * @return the driver with a matching name or NULL 30 | */ 31 | struct cdi_driver *drivermanager_getDriver(const char *name); 32 | 33 | /** 34 | * \brief Gets the next suitable driver. 35 | * 36 | * @param type Type of the driver searched 37 | * @param prev Previous returned driver 38 | * @return a suitable driver or NULL 39 | */ 40 | struct cdi_driver *drivermanager_getNextDeviceDriver(cdi_device_type_t bus, struct cdi_driver *prev); 41 | 42 | #endif /* DRIVERMANAGER_H_ */ 43 | -------------------------------------------------------------------------------- /gdt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * gdt.c 3 | * 4 | * Created on: 02.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #include "gdt.h" 9 | #include "display.h" 10 | 11 | static uint64_t gdt[GDT_ENTRIES]; 12 | 13 | void GDT_Init() 14 | { 15 | gdtr_t gdtr; 16 | GDT_SetEntry(0, 0, 0, 0, 0); //NULL-Deskriptor 17 | //Ring 0 18 | GDT_SetEntry(1, 0, 0xFFFFF, 0x9A, 0xA); //Codesegment, ausführ- und lesbar, 64-bit, Ring 0 19 | GDT_SetEntry(2, 0, 0xFFFFF, 0x92, 0xC); //Datensegment, les- und schreibbar 20 | //Ring 3 (muss so sein sonst funktioniert sysret nicht) 21 | GDT_SetEntry(3, 0, 0xFFFFF, 0xF2, 0xC); //Datensegment, les- und schreibbar, Ring 3 22 | GDT_SetEntry(4, 0, 0xFFFFF, 0xFA, 0xA); //Codesegment, ausführ- und lesbar, 64-bit, Ring 3 23 | 24 | gdtr.limit = GDT_ENTRIES *8 - 1; 25 | gdtr.pointer = gdt; 26 | asm volatile("lgdt %0": :"m"(gdtr)); 27 | asm volatile( 28 | "mov $0x10,%ax;"//Index für das Datensegment des Kernels 29 | "mov %ax,%ds;" 30 | "mov %ax,%es;" 31 | "mov %ax,%ss;" 32 | "mov %ax,%fs;" 33 | "mov %ax,%gs;" 34 | "push $0x8;" //Compiler akzeptiert keinen farjump also machen wir es auf diese 35 | "push $(.1);" //Art. So holt sich die CPU den Codesegmentindex vom Stack 36 | "lretq;" 37 | ".1:" 38 | ); 39 | SysLog("GDT", "Initialisierung abgeschlossen"); 40 | } 41 | 42 | void GDT_SetEntry(int i, uint32_t base, uint32_t limit, uint8_t access, uint8_t flags) 43 | { 44 | gdt[i] = limit & 0xFFFF; 45 | gdt[i] |= (base & 0xFFFFFFLL) << 16; 46 | gdt[i] |= (access & 0xFFLL) << 40; 47 | gdt[i] |= ((limit >> 16) & 0xFLL) << 48; 48 | gdt[i] |= (flags & 0xFLL) << 52; 49 | gdt[i] |= ((base >> 24) & 0xFFLL) << 56; 50 | } 51 | 52 | void GDT_SetSystemDescriptor(int i, uint64_t base, uint32_t limit, uint8_t access, uint8_t flags) 53 | { 54 | gdt[i] = limit & 0xFFFF; 55 | gdt[i] |= (base & 0xFFFFFFLL) << 16; 56 | gdt[i] |= (access & 0xFFLL) << 40; 57 | gdt[i] |= ((limit >> 16) & 0xFLL) << 48; 58 | gdt[i] |= (flags & 0xFLL) << 52; 59 | gdt[i + 1] = base >> 24; 60 | gdt[i + 1] |= 0ul << 32; 61 | } 62 | -------------------------------------------------------------------------------- /gdt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * gdt.h 3 | * 4 | * Created on: 02.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef GDT_H_ 9 | #define GDT_H_ 10 | 11 | #define GDT_ENTRIES 7 12 | 13 | #include "stdint.h" 14 | 15 | typedef struct{ 16 | uint16_t limit; 17 | void *pointer; 18 | }__attribute__((packed)) gdtr_t; 19 | 20 | typedef struct{ 21 | uint16_t Limit1; //Segment Limit 0-15 22 | uint32_t Base1 :24; //Base Address 0-23 23 | uint8_t A :1; //Zugriff-Bit (Wird von der CPU bei Zugriff gesetzt) 24 | uint8_t R :1; //Lesbar-Bit (Kann das Segment gelesen werden?) 25 | uint8_t C :1; // 26 | uint8_t MB1 :2; //Muss 0b11 sein 27 | uint8_t DPL :2; // 28 | uint8_t P :1; 29 | uint8_t Limit2 :4; //Segment Limit 16-19 30 | uint8_t AVL :1; //Frei verfügbar 31 | uint8_t L :1; //Long Attribute Bit (64-Bit Modus = 1 | Legacy Mode = 0) 32 | uint8_t D :1; 33 | uint8_t G :1; //Granularity-Bit 34 | uint8_t Base2; //Base Address 24-31 35 | }__attribute__((packed)) gdt_code_segment_t; 36 | 37 | 38 | //Funktionen 39 | void GDT_Init(void); 40 | void GDT_SetEntry(int i, uint32_t base, uint32_t limit, uint8_t access, uint8_t flags); 41 | void GDT_SetSystemDescriptor(int i, uint64_t base, uint32_t limit, uint8_t access, uint8_t flags); 42 | 43 | #endif /* GDT_H_ */ 44 | -------------------------------------------------------------------------------- /idt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * idt.h 3 | * 4 | * Created on: 02.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef IDT_H_ 9 | #define IDT_H_ 10 | 11 | #define IDT_ENTRIES 256 12 | 13 | #include "stdint.h" 14 | 15 | //Flags 16 | #define IDT_TYPE_INTERRUPT (0b1110 << 8) //Interrupts werden deaktiviert 17 | #define IDT_TYPE_TRAP_GATE (0b1111 << 8) //Interrupts bleiben aktiviert 18 | 19 | #define IDT_DPL_KERNEL 0 20 | #define IDT_DPL_USER 0x6000 21 | 22 | #define IDT_PRESENT 0x8000 23 | 24 | #define IDT_IST_1 1 25 | 26 | typedef struct{ 27 | uint16_t limit; 28 | void *pointer; 29 | }__attribute__((packed)) idtr_t; 30 | 31 | //Funktionen 32 | void IDT_Init(void); 33 | void IDT_SetEntry(uint8_t i, uint16_t Selector, uint16_t Flags, uintptr_t Offset); 34 | 35 | #endif /* IDT_H_ */ 36 | -------------------------------------------------------------------------------- /include/assert.h: -------------------------------------------------------------------------------- 1 | /* 2 | * assert.h 3 | * 4 | * Created on: 21.08.2015 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef ASSERT_H_ 9 | #define ASSERT_H_ 10 | 11 | #ifdef NDEBUG 12 | #define assert(condition) ((void)0) 13 | #else 14 | extern void _assert(const char *assertion, const char *file, unsigned int line, const char *function) __attribute__((noreturn)); 15 | 16 | #define assert(condition) ((condition) ? ((void)0) : _assert(#condition, __FILE__, __LINE__, "")) 17 | #endif 18 | 19 | #define static_assert _Static_assert 20 | 21 | #endif /* ASSERT_H_ */ 22 | -------------------------------------------------------------------------------- /include/bits/sys_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * syscall_types.h 3 | * 4 | * Created on: 17.06.2017 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef BITS_SYS_TYPES_H_ 9 | #define BITS_SYS_TYPES_H_ 10 | 11 | #include 12 | #include 13 | 14 | typedef _size_t size_t; 15 | 16 | typedef _pid_t pid_t; 17 | typedef _tid_t tid_t; 18 | 19 | typedef _time_t time_t; 20 | 21 | typedef enum{ 22 | VFS_MODE_READ = (1 << 0), 23 | VFS_MODE_WRITE = (1 << 1), 24 | VFS_MODE_EXEC = (1 << 2), 25 | VFS_MODE_CREATE = (1 << 3), 26 | VFS_MODE_TRUNCATE = (1 << 4), 27 | VFS_MODE_DIR = (1 << 5) 28 | }vfs_mode_t; 29 | 30 | typedef enum{ 31 | VFS_INFO_FILESIZE, VFS_INFO_BLOCKSIZE, VFS_INFO_USEDBLOCKS, VFS_INFO_CREATETIME, VFS_INFO_ACCESSTIME, VFS_INFO_CHANGETIME, VFS_INFO_ATTRIBUTES 32 | }vfs_fileinfo_t; 33 | 34 | typedef enum{ 35 | UDT_UNKNOWN, UDT_DIR, UDT_FILE, UDT_LINK, UDT_DEV 36 | }vfs_userspace_direntry_type_t; 37 | 38 | typedef struct{ 39 | size_t size; 40 | vfs_userspace_direntry_type_t type; 41 | char name[]; 42 | }vfs_userspace_direntry_t; 43 | 44 | typedef struct{ 45 | uint64_t physSpeicher; 46 | uint64_t physFree; 47 | uint64_t Uptime; 48 | }SIS; 49 | 50 | #endif /* BITS_SYS_TYPES_H_ */ 51 | -------------------------------------------------------------------------------- /include/bits/syscall_numbers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * syscall_numbers.h 3 | * 4 | * Created on: 17.06.2017 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef BITS_SYSCALL_NUMBERS_H_ 9 | #define BITS_SYSCALL_NUMBERS_H_ 10 | 11 | enum{ 12 | SYSCALL_ALLOC_PAGES = 0, 13 | SYSCALL_FREE_PAGES = 1, 14 | SYSCALL_UNUSE_PAGES = 2, 15 | 16 | SYSCALL_EXEC = 10, 17 | SYSCALL_EXIT = 11, 18 | SYSCALL_WAIT = 12, 19 | SYSCALL_THREAD_CREATE = 13, 20 | SYSCALL_THREAD_EXIT = 14, 21 | 22 | SYSCALL_GET_TIMESTAMP = 30, 23 | SYSCALL_SLEEP = 31, 24 | 25 | SYSCALL_OPEN = 40, 26 | SYSCALL_CLOSE = 41, 27 | SYSCALL_READ = 42, 28 | SYSCALL_WRITE = 43, 29 | SYSCALL_INFO_GET = 44, 30 | SYSCALL_INFO_SET = 45, 31 | SYSCALL_TRUNCATE = 46, 32 | SYSCALL_MKDIR = 47, 33 | 34 | SYSCALL_MOUNT = 50, 35 | SYSCALL_UNMOUNT = 51, 36 | 37 | SYSCALL_SYSINF_GET = 60, 38 | 39 | _SYSCALL_NUM 40 | }; 41 | 42 | #endif /* BITS_SYSCALL_NUMBERS_H_ */ 43 | -------------------------------------------------------------------------------- /include/bits/types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * types.h 3 | * 4 | * Created on: 06.06.2017 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef BITS_TYPES_H_ 9 | #define BITS_TYPES_H_ 10 | 11 | typedef unsigned int __attribute__((__mode__(__TI__))) _uint128_t; 12 | typedef unsigned long _uint64_t; 13 | typedef unsigned int _uint32_t; 14 | typedef unsigned short _uint16_t; 15 | typedef unsigned char _uint8_t; 16 | 17 | typedef signed int __attribute__((__mode__(__TI__))) _int128_t; 18 | typedef signed long _int64_t; 19 | typedef signed int _int32_t; 20 | typedef signed short _int16_t; 21 | typedef signed char _int8_t; 22 | 23 | typedef _uint64_t _uintptr_t; 24 | typedef _int64_t _intptr_t; 25 | typedef _intptr_t _ptrdiff_t; 26 | 27 | typedef _uint128_t _uintmax_t; 28 | typedef _int128_t _intmax_t; 29 | 30 | typedef unsigned long _size_t; 31 | 32 | typedef _uint64_t _pid_t; 33 | typedef _uint64_t _tid_t; 34 | 35 | typedef _uint64_t _clock_t; 36 | typedef _int64_t _time_t; 37 | 38 | #endif /* BITS_TYPES_H_ */ 39 | -------------------------------------------------------------------------------- /include/complex.h: -------------------------------------------------------------------------------- 1 | #ifndef COMPLEX_H_ 2 | #define COMPLEX_H_ 3 | 4 | #define complex _Complex 5 | 6 | // TODO: implement 7 | 8 | #endif /* COMPLEX_H_ */ -------------------------------------------------------------------------------- /include/ctype.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ctype.h 3 | * 4 | * Created on: 28.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef CTYPE_H_ 9 | #define CTYPE_H_ 10 | 11 | extern int isalnum(int c); 12 | extern int isalpha(int c); 13 | extern int isdigit(int c); 14 | extern int isspace(int c); 15 | extern int isxdigit(int c); 16 | 17 | extern int iscntrl(int c); 18 | extern int isgraph(int c); 19 | extern int isprint(int c); 20 | extern int ispunct(int c); 21 | 22 | extern int islower(int c); 23 | extern int isupper(int c); 24 | 25 | extern int tolower(int c); 26 | extern int toupper(int c); 27 | 28 | #endif /* CTYPE_H_ */ 29 | -------------------------------------------------------------------------------- /include/dirent.h: -------------------------------------------------------------------------------- 1 | /* 2 | * dirent.h 3 | * 4 | * Created on: 21.03.2017 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef DIRENT_H_ 9 | #define DIRENT_H_ 10 | 11 | #include 12 | 13 | //Typen für d_type 14 | typedef enum{ 15 | DT_UNKNOWN, DT_DIR, DT_FILE, DT_LINK, DT_DEV 16 | }d_type_t; 17 | 18 | struct dirent{ 19 | ino_t d_ino; 20 | off_t d_off; 21 | unsigned short d_reclen; 22 | d_type_t d_type; 23 | char d_name[]; 24 | }; 25 | 26 | typedef struct dirstream DIR; 27 | 28 | int alphasort(const struct dirent **d1, const struct dirent **d2); 29 | int closedir(DIR* dirp); 30 | DIR* opendir(const char* dirname); 31 | struct dirent* readdir(DIR* dirp); 32 | int readdir_r(DIR* dirp, struct dirent* entry, struct dirent** result); 33 | void rewinddir(DIR* dirp); 34 | int scandir(const char *dir, struct dirent ***namelist, 35 | int (*sel)(const struct dirent*), 36 | int (*compar)(const struct dirent**, const struct dirent**)); 37 | void seekdir(DIR* dirp, long loc); 38 | long telldir(DIR* dirp); 39 | 40 | #endif /* DIRENT_H_ */ 41 | -------------------------------------------------------------------------------- /include/fenv.h: -------------------------------------------------------------------------------- 1 | #ifndef FENV_H_ 2 | #define FENV_H_ 3 | 4 | #define FE_INVALID (1 << 0) 5 | #define FE_DIVBYZERO (1 << 2) 6 | #define FE_OVERFLOW (1 << 3) 7 | #define FE_UNDERFLOW (1 << 4) 8 | #define FE_INEXACT (1 << 5) 9 | #define FE_ALL_EXCEPT FE_DIVBYZERO | FE_INEXACT | \ 10 | FE_INVALID | FE_OVERFLOW | \ 11 | FE_UNDERFLOW 12 | 13 | #define FE_DOWNWARD 0b01 14 | #define FE_TONEAREST 0b00 15 | #define FE_TOWARDZERO 0b11 16 | #define FE_UPWARD 0b10 17 | 18 | typedef struct { 19 | struct { 20 | unsigned short control_word; 21 | unsigned short __res1; 22 | unsigned short status_word; 23 | unsigned short __res2; 24 | unsigned short tag_word; 25 | unsigned short __res3; 26 | unsigned int instruction_pointer_offset; 27 | unsigned short instruction_pointer_selector; 28 | unsigned short opcode; 29 | unsigned int data_pointer_offset; 30 | unsigned short data_pointer_selector; 31 | unsigned short __res4; 32 | } __attribute__((packed)) fpu_env; 33 | unsigned int mxcsr; 34 | } fenv_t; 35 | 36 | typedef unsigned short fexcept_t; 37 | 38 | extern int feclearexcept(int excepts); 39 | extern int fetestexcept(int excepts); 40 | extern int feraiseexcept(int excepts); 41 | extern int fegetexceptflag(fexcept_t* flagp, int excepts); 42 | extern int fesetexceptflag(const fexcept_t* flagp, int excepts); 43 | int fesetround(int round); 44 | int fegetround(); 45 | int fegetenv(fenv_t *envp); 46 | int fesetenv(const fenv_t *envp); 47 | int feholdexcept(fenv_t* envp); 48 | int feupdateenv(const fenv_t *envp); 49 | 50 | #endif /* FENV_H_ */ -------------------------------------------------------------------------------- /include/limits.h: -------------------------------------------------------------------------------- 1 | /* 2 | * limits.h 3 | * 4 | * Created on: 26.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef LIMITS_H_ 9 | #define LIMITS_H_ 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | //Grösse der Datentypen 16 | #define CHAR_BIT 8 //Anzahl Bits in einem Byte 17 | #define SCHAR_MIN (-128) //Kleinster Wert eines signed char 18 | #define SCHAR_MAX 127 //Grösster Wert eines signed char 19 | #define UCHAR_MAX 255 //Grösster Wert eines unsigned char 20 | #define CHAR_MIN SCHAR_MIN //Kleinster Wert eines char 21 | #define CHAR_MAX SCHAR_MAX //Grösster Wert eines char 22 | 23 | //TODO 24 | #define MB_LEN_MAX 1 //? 25 | 26 | #define SHRT_MIN (-32768) //Kleinster Wert eines short int 27 | #define SHRT_MAX 32767 //Grösster Wert eines short int 28 | #define USHRT_MAX 65535 //Grösster Wert eines unsigned short int 29 | 30 | #define INT_MIN (-2147483648) //Kleinster Wert eines int 31 | #define INT_MAX 2147483647 //Grösster Wert eines int 32 | #define UINT_MAX 4294967295U //Grösster Wert eines unsigned int 33 | 34 | #define LONG_MIN (-9223372036854775808ll) //Kleinster Wert eines long int 35 | #define LONG_MAX 9223372036854775807ll //Grösster Wert eines long int 36 | #define ULONG_MAX 18446744073709551615ull //Grösster Wert eines unsigned long int 37 | 38 | #define SIZE_MAX __SIZE_MAX__ 39 | 40 | //Posix 41 | #define NAME_MAX 255 //Maximale Länge eines Dateinamens ohne Nullzeichen 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | 47 | #endif /* LIMITS_H_ */ 48 | -------------------------------------------------------------------------------- /include/lock.h: -------------------------------------------------------------------------------- 1 | /* 2 | * lock.h 3 | * 4 | * Created on: 29.07.2013 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef LOCK_H_ 9 | #define LOCK_H_ 10 | 11 | #include "stdint.h" 12 | #include "stdbool.h" 13 | #include "stddef.h" 14 | 15 | #define LOCK_INIT NULL 16 | 17 | //Führt eine Funktion gelockt aus und gibt deren Resultat zurück 18 | #define LOCKED_RESULT(lck, task) \ 19 | ({ \ 20 | lock_node_t ___lock_node; \ 21 | lock(&lck, &___lock_node); \ 22 | typeof((task)) ___result = (task); \ 23 | unlock(&lck, &___lock_node); \ 24 | ___result; \ 25 | }) 26 | 27 | //Führt eine Funktion gelockt aus 28 | #define LOCKED_TASK(lck, task) \ 29 | { \ 30 | lock_node_t ___lock_node; \ 31 | lock(&lck, &___lock_node); \ 32 | task; \ 33 | unlock(&lck, &___lock_node); \ 34 | } 35 | 36 | //Versucht den lock zu holen und führt dann den task aus 37 | #define LOCKED_TRY_TASK(lck, task) \ 38 | { \ 39 | lock_node_t ___lock_node; \ 40 | if (try_lock(&lck, &___lock_node)) \ 41 | { \ 42 | task; \ 43 | unlock(&lck, &___lock_node); \ 44 | } \ 45 | } 46 | 47 | typedef struct lock_node { 48 | struct lock_node *next; 49 | bool locked; 50 | } lock_node_t; 51 | 52 | typedef lock_node_t *lock_t; 53 | 54 | bool try_lock(lock_t *lock, lock_node_t *node); 55 | void lock(lock_t *lock, lock_node_t *node); 56 | void unlock(lock_t *lock, lock_node_t *node); 57 | bool locked(const lock_t *lock); 58 | void lock_wait(lock_t *lock); 59 | 60 | #endif /* LOCK_H_ */ 61 | -------------------------------------------------------------------------------- /include/path.h: -------------------------------------------------------------------------------- 1 | /* 2 | * path.h 3 | * 4 | * Created on: 28.05.2017 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef PATH_H_ 9 | #define PATH_H_ 10 | 11 | #include 12 | #include 13 | 14 | /** 15 | * \brief Returns if a path is relative or absolute 16 | * 17 | * @param path Path to be checked 18 | * @return true if the path is relative, false otherwise 19 | */ 20 | bool path_isRelative(const char *path); 21 | 22 | /** 23 | * \brief Returns if a path element is valid 24 | * 25 | * @param element Element of path to be checked 26 | * @return true if element is a valid path element 27 | */ 28 | bool path_elementIsValid(const char *element); 29 | 30 | /** 31 | * \brief Gets an absolute path out of path 32 | * 33 | * The second parameter must be an absolute path to the current directory which will be prepended to path if path is a relative path. 34 | * 35 | * @param path Relative or absolute path to be converted 36 | * @param pwd Current working directory 37 | * @return a newly allocated string which holds the absolute path 38 | */ 39 | char *path_getAbsolute(const char *path, const char *pwd); 40 | 41 | /** 42 | * \brief Appends path2 to path1 43 | * 44 | * @param path1 Path 45 | * @param path2 Path to append 46 | * @return a newly allocated string which holds the result of the concatenation of path1 and path2 47 | */ 48 | char *path_append(const char *path1, const char *path2); 49 | 50 | 51 | /** 52 | * \brief Removes the last element of path and returns the new path 53 | * 54 | * This function removes the last element which is stored in element if element is not NULL in a newly allocated string. 55 | * The returned string is newly allocated and holds the path to the directory in which element is contained. 56 | * 57 | * @param path Path of which the last element should be removed 58 | * @param element The address to store a newly allocated string holding the removed element 59 | * @return a newly allocated string holding the path to the directory in which the removed element is contained 60 | */ 61 | char *path_removeLast(const char *path, char **element); 62 | 63 | /** 64 | * \brief Split the path into its elements 65 | * 66 | * This function splits the path into its elements. The elements are returned as an array of strings with a size of \p count. 67 | * The \p elements array has to be freed by the caller. The array is always allocated if no error occured. 68 | * 69 | * @param[in] path Path of which to extract the elements 70 | * @param[out] elements An array of strings containing copies of the elements. The caller is responsible for freeing it 71 | * @param[out] count The number of valid elements in the \p elements array 72 | * 73 | * @return non-zero if an error occured else 0 74 | */ 75 | int path_split(const char *path, char ***elements, size_t *count); 76 | 77 | #endif /* PATH_H_ */ 78 | -------------------------------------------------------------------------------- /include/setjmp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * setjmp.h 3 | * 4 | * Created on: 16.10.2017 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef SETJMP_H_ 9 | #define SETJMP_H_ 10 | 11 | #include 12 | 13 | #define setjmp(env) setjmp(env) 14 | 15 | typedef _uintptr_t jmp_buf[8]; 16 | 17 | int setjmp(jmp_buf env); 18 | void longjmp(jmp_buf env, int status) __attribute__((noreturn)); 19 | 20 | #endif /* SETJMP_H_ */ 21 | -------------------------------------------------------------------------------- /include/signal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * signal.h 3 | * 4 | * Created on: 05.06.2015 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef SIGNAL_H_ 9 | #define SIGNAL_H_ 10 | 11 | #ifndef BUILD_KERNEL 12 | 13 | #define SIGTERM 0 14 | #define SIGSEGV 1 15 | #define SIGINT 2 16 | #define SIGILL 3 17 | #define SIGABRT 4 18 | #define SIGFPE 5 19 | 20 | #define SIG_DFL __sig_dfl 21 | #define SIG_IGN __sig_ign 22 | #define SIG_ERR NULL 23 | 24 | void SIG_DFL(int signal); 25 | void SIG_IGN(int signal); 26 | void (*signal(int sig, void (*handler)(int)))(int); 27 | int raise(int sig); 28 | 29 | #endif 30 | 31 | #endif /* SIGNAL_H_ */ 32 | -------------------------------------------------------------------------------- /include/stdarg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * stdarg.h 3 | * 4 | * Created on: 22.10.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef STDARG_H_ 9 | #define STDARG_H_ 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | typedef __builtin_va_list va_list; 16 | #define va_start(ap, X) __builtin_va_start(ap, X) 17 | #define va_arg(ap, type) __builtin_va_arg(ap, type) 18 | #define va_end(ap) __builtin_va_end(ap) 19 | #define va_copy(dest, src) __builtin_va_copy(dest, src) 20 | 21 | #ifdef __cplusplus 22 | } 23 | #endif 24 | 25 | #endif /* STDARG_H_ */ 26 | -------------------------------------------------------------------------------- /include/stdbool.h: -------------------------------------------------------------------------------- 1 | /* 2 | * stdbool.h 3 | * 4 | * Created on: 26.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef STDBOOL_H_ 9 | #define STDBOOL_H_ 10 | 11 | #ifndef __bool_true_false_are_defined 12 | #ifndef _cplusplus 13 | typedef _Bool bool; 14 | #define true 1 15 | #define false 0 16 | #endif 17 | #define __bool_true_false_are_defined 1 18 | #endif 19 | 20 | #endif /* STDBOOL_H_ */ 21 | -------------------------------------------------------------------------------- /include/stddef.h: -------------------------------------------------------------------------------- 1 | /* 2 | * stddef.h 3 | * 4 | * Created on: 26.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef STDDEF_H_ 9 | #define STDDEF_H_ 10 | 11 | #include 12 | 13 | typedef _size_t size_t; 14 | typedef _ptrdiff_t ptrdiff_t; 15 | 16 | #ifndef NULL 17 | #define NULL (void*)0 18 | #endif 19 | 20 | #ifndef offsetof 21 | #define offsetof(type, field) ((size_t)(&((type *)0)->field)) 22 | #endif 23 | 24 | #endif /* STDDEF_H_ */ 25 | -------------------------------------------------------------------------------- /include/stdint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * stdint.h 3 | * 4 | * Created on: 26.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef STDINT_H_ 9 | #define STDINT_H_ 10 | 11 | #include 12 | #include 13 | 14 | typedef _uint128_t uint128_t; 15 | typedef _uint64_t uint64_t; 16 | typedef _uint32_t uint32_t; 17 | typedef _uint16_t uint16_t; 18 | typedef _uint8_t uint8_t; 19 | 20 | typedef _int128_t int128_t; 21 | typedef _int64_t int64_t; 22 | typedef _int32_t int32_t; 23 | typedef _int16_t int16_t; 24 | typedef _int8_t int8_t; 25 | 26 | typedef _uintptr_t uintptr_t; 27 | typedef _intptr_t intptr_t; 28 | 29 | typedef _uintmax_t _uintmax_t; 30 | typedef _intmax_t _intmax_t; 31 | 32 | #define INT8_MIN SCHAR_MIN 33 | #define INT16_MIN SHRT_MIN 34 | #define INT32_MIN INT_MIN 35 | #define INT64_MIN LONG_MIN 36 | 37 | #define INT8_MAX SCHAR_MAX 38 | #define INT16_MAX SHRT_MAX 39 | #define INT32_MAX INT_MAX 40 | #define INT64_MAX LONG_MAX 41 | 42 | #define UINT8_MAX UCHAR_MAX 43 | #define UINT16_MAX USHRT_MAX 44 | #define UINT32_MAX UINT_MAX 45 | #define UINT64_MAX ULONG_MAX 46 | 47 | #endif /* STDINT_H_ */ 48 | -------------------------------------------------------------------------------- /include/stdio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * stdio.h 3 | * 4 | * Created on: 26.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef STDIO_H_ 9 | #define STDIO_H_ 10 | 11 | #include 12 | #include "stdarg.h" 13 | #include "stdbool.h" 14 | #include "stdint.h" 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | #ifndef EOF 21 | #define EOF (-1) 22 | #endif 23 | 24 | #define _IONBF 0 25 | #define _IOLBF 1 26 | #define _IOFBF 2 27 | 28 | #ifndef SEEK_SET 29 | #define SEEK_SET 1 30 | #endif 31 | #ifndef SEEK_CUR 32 | #define SEEK_CUR 2 33 | #endif 34 | #ifndef SEEK_END 35 | #define SEEK_END 3 36 | #endif 37 | 38 | #define FILENAME_MAX 4096 39 | 40 | #define BUFSIZ 65536 41 | 42 | typedef _size_t size_t; 43 | 44 | typedef enum{ 45 | IO_MODE_NO_BUFFER, IO_MODE_LINE_BUFFER, IO_MODE_FULL_BUFFER 46 | }bufMode_t; 47 | 48 | typedef enum{ 49 | IO_NO_ERROR 50 | }io_error_t; 51 | 52 | 53 | typedef struct filestream FILE; 54 | 55 | typedef size_t fpos_t; 56 | 57 | extern FILE* stderr; 58 | extern FILE* stdin; 59 | extern FILE* stdout; 60 | 61 | extern FILE *fopen(const char *filename, const char *mode); 62 | extern int fclose(FILE *stream); 63 | extern size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); 64 | extern size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); 65 | extern int fflush(FILE *stream); 66 | extern void setbuf(FILE *stream, char *buffer); 67 | extern int setvbuf(FILE *stream, char *buffer, int mode, size_t size); 68 | extern int fseek(FILE *stream, long int offset, int whence); 69 | extern long int ftell(FILE *stream); 70 | extern int fsetpos(FILE *stream, const fpos_t *pos); 71 | extern int fgetpos(FILE *stream, fpos_t *pos); 72 | extern void rewind(FILE *stream); 73 | extern int feof(FILE *stream); 74 | 75 | extern int fgetc(FILE *stream); 76 | extern char *fgets(char *str, int n, FILE *stream); 77 | 78 | extern int fputc(int ch, FILE *stream); 79 | extern int fputs(const char *str, FILE *stream); 80 | 81 | extern int vfprintf(FILE *stream, const char *format, va_list arg); 82 | extern int vprintf(const char *format, va_list arg); 83 | extern int vsprintf(char *str, const char *format, va_list arg); 84 | extern int vsnprintf(char *str, int bufsz, const char *format, va_list arg); 85 | extern int vasprintf(char **str, const char *format, va_list arg); 86 | 87 | extern int fprintf(FILE *stream, const char *format, ...); 88 | extern int printf(const char *format, ...); 89 | extern int sprintf(char *str, const char *format, ...); 90 | extern int snprintf(char *str, int bufsz, const char *format, ...); 91 | extern int asprintf(char **str, const char *format, ...); 92 | 93 | extern int vfscanf(FILE *stream, const char *format, va_list arg); 94 | extern int vscanf(const char *format, va_list arg); 95 | extern int vsscanf(const char *str, const char *format, va_list arg); 96 | 97 | extern int fscanf(FILE *stream, const char *format, ...); 98 | extern int scanf(const char *format, ...); 99 | extern int sscanf(const char *str, const char *format, ...); 100 | 101 | extern int ungetc(int c, FILE *stream); 102 | extern int getc(FILE *stream); 103 | extern int getchar(void); 104 | extern char *gets(char *str); 105 | 106 | extern int putc(int ch, FILE *stream); 107 | extern int putchar(int zeichen); 108 | extern int puts(const char *str); 109 | 110 | #ifdef __cplusplus 111 | } 112 | #endif 113 | 114 | #endif /* STDIO_H_ */ 115 | -------------------------------------------------------------------------------- /include/stdlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | * stdlib.h 3 | * 4 | * Created on: 26.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef STDLIB_H_ 9 | #define STDLIB_H_ 10 | 11 | #include "stddef.h" 12 | #include "limits.h" 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | #define EXIT_SUCCESS 0 19 | #define EXIT_FAILURE 1 20 | #define RAND_MAX INT_MAX 21 | 22 | typedef struct{ 23 | int quot; 24 | int rem; 25 | }div_t; 26 | 27 | typedef struct{ 28 | long quot; 29 | long rem; 30 | }ldiv_t; 31 | 32 | typedef struct{ 33 | long long quot; 34 | long long rem; 35 | }lldiv_t; 36 | 37 | extern double atof(const char* str); 38 | extern int atoi(const char *str); 39 | extern long atol(const char *str); 40 | 41 | extern long int strtol(const char *str, char **endptr, int base); 42 | 43 | extern void *calloc(size_t nitems, size_t size); 44 | extern void free(void *ptr); 45 | extern void *malloc(size_t size); 46 | extern void *realloc(void *ptr, size_t size); 47 | 48 | extern void abort(void) __attribute__((noreturn)); 49 | extern int atexit(void (*func)(void)); 50 | extern void exit(int status) __attribute__((noreturn)); 51 | 52 | extern int abs(int x); 53 | extern long labs(long x); 54 | extern long long llabs(long long x); 55 | extern div_t div(int numer, int denom); 56 | extern ldiv_t ldiv(long numer, long denom); 57 | extern lldiv_t lldiv(long long numer, long long denom); 58 | extern int rand(void); 59 | extern long lrand(void); 60 | extern void srand(unsigned int seed); 61 | 62 | extern char *getenv(const char *name); 63 | extern int setenv(const char *name, const char *value, int overwrite); 64 | extern int unsetenv(const char *name); 65 | extern int putenv(char *str); 66 | 67 | extern void qsort(void *base, size_t n, size_t size, int (*cmp)(const void*, const void*)); 68 | extern void qsort_s(void *base, size_t n, size_t size, int (*cmp)(const void*, const void*, void*), void *context); 69 | 70 | extern void *bsearch(const void *key, const void *base, size_t n, size_t size, int (*cmp)(const void*, const void*)); 71 | extern void *bsearch_s(const void *key, const void *base, size_t n, size_t size, int (*cmp)(const void*, const void*, void*), void *context); 72 | 73 | #ifdef __cplusplus 74 | } 75 | #endif 76 | 77 | #endif /* STDLIB_H_ */ 78 | -------------------------------------------------------------------------------- /include/string.h: -------------------------------------------------------------------------------- 1 | /* 2 | * string.h 3 | * 4 | * Created on: 27.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef STRINGS_H_ 9 | #define STRINGS_H_ 10 | 11 | #include "stddef.h" 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | 17 | extern char *strcpy(char *to, const char *from); 18 | extern char *strncpy(char *to, const char *from, size_t size); 19 | extern int strcmp(const char *str1, const char *str2); 20 | extern int strncmp(const char *str1, const char *str2, size_t size); 21 | 22 | extern size_t strlen(const char *cs); 23 | extern void *strdup(const char *s); 24 | extern char *strtok(char *string, const char *delimiters); 25 | extern char *strtok_s(char **str, const char *delimiters); 26 | extern char *strcat(char *str1, const char *str2); 27 | extern char *strncat(char *str1, const char *str2, size_t n); 28 | 29 | extern char *strchr(const char *str, int ch); 30 | extern char *strrchr(const char *str, int ch); 31 | extern size_t strspn(const char *dest, const char *src); 32 | extern size_t strcspn(const char *dest, const char *src); 33 | extern char *strpbrk(const char *dest, const char *breakset); 34 | extern char *strstr(const char *str, const char *substr); 35 | 36 | extern void *memchr(const void *ptr, int ch, size_t count); 37 | extern int memcmp(const void *lhs, const void *rhs, size_t count); 38 | extern void *memset(void *block, int c, size_t n); 39 | extern void *memmove(void *to, const void *from, size_t size); 40 | extern void *memcpy (void *to, const void *from, size_t size); 41 | 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | 46 | #endif /* STRINGS_H_ */ 47 | -------------------------------------------------------------------------------- /include/sys/types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * types.h 3 | * 4 | * Created on: 16.07.2015 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef TYPES_H_ 9 | #define TYPES_H_ 10 | 11 | #include 12 | 13 | typedef _clock_t clock_t; 14 | typedef _uint64_t id_t; 15 | typedef _uint64_t ino_t; 16 | typedef _pid_t pid_t; 17 | typedef _size_t size_t; 18 | typedef _time_t time_t; 19 | 20 | typedef _uint64_t uid_t; 21 | typedef _uint64_t gid_t; 22 | typedef _uint64_t mode_t; 23 | typedef _uint64_t nlink_t; 24 | typedef _size_t off_t; 25 | 26 | #endif /* TYPES_H_ */ 27 | -------------------------------------------------------------------------------- /include/syscall.h: -------------------------------------------------------------------------------- 1 | /* 2 | * syscall.h 3 | * 4 | * Created on: 28.10.2014 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef BUILD_KERNEL 9 | 10 | #ifndef SYSCALL_H_ 11 | #define SYSCALL_H_ 12 | 13 | #include "stddef.h" 14 | #include "stdint.h" 15 | #include "stdbool.h" 16 | #include 17 | 18 | void *syscall_allocPages(size_t Pages); 19 | void syscall_freePages(void *Address, size_t Pages); 20 | void syscall_unusePages(void *Address, size_t Pages); 21 | 22 | pid_t syscall_createProcess(const char *path, const char *cmd, const char **env, const char *stdin, const char *stdout, const char *stderr); 23 | void syscall_exit(int status); 24 | pid_t syscall_wait(pid_t pid, int *status); 25 | tid_t syscall_createThread(void *entry, void *arg); 26 | void syscall_exitThread(int status); 27 | 28 | uint64_t syscall_fopen(char *path, vfs_mode_t mode); 29 | void syscall_fclose(uint64_t stream); 30 | size_t syscall_fread(uint64_t stream, uint64_t start, size_t length, const void *buffer); 31 | size_t syscall_fwrite(uint64_t stream, uint64_t start, size_t length, const void *buffer); 32 | uint64_t syscall_getStreamInfo(uint64_t stream, vfs_fileinfo_t info); 33 | void syscall_setStreamInfo(uint64_t stream, vfs_fileinfo_t info, uint64_t value); 34 | int syscall_truncate(const char *path, size_t size); 35 | int syscall_mount(const char *mountpoint, const char *device, const char *filesystem); 36 | int syscall_unmount(const char *mountpoint); 37 | int syscall_mkdir(const char *path); 38 | 39 | time_t syscall_getTimestamp(); 40 | void syscall_sleep(uint64_t msec); 41 | 42 | void syscall_getSysInfo(SIS *Struktur); 43 | 44 | #endif /* SYSCALL_H_ */ 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /include/time.h: -------------------------------------------------------------------------------- 1 | /* 2 | * time.h 3 | * 4 | * Created on: 18.07.2015 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef TIME_H_ 9 | #define TIME_H_ 10 | 11 | #include 12 | 13 | #define CLOCKS_PER_SEC 1000000l 14 | 15 | typedef _size_t size_t; 16 | typedef _clock_t clock_t; 17 | typedef _time_t time_t; 18 | 19 | struct tm{ 20 | int tm_sec; //Seconds [0,60] 21 | int tm_min; //Minutes [0,59] 22 | int tm_hour; //Hour [0,23] 23 | int tm_mday; //Day of month [1,31] 24 | int tm_mon; //Month of year [0,11] 25 | int tm_year; //Years since 1900 26 | int tm_wday; //Day of week [0,6] (Sunday =0) 27 | int tm_yday; //Day of year [0,365] 28 | int tm_isdst; //Daylight Savings flag 29 | }; 30 | 31 | struct timespec{ 32 | time_t tv_sec; //Seconds. 33 | long tv_nsec; //Nanoseconds. 34 | }; 35 | 36 | extern double difftime(time_t time_end, time_t time_beg); 37 | extern time_t time(time_t *res); 38 | extern clock_t clock(); 39 | 40 | extern struct tm *gmtime(const time_t *time); 41 | extern time_t mktime(struct tm *time); 42 | 43 | extern char *asctime(const struct tm *time); 44 | extern size_t strftime(char *restrict str, size_t count, const char *restrict format, const struct tm *restrict time); 45 | 46 | #endif /* TIME_H_ */ 47 | -------------------------------------------------------------------------------- /include/unistd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * unistd.h 3 | * 4 | * Created on: 18.07.2015 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef UNISTD_H_ 9 | #define UNISTD_H_ 10 | 11 | #include 12 | 13 | #ifndef NULL 14 | #define NULL (void*)0 15 | #endif 16 | 17 | //Konstanten für access() 18 | #define F_OK 1 //Test for existence of file. 19 | #define R_OK 2 //Test for read permission. 20 | #define W_OK 4 //Test for write permission. 21 | #define X_OK 8 //Test for execute (search) permission. 22 | 23 | #ifndef SEEK_SET 24 | #define SEEK_SET 1 25 | #endif 26 | #ifndef SEEK_CUR 27 | #define SEEK_CUR 2 28 | #endif 29 | #ifndef SEEK_END 30 | #define SEEK_END 3 31 | #endif 32 | 33 | #define STDERR_FILENO 2 //File number of stderr. 34 | #define STDIN_FILENO 0 //File number of stdin. 35 | #define STDOUT_FILENO 1 //File number of stdout. 36 | 37 | unsigned sleep(unsigned seconds); 38 | 39 | #endif /* UNISTD_H_ */ 40 | -------------------------------------------------------------------------------- /include/userlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | * userlib.h 3 | * 4 | * Created on: 11.08.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef USERLIB_H_ 9 | #define USERLIB_H_ 10 | 11 | #include "stddef.h" 12 | 13 | #ifndef BUILD_KERNEL 14 | #include "stdint.h" 15 | #include "syscall.h" 16 | 17 | #define sleep(msec) syscall_sleep(msec) 18 | #define getSysInfo(Struktur) syscall_getSysInfo(Struktur) 19 | 20 | pid_t createProcess(const char *path, const char *cmd, const char **env, const char *stdin, const char *stdout, const char *stderr); 21 | #endif 22 | 23 | void initLib(void); 24 | 25 | void reverse(char *s); 26 | size_t count_envs(const char **env); 27 | 28 | #endif /* USERLIB_H_ */ 29 | -------------------------------------------------------------------------------- /isr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * isr.h 3 | * 4 | * Created on: 15.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef ISR_H_ 9 | #define ISR_H_ 10 | 11 | #include "stdint.h" 12 | 13 | #define NUM_IRQ 16 14 | #define NUM_INTERRUPTS 256 15 | 16 | typedef struct{ 17 | uint64_t gs, fs, es, ds; 18 | uint64_t rsi, rdi, rbp; 19 | uint64_t r15, r14, r13, r12, r11, r10, r9, r8; 20 | uint64_t rdx, rcx, rbx, rax; 21 | uint64_t interrupt, error; 22 | uint64_t rip, cs, rflags, rsp, ss; 23 | }__attribute__((packed)) ihs_t; //Interrupt-Handler Stack 24 | 25 | typedef ihs_t*(*interrupt_handler)(ihs_t *ihs); 26 | 27 | void isr_Init(void); 28 | void isr_RegisterIRQHandler(uint16_t irq, void *Handler); 29 | 30 | interrupt_handler isr_setHandler(uint8_t num, interrupt_handler handler); 31 | ihs_t *isr_Handler(ihs_t *ihs); 32 | 33 | #endif /* ISR_H_ */ 34 | -------------------------------------------------------------------------------- /kernel.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_FORMAT(elf64-x86-64) 2 | OUTPUT_ARCH(i386:x86-64) 3 | /* Bei _start soll die Ausfuehrung losgehen */ 4 | ENTRY(_start) 5 | 6 | /* 7 | * Hier wird festgelegt, in welcher Reihenfolge welche Sektionen in die Binary 8 | * geschrieben werden sollen 9 | */ 10 | SECTIONS 11 | { 12 | /* 13 | * . ist die aktuelle Position in der Datei. Wir wollen den Kernel wie gehabt 14 | * an 1 MB laden, also muessen wir dort die erste Sektion hinlegen 15 | */ 16 | . = 0x100000; 17 | kernel_start = .; 18 | 19 | /* 20 | * Der Multiboot-Header muss zuerst kommen (in den ersten 8 kB). 21 | * Die Standardsektionen einfach hintereinander weg einbinden. 22 | */ 23 | kernel_code_start = .; 24 | .text : { 25 | /*(multiboot) kein Multibootheader vorhanden.*/ 26 | *(.text*) 27 | } 28 | kernel_code_end = .; 29 | .data ALIGN(4096) : { 30 | *(.data) 31 | } 32 | /*cdi_drivers ALIGN(4096) : { 33 | __start_cdi_drivers = .; 34 | *(cdi_drivers) 35 | } 36 | __stop_cdi_drivers = .;*/ 37 | .rodata ALIGN(4096) : { 38 | *(.rodata) 39 | } 40 | .bss ALIGN(4096) : { 41 | *(.bss) 42 | } 43 | kernel_end = .; 44 | } 45 | 46 | -------------------------------------------------------------------------------- /keyboard.h: -------------------------------------------------------------------------------- 1 | /* 2 | * keyboard.h 3 | * 4 | * Created on: 15.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef KEYBOARD_H_ 9 | #define KEYBOARD_H_ 10 | 11 | #include "stdbool.h" 12 | 13 | typedef enum{ 14 | __KEY_INVALID, //Ungültige Taste 15 | KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, 16 | KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z, 17 | KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, 18 | KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, 19 | KEY_F12, 20 | KEY_PRINT, KEY_SCROLL, KEY_PAUSE, 21 | KEY_TAB, KEY_CAPS, KEY_LSHIFT, KEY_LCTRL, KEY_LGUI, KEY_LALT, KEY_RSHIFT, KEY_RCTRL, 22 | KEY_RGUI, KEY_SPACE, KEY_ALTGR, KEY_MENU, KEY_ENTER, KEY_BACK, KEY_ESC, 23 | KEY_INS, KEY_DEL, KEY_HOME, KEY_END, KEY_PGUP, KEY_PGDOWN, 24 | KEY_UP, KEY_DOWN, KEY_RIGHT, KEY_LEFT, 25 | KEY_AUML, KEY_OUML, KEY_UUML, KEY_DP, KEY_DOL, 26 | KEY_ST, KEY_FRAG, KEY_DACH, 27 | KEY_BIGGER, KEY_COMMA, KEY_DOT, KEY_MIN, 28 | //Keypad-Tasten 29 | KEY_KPNUM, KEY_KPSLASH, KEY_KPMUL, KEY_KPMIN, KEY_KPPLUS, KEY_KPENTER, KEY_KPDOT, 30 | KEY_KP0, KEY_KP1, KEY_KP2, KEY_KP3, KEY_KP4, KEY_KP5, KEY_KP6, KEY_KP7, KEY_KP8, KEY_KP9, 31 | __KEY_LAST 32 | }KEY_t; //Alle Tasten 33 | 34 | /* 35 | * Parameter: Keycode der Taste 36 | */ 37 | typedef void(*key_handler)(void *opaque, KEY_t key); 38 | 39 | 40 | void keyboard_Init(void); 41 | 42 | /* 43 | * Registriert einen Handler beim Tastaturtreiber, der aufgerufen wird, sobald eine Taste gedrückt wurde 44 | * Parameter: Der aufzurufende Handler 45 | */ 46 | void keyboard_registerKeydownHandler(key_handler handler, void *opaque); 47 | 48 | /* 49 | * Registriert einen Handler beim Tastaturtreiber, der aufgerufen wird, sobald eine Taste losgelassen wurde 50 | * Parameter: Der aufzurufende Handler 51 | */ 52 | void keyboard_registerKeyupHandler(key_handler handler, void *opaque); 53 | 54 | /* 55 | * Gibt zurück, ob die Taste aktuell gedrückt ist. 56 | * Parameter: Die Taste, deren Status man haben will 57 | * Rückgabe: Status des Taste 58 | */ 59 | bool keyboard_isKeyPressed(KEY_t key); 60 | 61 | #endif /* KEYBOARD_H_ */ 62 | -------------------------------------------------------------------------------- /lib/Makefile: -------------------------------------------------------------------------------- 1 | CC = x86_64-elf-gcc 2 | LD = x86_64-elf-gcc 3 | AS = x86_64-elf-as 4 | AR = x86_64-elf-ar 5 | RM = rm -rf 6 | 7 | OUTPUT_DIR = build 8 | 9 | CPPFLAGS = -I"../include" 10 | CFLAGS = -gdwarf-4 -Wall -Wextra -fmessage-length=0 -m64 -ffreestanding -fno-stack-protector -fno-omit-frame-pointer -fPIC -std=gnu99 11 | ARFLAGS = -rs 12 | 13 | C_SRCS = $(shell find -name '*.c') 14 | S_SRCS = $(shell find -name '*.S' ! -name 'start.S') 15 | 16 | C_OBJS = $(patsubst ./%,$(OUTPUT_DIR)/%,$(C_SRCS:.c=.o)) 17 | S_OBJS = $(patsubst ./%,$(OUTPUT_DIR)/%,$(S_SRCS:.S=.o)) 18 | OBJS := $(C_OBJS) $(S_OBJS) 19 | DEPS := $(OBJS:.o=.d) 20 | 21 | ifeq ($(BUILD_CONFIG), release) 22 | CFLAGS+= -O3 23 | else 24 | CFLAGS+= -Og 25 | endif 26 | 27 | .PHONY: all 28 | all: $(OUTPUT_DIR)/crt0.o libc 29 | 30 | .PHONY: release 31 | release: 32 | $(MAKE) BUILD_CONFIG=$@ 33 | 34 | .PHONY: install 35 | install: all install-headers check-sysroot 36 | cp $(OUTPUT_DIR)/libc.a $(SYSROOT_DIR)/lib/libc.a 37 | cp $(OUTPUT_DIR)/crt0.o $(SYSROOT_DIR)/lib/crt0.o 38 | 39 | .PHONY: install-headers 40 | install-headers: check-sysroot 41 | cp -r ../include/* $(SYSROOT_DIR)/include/ 42 | 43 | .PHONY: check-sysroot 44 | check-sysroot: 45 | ifndef SYSROOT_DIR 46 | $(error SYSROOT_DIR is not set) 47 | endif 48 | 49 | .PHONY: libc 50 | libc: $(OUTPUT_DIR)/libc.a 51 | 52 | #Pull in dependency info for *existing* .o files 53 | -include $(DEPS) 54 | 55 | $(OUTPUT_DIR)/libc.a: $(OBJS) 56 | $(AR) $(ARFLAGS) -o $@ $^ 57 | 58 | $(OUTPUT_DIR)/crt0.o: start.S 59 | @mkdir -p $(@D) 60 | $(AS) -64 -o $@ $< 61 | 62 | $(OUTPUT_DIR)/%.o: %.c 63 | @mkdir -p $(@D) 64 | $(CC) $(CFLAGS) $(CPPFLAGS) -MMD -MP -MT $@ -c $< -o $@ 65 | 66 | $(OUTPUT_DIR)/%.o: %.S 67 | @mkdir -p $(@D) 68 | $(AS) -64 -o $@ $< 69 | 70 | .PHONY: clean 71 | clean: 72 | -$(RM) $(OUTPUT_DIR) 73 | -------------------------------------------------------------------------------- /lib/lock.c: -------------------------------------------------------------------------------- 1 | /* 2 | * lock.c 3 | * 4 | * Created on: 29.07.2013 5 | * Author: pascal 6 | */ 7 | 8 | #include "lock.h" 9 | 10 | #define pause() asm volatile("pause") 11 | 12 | bool locked(const lock_t *lock) { 13 | return *lock == NULL; 14 | } 15 | 16 | void lock(lock_t *lock, lock_node_t *node) { 17 | node->next = NULL; 18 | node->locked = true; 19 | 20 | lock_node_t *prev = __atomic_exchange_n(lock, node, __ATOMIC_ACQ_REL); 21 | if (prev != NULL) { 22 | __atomic_store_n(&prev->next, node, __ATOMIC_RELEASE); 23 | while (__atomic_load_n(&node->locked, __ATOMIC_ACQUIRE)) pause(); 24 | } 25 | } 26 | 27 | void unlock(lock_t *lock, lock_node_t *node) { 28 | if (__atomic_load_n(&node->next, __ATOMIC_ACQUIRE) == NULL) { 29 | lock_node_t *expected = node; 30 | if (__atomic_compare_exchange_n(lock, &expected, NULL, false, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) { 31 | // Nobody waiting 32 | return; 33 | } 34 | 35 | // Wait until someone is definitely enqueued 36 | while (__atomic_load_n(&node->next, __ATOMIC_ACQUIRE) == NULL) pause(); 37 | } 38 | // Release lock 39 | __atomic_store_n(&node->next->locked, false, __ATOMIC_RELEASE); 40 | } 41 | 42 | bool try_lock(lock_t *lock, lock_node_t *node) { 43 | node->next = NULL; 44 | lock_node_t *expected = NULL; 45 | return __atomic_compare_exchange_n(lock, &expected, node, false, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED); 46 | } 47 | 48 | void lock_wait(lock_t *lock) { 49 | while (__atomic_load_n(lock, __ATOMIC_RELAXED) != NULL) pause(); 50 | } 51 | -------------------------------------------------------------------------------- /lib/posix/unistd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * unistd.c 3 | * 4 | * Created on: 02.09.2018 5 | * Author: pascal 6 | */ 7 | 8 | #include "unistd.h" 9 | #ifdef BUILD_KERNEL 10 | #include "util.h" 11 | #else 12 | #include "syscall.h" 13 | #endif 14 | 15 | unsigned sleep(unsigned seconds) 16 | { 17 | #ifdef BUILD_KERNEL 18 | Sleep(seconds * 1000); 19 | #else 20 | syscall_sleep(seconds * 1000); 21 | #endif 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /lib/start.S: -------------------------------------------------------------------------------- 1 | .ifndef BUILD_KERNEL 2 | .code64 3 | 4 | .extern c_main 5 | .global _start 6 | 7 | .section .text 8 | _start: 9 | mov %rsp,%rdi 10 | #Stack wieder alignen 11 | and $~0xF,%rsp 12 | 13 | call c_main 14 | #Hier sollten wir nie hinkommen 15 | ud2 16 | 17 | .global syscall 18 | syscall: 19 | mov %rcx,%r10 20 | syscall 21 | retq 22 | 23 | .endif 24 | -------------------------------------------------------------------------------- /lib/stdlibc/assert.c: -------------------------------------------------------------------------------- 1 | /* 2 | * assert.c 3 | * 4 | * Created on: 21.08.2015 5 | * Author: pascal 6 | */ 7 | 8 | #include "assert.h" 9 | #include "stdio.h" 10 | #ifdef BUILD_KERNEL 11 | #include "display.h" 12 | #else 13 | #include "stdlib.h" 14 | #endif 15 | 16 | void _assert(const char *assertion, const char *file, unsigned int line, const char *function) 17 | { 18 | #ifdef BUILD_KERNEL 19 | printf("Assertion '%s' failed at line %u in %s:%s\n", assertion, line, file, function); 20 | Panic("KERNEL", "Assertion failure"); 21 | #else 22 | fprintf(stderr, "Assertion '%s' failed at line %u in %s:%s\n", assertion, line, file, function); 23 | abort(); 24 | #endif 25 | } 26 | -------------------------------------------------------------------------------- /lib/stdlibc/ctype.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ctype.c 3 | * 4 | * Created on: 28.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #include "ctype.h" 9 | 10 | int isalnum(int c) 11 | { 12 | return (isalpha(c) || isdigit(c)); 13 | } 14 | 15 | int isalpha(int c) 16 | { 17 | return (islower(c) || isupper(c)); 18 | } 19 | 20 | int isdigit(int c) 21 | { 22 | return (c >= '0' && c <= '9'); 23 | } 24 | 25 | int isspace(int c) 26 | { 27 | return (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v'); 28 | } 29 | 30 | int isxdigit(int c) 31 | { 32 | return (isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')); 33 | } 34 | 35 | int iscntrl(int c) 36 | { 37 | return ((c >= 0x00 && c <= 0x1F) || c == 0x7F); 38 | } 39 | 40 | int isgraph(int c) 41 | { 42 | return (isalnum(c) || ispunct(c)); 43 | } 44 | 45 | int isprint(int c) 46 | { 47 | return (isgraph(c) || c == 0x20); 48 | } 49 | 50 | int ispunct(int c) 51 | { 52 | return ((c >= 0x21 && c <= 0x2F) || (c >= 0x3A && c <= 0x40) || (c >= 0x5B && c <= 0x60) || (c >= 0x7B && c <= 0x7E)); 53 | } 54 | 55 | int islower(int c) 56 | { 57 | return (c >= 'a' && c <= 'z'); 58 | } 59 | 60 | int isupper(int c) 61 | { 62 | return (c >= 'A' && c <= 'Z'); 63 | } 64 | 65 | 66 | int tolower(int c) 67 | { 68 | return (isupper(c)) ? 'a' - 'A' + c : c; 69 | } 70 | 71 | int toupper(int c) 72 | { 73 | return (islower(c)) ? 'A' - 'a' + c : c; 74 | } 75 | -------------------------------------------------------------------------------- /lib/stdlibc/errno.c: -------------------------------------------------------------------------------- 1 | 2 | //TODO: sollte thread local sein 3 | int _errno = 0; -------------------------------------------------------------------------------- /lib/stdlibc/setjmp.S: -------------------------------------------------------------------------------- 1 | .code64 2 | 3 | .global setjmp 4 | .global longjmp 5 | 6 | .section .text 7 | setjmp: 8 | mov (%rsp), %rax 9 | lea -8(%rsp), %rcx 10 | mov %rcx, 0x0(%rdi) 11 | mov %rax, 0x8(%rdi) 12 | mov %rbx, 0x10(%rdi) 13 | mov %rbp, 0x18(%rdi) 14 | mov %r12, 0x20(%rdi) 15 | mov %r13, 0x28(%rdi) 16 | mov %r14, 0x30(%rdi) 17 | mov %r15, 0x38(%rdi) 18 | xor %eax, %eax 19 | ret 20 | 21 | longjmp: 22 | //Restore all state 23 | mov 0x0(%rdi), %rsp 24 | mov 0x10(%rdi), %rbx 25 | mov 0x18(%rdi), %rbp 26 | mov 0x20(%rdi), %r12 27 | mov 0x28(%rdi), %r13 28 | mov 0x30(%rdi), %r14 29 | mov 0x38(%rdi), %r15 30 | mov $1, %eax 31 | test %esi, %esi 32 | cmovz %eax, %esi 33 | mov %esi, %eax 34 | jmp *0x8(%rdi) 35 | -------------------------------------------------------------------------------- /lib/stdlibc/signal.c: -------------------------------------------------------------------------------- 1 | /* 2 | * signal.c 3 | * 4 | * Created on: 05.06.2015 5 | * Author: pascal 6 | */ 7 | 8 | #include "signal.h" 9 | #include "stdlib.h" 10 | #include "syscall.h" 11 | #include "stdio.h" 12 | 13 | #ifndef BUILD_KERNEL 14 | 15 | static void (*signal_handlers[6])(int) = {SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL}; 16 | 17 | void SIG_DFL(int signal) 18 | { 19 | switch(signal) 20 | { 21 | case SIGTERM: 22 | exit(EXIT_SUCCESS); 23 | break; 24 | case SIGSEGV: 25 | puts("segmentation fault"); 26 | abort(); 27 | break; 28 | case SIGINT: 29 | break; 30 | case SIGILL: 31 | puts("invalid instruction"); 32 | abort(); 33 | case SIGABRT: 34 | abort(); 35 | case SIGFPE: 36 | puts("erroneous arithmetic operation"); 37 | abort(); 38 | } 39 | } 40 | 41 | void SIG_IGN(int signal __attribute__((unused))) 42 | { 43 | } 44 | 45 | void (*signal(int sig, void (*handler)(int)))(int) 46 | { 47 | if(sig > 5) 48 | return SIG_ERR; 49 | return __atomic_exchange_n(&signal_handlers[sig], handler, __ATOMIC_SEQ_CST); 50 | } 51 | 52 | int raise(int sig) 53 | { 54 | if(sig > 5) 55 | return -1; 56 | signal_handlers[sig](sig); 57 | return 0; 58 | } 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /lib/stdlibc/syscall.c: -------------------------------------------------------------------------------- 1 | /* 2 | * syscall.c 3 | * 4 | * Created on: 28.10.2014 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef BUILD_KERNEL 9 | 10 | #include "syscall.h" 11 | #include 12 | 13 | extern uint64_t syscall(uint64_t func, ...); 14 | 15 | void *syscall_allocPages(size_t Pages) 16 | { 17 | return (void*)syscall(SYSCALL_ALLOC_PAGES, Pages); 18 | } 19 | 20 | void syscall_freePages(void *Address, size_t Pages) 21 | { 22 | syscall(SYSCALL_FREE_PAGES, Address, Pages); 23 | } 24 | 25 | void syscall_unusePages(void *Address, size_t Pages) 26 | { 27 | syscall(SYSCALL_UNUSE_PAGES, Address, Pages); 28 | } 29 | 30 | pid_t syscall_createProcess(const char *path, const char *cmd, const char **env, const char *stdin, const char *stdout, const char *stderr) 31 | { 32 | const char *stddevs[3] = {stdin, stdout, stderr}; 33 | return (pid_t)syscall(SYSCALL_EXEC, path, cmd, env, stddevs); 34 | } 35 | 36 | void __attribute__((noreturn)) syscall_exit(int status) 37 | { 38 | //Dieser syscall funktioniert nur über Interrupts 39 | syscall(SYSCALL_EXIT, status); 40 | while(1); 41 | } 42 | 43 | pid_t syscall_wait(pid_t pid, int *status) 44 | { 45 | return (pid_t)syscall(SYSCALL_WAIT, pid, status); 46 | } 47 | 48 | tid_t syscall_createThread(void *entry, void *arg) 49 | { 50 | return (tid_t)syscall(SYSCALL_THREAD_CREATE, entry, arg); 51 | } 52 | 53 | void __attribute__((noreturn)) syscall_exitThread(int status) 54 | { 55 | syscall(SYSCALL_THREAD_EXIT, status); 56 | } 57 | 58 | uint64_t syscall_fopen(char *path, vfs_mode_t mode) 59 | { 60 | return (void*)syscall(SYSCALL_OPEN, path, mode); 61 | } 62 | 63 | void syscall_fclose(uint64_t stream) 64 | { 65 | syscall(SYSCALL_CLOSE, stream); 66 | } 67 | 68 | size_t syscall_fread(uint64_t stream, uint64_t start, size_t length, const void *buffer) 69 | { 70 | return syscall(SYSCALL_READ, stream, start, length, buffer); 71 | } 72 | 73 | size_t syscall_fwrite(uint64_t stream, uint64_t start, size_t length, const void *buffer) 74 | { 75 | return syscall(SYSCALL_WRITE, stream, start, length, buffer); 76 | } 77 | 78 | uint64_t syscall_getStreamInfo(uint64_t stream, vfs_fileinfo_t info) 79 | { 80 | return syscall(SYSCALL_INFO_GET, stream, info); 81 | } 82 | 83 | void syscall_setStreamInfo(uint64_t stream, vfs_fileinfo_t info, uint64_t value) 84 | { 85 | syscall(SYSCALL_INFO_SET, stream, info, value); 86 | } 87 | 88 | int syscall_truncate(const char *path, size_t size) 89 | { 90 | return syscall(SYSCALL_TRUNCATE, path, size); 91 | } 92 | 93 | int syscall_mount(const char *mountpoint, const char *device, const char *filesystem) 94 | { 95 | return syscall(SYSCALL_MOUNT, mountpoint, device, filesystem); 96 | } 97 | 98 | int syscall_unmount(const char *mountpoint) 99 | { 100 | return syscall(SYSCALL_UNMOUNT, mountpoint); 101 | } 102 | 103 | int syscall_mkdir(const char *path) 104 | { 105 | return syscall(SYSCALL_MKDIR, path); 106 | } 107 | 108 | time_t syscall_getTimestamp() 109 | { 110 | return syscall(SYSCALL_GET_TIMESTAMP); 111 | } 112 | 113 | void syscall_sleep(uint64_t msec) 114 | { 115 | syscall(SYSCALL_SLEEP, msec); 116 | } 117 | 118 | void syscall_getSysInfo(SIS *Struktur) 119 | { 120 | syscall(SYSCALL_SYSINF_GET, Struktur); 121 | } 122 | 123 | #endif 124 | -------------------------------------------------------------------------------- /lib/stdlibc/userlib.c: -------------------------------------------------------------------------------- 1 | /* 2 | * userlib.c 3 | * 4 | * Created on: 11.08.2012 5 | * Author: pascal 6 | */ 7 | 8 | #include "userlib.h" 9 | #include "stdlib.h" 10 | #include "stdbool.h" 11 | #include "string.h" 12 | #include "stdio.h" 13 | 14 | extern void init_stdio(); 15 | 16 | void initLib() 17 | { 18 | init_stdio(); 19 | } 20 | #ifndef BUILD_KERNEL 21 | extern char **environ; 22 | extern void init_envvars(char **env); 23 | extern int main(int argc, char *argv[]); 24 | 25 | static int getArgCount(char *cmd) 26 | { 27 | int count = 0; 28 | char previous = '\0'; 29 | 30 | for(size_t i = 0; ; i++) 31 | { 32 | if(cmd[i] == '\0') 33 | { 34 | count++; 35 | break; 36 | } 37 | else if(cmd[i] == ' ' && previous != ' ') 38 | count++; 39 | previous = cmd[i]; 40 | } 41 | 42 | return count; 43 | } 44 | 45 | void c_main(char *data) 46 | { 47 | initLib(); 48 | 49 | int argc = getArgCount(data); 50 | char *argv[argc + 1]; 51 | 52 | char *env_start = (char*)((uintptr_t)data + strlen(data) + 1); 53 | size_t env_count = *(size_t*)env_start; 54 | env_start += sizeof(size_t); 55 | 56 | argv[0] = strtok(data, " "); 57 | 58 | for(int i = 1; i < argc; i++) 59 | { 60 | argv[i] = strtok(NULL, " "); 61 | } 62 | argv[argc] = NULL; 63 | 64 | char *envs[env_count + 1]; 65 | for(size_t i = 0; i < env_count; i++) 66 | { 67 | envs[i] = env_start; 68 | env_start += strlen(env_start) + 1; 69 | } 70 | envs[env_count] = NULL; 71 | 72 | init_envvars(envs); 73 | 74 | exit(main(argc, argv)); 75 | } 76 | 77 | pid_t createProcess(const char *path, const char *cmd, const char **env, const char *stdin, const char *stdout, const char *stderr) 78 | { 79 | const char **use_environ = env ? : (const char**)environ; 80 | if(path != NULL) 81 | { 82 | return syscall_createProcess(path, cmd, use_environ, stdin, stdout, stderr); 83 | } 84 | else 85 | { 86 | char *env = getenv("PATH"); 87 | if(env == NULL) 88 | return 0; 89 | char *env_copy = strdup(env); 90 | if(env_copy == NULL) 91 | return 0; 92 | 93 | char *env_tmp = env_copy; 94 | char *token; 95 | pid_t pid; 96 | while((token = strtok_s(&env_tmp, ":")) != NULL) 97 | { 98 | pid = syscall_createProcess(token, cmd, use_environ, stdin, stdout, stderr); 99 | if(pid != 0) 100 | break; 101 | } 102 | 103 | free(env_copy); 104 | return pid; 105 | } 106 | } 107 | 108 | #endif 109 | 110 | void reverse(char *s) 111 | { 112 | size_t i, j; 113 | for(i = 0, j = strlen(s) - 1; i < j; i++, j--) 114 | { 115 | char c = s[i]; 116 | s[i] = s[j]; 117 | s[j] = c; 118 | } 119 | } 120 | 121 | size_t count_envs(const char **env) 122 | { 123 | size_t count = 0; 124 | 125 | while(*env++ != NULL) count++; 126 | 127 | return count; 128 | } 129 | -------------------------------------------------------------------------------- /loader/elf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * elf.h 3 | * 4 | * Created on: 25.06.2012 5 | * Author: pascal 6 | * 7 | * Nach dem Tutorial "http://www.lowlevel.eu/wiki/ELF-Tutorial" 8 | */ 9 | 10 | #ifndef ELF_H_ 11 | #define ELF_H_ 12 | 13 | #include "vfs.h" 14 | #include "pm.h" 15 | 16 | //Funktionen 17 | ERROR_TYPE(pid_t) elfLoad(vfs_stream_t *file, const char *cmd, const char **env, const char *stdin, const char *stdout, const char *stderr); //Par.: Datei = Addresse der Datei im Speicher; Segment = Segment in das kopiert werden soll (GDT) 18 | 19 | #endif /* ELF_H_ */ 20 | -------------------------------------------------------------------------------- /loader/loader.c: -------------------------------------------------------------------------------- 1 | /* 2 | * loader.c 3 | * 4 | * Created on: 17.10.2014 5 | * Author: pascal 6 | */ 7 | 8 | #include "loader.h" 9 | #include "vfs.h" 10 | #include "elf.h" 11 | #include "string.h" 12 | 13 | ERROR_TYPE(pid_t) loader_load(const char *path, const char *cmd, const char **env, const char *stdin, const char *stdout, const char *stderr) 14 | { 15 | char *bin; 16 | 17 | if(path == NULL || cmd == NULL) 18 | return ERROR_RETURN_ERROR(pid_t, E_INVALID_ARGUMENT); 19 | 20 | //Zuerst erstellen wir den Pfad zur Datei, die geöffnet werden soll 21 | char cmdline[strlen(cmd) + 1]; 22 | strcpy(cmdline, cmd); 23 | bin = strtok(cmdline, " "); 24 | if(bin == NULL) 25 | return ERROR_RETURN_ERROR(pid_t, E_INVALID_ARGUMENT); 26 | char binpath[strlen(path) + 1 + strlen(cmdline) + 1]; 27 | strcpy(binpath, path); 28 | binpath[strlen(binpath) + 1] = '\0'; 29 | binpath[strlen(binpath)] = '/'; 30 | strcat(binpath, cmdline); 31 | 32 | //Jetzt können wir die Datei öffnen 33 | ERROR_TYPE_POINTER(vfs_stream_t) file = vfs_Open(binpath, VFS_MODE_READ); 34 | if(ERROR_DETECT(file)) 35 | return ERROR_RETURN_ERROR(pid_t, ERROR_GET_ERROR(file)); 36 | 37 | ERROR_TYPE(pid_t) elf_ret = elfLoad(ERROR_GET_VALUE(file), cmd, env, stdin, stdout, stderr); 38 | vfs_Close(ERROR_GET_VALUE(file)); 39 | return elf_ret; 40 | } 41 | 42 | pid_t loader_syscall_load(const char *path, const char *cmd, const char **env, const char *stddevs[3]) 43 | { 44 | //TODO: check env pointers 45 | if(!vmm_userspacePointerValid(path, strlen(path)) || !vmm_userspacePointerValid(cmd, strlen(cmd))) 46 | return 0; 47 | if((stddevs[0] != NULL && !vmm_userspacePointerValid(stddevs[0], strlen(stddevs[0]))) 48 | || (stddevs[1] != NULL && !vmm_userspacePointerValid(stddevs[1], strlen(stddevs[1]))) 49 | || (stddevs[2] != NULL && !vmm_userspacePointerValid(stddevs[2], strlen(stddevs[2])))) 50 | return 0; 51 | return ERROR_GET_VALUE(loader_load(path, cmd, env, stddevs[0], stddevs[1], stddevs[2])); //TODO: pass error to userspace 52 | } 53 | -------------------------------------------------------------------------------- /loader/loader.h: -------------------------------------------------------------------------------- 1 | /* 2 | * loader.h 3 | * 4 | * Created on: 17.10.2014 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef LOADER_H_ 9 | #define LOADER_H_ 10 | 11 | #include "pm.h" 12 | 13 | ERROR_TYPE(pid_t) loader_load(const char *path, const char *cmd, const char **env, const char *stdin, const char *stdout, const char *stderr); 14 | 15 | //Syscalls 16 | pid_t loader_syscall_load(const char *path, const char *cmd, const char **env, const char *stddevs[3]); 17 | 18 | #endif /* LOADER_H_ */ 19 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * kernel.c 3 | * 4 | * Created on: 27.06.2012 5 | * Author: pascal 6 | */ 7 | 8 | #include "config.h" 9 | #include "multiboot.h" 10 | #include "mm.h" 11 | #include "gdt.h" 12 | #include "idt.h" 13 | #include "display.h" 14 | #include "cpu.h" 15 | #include "pic.h" 16 | #include "keyboard.h" 17 | #include "pm.h" 18 | #include "debug.h" 19 | #include "cmos.h" 20 | #include "cdi.h" 21 | #include "vfs.h" 22 | #include "pit.h" 23 | #include "sound.h" 24 | #include "version.h" 25 | #include "loader.h" 26 | #include "stdio.h" 27 | #include "scheduler.h" 28 | #include "apic.h" 29 | #include "tss.h" 30 | #include "pci.h" 31 | #include "drivermanager.h" 32 | #include "devicemng.h" 33 | #include "console.h" 34 | #include "syscalls.h" 35 | #include 36 | 37 | static multiboot_structure static_MBS; 38 | 39 | multiboot_structure *Init(multiboot_structure *MBS); 40 | 41 | void __attribute__((noreturn)) main(multiboot_structure *MBS) 42 | { 43 | MBS = Init(MBS); //Initialisiere System 44 | if(MBS->mbs_flags & 0x1) 45 | printf("Bootdevice: %X\n", MBS->mbs_bootdevice); 46 | 47 | printf("Kernel version : %u.%u.%u\n", version_major, version_minor, version_bugfix); 48 | printf("Kernel commit : %s %s\n", version_branch, version_commitId); 49 | printf("Kernel build date: %s %s\n", version_buildDate, version_buildTime); 50 | printf("Kernel compiler : %s\n", version_compiler); 51 | if(vfs_MountRoot() || vfs_Mount("/dev", NULL, "devfs")) 52 | SysLogError("KERNEL", "Could not find root directory\n"); 53 | else 54 | { 55 | const char **env = {NULL}; 56 | loader_load("/bin", "init", env, "/dev/tty01", "/dev/tty01", "/dev/tty01"); 57 | scheduler_activate(); 58 | } 59 | 60 | //Der Kernel wird durch ein Interrupt aufgeweckt 61 | while(1) CPU_HALT(); //Wir wollen diese Funktion nicht verlassen 62 | } 63 | 64 | multiboot_structure *Init(multiboot_structure *MBS) 65 | { 66 | Display_Init(); //Anzeige Intialisieren 67 | cpu_init(true); //CPU Initialisieren 68 | GDT_Init(); //GDT initialisieren 69 | IDT_Init(); //IDT initialisieren 70 | TSS_Init(); //TSS initialisieren 71 | 72 | //MBS zwischenspeichern, bis Speicherverwaltung initialisiert ist, wenn nötig noch andere Strukturen sichern 73 | static_MBS = *MBS; 74 | MBS = &static_MBS; 75 | 76 | pit_Init(1000); //PIT initialisieren mit 1kHz 77 | pic_Init(); //PIC initialisieren 78 | cmos_Init(); //CMOS initialisieren 79 | syscall_Init(); //Syscall initialisieren 80 | #ifdef DEBUGMODE 81 | Debug_Init(); 82 | #endif 83 | if(!mm_Init((mmap*)(uintptr_t)MBS->mbs_mmap_addr, MBS->mbs_mmap_length)) //Speicherverwaltung initialisieren 84 | SysLogError("MM", "Fehler beim Initialisieren der Speicherverwaltung"); 85 | #ifdef DEBUGMODE 86 | asm volatile("int $0x1"); 87 | #endif 88 | //isr_Init(); 89 | keyboard_Init(); //Tastatur(treiber) initialisieren 90 | apic_Init(); 91 | vfs_Init(); //VFS initialisieren 92 | pci_Init(); //PCI-Treiber initialisieren 93 | drivermanager_init(); 94 | dmng_Init(); 95 | pm_Init(); //Tasks initialisieren 96 | console_Init(); 97 | dispatcher_init(100); 98 | 99 | SysLog("SYSTEM", "Initialisierung abgeschlossen"); 100 | setColor(BG_BLACK | CL_WHITE); 101 | #ifdef DEBUGMODE 102 | printf("Aktiviere Interrupts\n\r"); 103 | #endif 104 | CPU_ENABLE_INTERRUPTS(); 105 | cdi_init(); //CDI und -Treiber initialisieren 106 | return MBS; 107 | } 108 | -------------------------------------------------------------------------------- /mm/memory.h: -------------------------------------------------------------------------------- 1 | /* 2 | * memory.h 3 | * 4 | * Created on: 31.12.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef MEMORY_H_ 9 | #define MEMORY_H_ 10 | 11 | //Kernelspace 12 | #define KERNELSPACE_START 0x1000 //Kernelspace Anfang 13 | #define KERNELSPACE_END (0x8000000000 - 1) //Kernelspace Ende (512GB) 14 | 15 | //Userspace 16 | #define USERSPACE_START (KERNELSPACE_END + 1) //Userspace Anfang 17 | #define USERSPACE_END 0xFFFFFF7FFFFFFFFF //Userspace Ende 18 | #define MAX_ADDRESS 0xFFFFFFFFFFFFFFFF //Maximale Adresse 19 | 20 | #define MM_KERN_STACK_SIZE (4 * MM_BLOCK_SIZE) //Stackgrösse für einen Thread im Kernelspace 21 | 22 | #define MM_USER_STACK USERSPACE_END //Stackaddresse für Prozesse 23 | #define MM_USER_STACK_SIZE (4 * MM_BLOCK_SIZE) //Stackgrösse 24 | 25 | #define MM_GUARD_PAGES 1 // Number of guard pages 26 | 27 | #define MM_BLOCK_SIZE 4096 //Eine Blockgrösse 28 | 29 | #endif /* MEMORY_H_ */ 30 | -------------------------------------------------------------------------------- /mm/mm.c: -------------------------------------------------------------------------------- 1 | /* 2 | * mm.c 3 | * 4 | * Created on: 02.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #include "mm.h" 9 | #include "multiboot.h" 10 | #include "display.h" 11 | #include "vmm.h" 12 | #include "pmm.h" 13 | #include "memory.h" 14 | #include "scheduler.h" 15 | 16 | //Speicherverwaltung 17 | bool mm_Init(const mmap *map, uint32_t map_length) 18 | { 19 | return pmm_Init(map, map_length) && vmm_Init(); 20 | } 21 | 22 | /* 23 | * Reserviert Speicher für Pages Pages. 24 | * Parameter: Pages = Anzahl Pages, die reserviert werden sollen 25 | */ 26 | void *mm_Alloc(uint64_t Pages) 27 | { 28 | return vmm_Alloc(currentProcess->Context, Pages); 29 | } 30 | 31 | void mm_Free(void *Address, uint64_t Pages) 32 | { 33 | if(Address < (void*)USERSPACE_START || Address > (void*)USERSPACE_END) //Kontrolle ob richtiger Adress- 34 | Panic("MM", "Ungueltiger Adressbereich"); //bereich 35 | vmm_Free(currentProcess->Context, Address, Pages); 36 | } 37 | 38 | //System 39 | /* 40 | * Reserviert Speicher für das System 41 | * Parameter: Size = Grösse des Speicherbereichs, der reserviert werden soll in Bytes 42 | * Rückgabewert: Adresse, an die der Speichblock reserviert wurde 43 | */ 44 | void *mm_SysAlloc(uint64_t Size) 45 | { 46 | void *Address; 47 | Address = vmm_SysAlloc(Size); 48 | if(Address == (void*)1) Panic("MM", "Nicht genuegend physikalischer Speicher vorhanden"); 49 | if(Address == (void*)2) Panic("MM", "Virtuelle Adresse ist schon belegt"); 50 | if(Address == (void*)3) Panic("MM", "Nich genuegend virtueller Speicher vorhanden"); 51 | return Address; 52 | } 53 | 54 | /* 55 | * Gibt die angegebene Speicherstelle frei 56 | * Parameter: Address = virt. Adresse des Speicherbereichs 57 | * Size = Grösse des Speicherbereichs 58 | * 59 | * Rückgabewert: true = Speicherbereich erfolgreich freigegeben 60 | * false = Fehler beim Freigeben des Speicherbereichs 61 | */ 62 | bool mm_SysFree(void *Address, uint64_t Size) 63 | { 64 | if(Address > (void*)KERNELSPACE_END) return false; 65 | vmm_SysFree(Address, Size); 66 | return true; 67 | } 68 | -------------------------------------------------------------------------------- /mm/mm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * mm.h 3 | * 4 | * Created on: 02.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef MM_H_ 9 | #define MM_H_ 10 | 11 | #include "stdint.h" 12 | #include "paging.h" 13 | #include "stdbool.h" 14 | #include "multiboot.h" 15 | 16 | //Speicherverwaltung 17 | bool mm_Init(const mmap *map, uint32_t map_length); 18 | void *mm_Alloc(uint64_t Size); 19 | void mm_Free(void *Address, uint64_t Size); 20 | 21 | void *mm_SysAlloc(uint64_t Size); 22 | bool mm_SysFree(void *Address, uint64_t Size); 23 | 24 | #endif /* MM_H_ */ 25 | -------------------------------------------------------------------------------- /mm/paging.h: -------------------------------------------------------------------------------- 1 | /* 2 | * paging.h 3 | * 4 | * Created on: 07.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef PAGING_H_ 9 | #define PAGING_H_ 10 | 11 | #include "stdint.h" 12 | #include "stdbool.h" 13 | #include "pmm.h" 14 | 15 | /*Pagingstrukturen 16 | *PML4 = Page-Map-Level-4 Table 17 | *PML4E = Page-Map-Level-4 Entry 18 | *PDP = Page-Directory-Pointer Table 19 | *PDPE = Page-Directory-Pointer Entry 20 | *PD = Page-Directory Table 21 | *PDE = Page-Directory Entry 22 | *PT = Page Table 23 | *PTE = Page Table Entry 24 | */ 25 | //Allgemeine Bits in den Page Tabellen 26 | #define PG_P 0x1 27 | #define PG_RW 0x2 28 | #define PG_US 0x4 29 | #define PG_PWT 0x8 30 | #define PG_PCD 0x10 31 | #define PG_A 0x20 32 | //Nur in PTE vorhanden 33 | #define PG_D 0x40 34 | #define PG_PAT 0x80 35 | #define PG_G 0x100LL 36 | //Allgemein 37 | #define PG_AVL1 0xE00LL 38 | #define PG_ADDRESS 0xFFFFFFFFFF000LL 39 | #define PG_AVL2 0x7FF0000000000000LL 40 | #define PG_NX 0x8000000000000000LL 41 | #define PG_AVL(Entry) (((Entry & PG_AVL1) | ((Entry & PG_AVL2) >> 40)) >> 9) 42 | 43 | //Indices der Tabellen in der virtuellen Addresse 44 | #define PG_PML4_INDEX 0xFF8000000000 45 | #define PG_PDP_INDEX 0x7FC0000000 46 | #define PG_PD_INDEX 0x3FE00000 47 | #define PG_PT_INDEX 0x1FF000 48 | 49 | #define PG_PAGE_SIZE 4096 50 | #define PG_PAGE_ALIGN_ROUND_DOWN(n) ((n) & PG_ADDRESS) 51 | #define PG_PAGE_ALIGN_ROUND_UP(n) (((n) + ~PG_ADDRESS) & PG_ADDRESS) 52 | #define PG_NUM_PAGES(size) (PG_PAGE_ALIGN_ROUND_UP(size) / PG_PAGE_SIZE) 53 | 54 | #define MAP 4096 //Anzahl der Bytes pro Map (4kb) 55 | #define PAGE_ENTRIES 512 //Anzahl der Einträge pro Tabelle 56 | 57 | typedef union { 58 | struct { 59 | bool P: 1; 60 | bool RW: 1; 61 | bool US: 1; 62 | bool PWT: 1; 63 | bool PCD: 1; 64 | bool A: 1; 65 | bool D: 1; // Only valid on last level page table 66 | bool PS_PAT: 1; // PS: valid for PML4 (must be 0), PDP, PD. PAT: valid for PT 67 | bool G: 1; 68 | uint32_t AVL1: 3; 69 | paddr_t Address: 40; 70 | uint32_t AVL2: 11; 71 | bool NX: 1; 72 | }__attribute__((packed)); 73 | uint64_t entry; 74 | } PageTableEntry_t; 75 | 76 | typedef PageTableEntry_t* PageTable_t; 77 | 78 | typedef struct{ 79 | uint64_t PML4E[PAGE_ENTRIES]; 80 | }PML4_t; 81 | 82 | typedef struct{ 83 | uint64_t PDPE[PAGE_ENTRIES]; 84 | }PDP_t; 85 | 86 | typedef struct{ 87 | uint64_t PDE[PAGE_ENTRIES]; 88 | }PD_t; 89 | 90 | typedef struct{ 91 | uint64_t PTE[PAGE_ENTRIES]; 92 | }PT_t; 93 | 94 | void setPML4Entry(uint16_t i, PML4_t *PML4, bool Present, bool RW, bool US, bool PWT, 95 | bool PCD, bool A, uint16_t AVL, bool NX, paddr_t Address); 96 | void setPDPEntry(uint16_t i, PDP_t *PDP, bool Present, bool RW, bool US, bool PWT, 97 | bool PCD, bool A, uint16_t AVL, bool NX, paddr_t Address); 98 | void setPDEntry(uint16_t i, PD_t *PD, bool Present, bool RW, bool US, bool PWT, 99 | bool PCD, bool A, uint16_t AVL, bool NX, paddr_t Address); 100 | void setPTEntry(uint16_t i, PT_t *PT, bool Present, bool RW, bool US, bool PWT, 101 | bool PCD, bool A, bool D, bool G, uint16_t AVL, 102 | bool PAT, bool NX, paddr_t Address); 103 | void clearPML4Entry(uint16_t i, PML4_t *PML4); 104 | void clearPDPEntry(uint16_t i, PDP_t *PDP); 105 | void clearPDEntry(uint16_t i, PD_t *PD); 106 | void clearPTEntry(uint16_t i, PT_t *PT); 107 | 108 | void InvalidateTLBEntry(void *Address); 109 | #endif /* PAGING_H_ */ 110 | -------------------------------------------------------------------------------- /mm/pmm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pmm.h 3 | * 4 | * Created on: 09.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef PMM_H_ 9 | #define PMM_H_ 10 | 11 | #include "multiboot.h" 12 | #include "stdint.h" 13 | #include "stdbool.h" 14 | #include "stddef.h" 15 | 16 | //Eine Speicherstelle = 4kb 17 | 18 | typedef uintptr_t paddr_t; 19 | 20 | bool pmm_Init(const mmap *map, uint32_t map_length); //Initialisiert die physikalische Speicherverwaltung 21 | void pmm_markPageReserved(paddr_t address); 22 | paddr_t pmm_Alloc(void); //Allokiert eine Speicherstelle 23 | void pmm_Free(paddr_t Address); //Gibt eine Speicherstelle frei 24 | paddr_t pmm_AllocDMA(paddr_t maxAddress, size_t Size); 25 | uint64_t pmm_getTotalPages(); 26 | uint64_t pmm_getFreePages(); 27 | paddr_t pmm_getHighestAddress(); 28 | 29 | #endif /* PMM_H_ */ 30 | -------------------------------------------------------------------------------- /partition.h: -------------------------------------------------------------------------------- 1 | /* 2 | * partition.h 3 | * 4 | * Created on: 06.08.2014 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef PARTITION_H_ 9 | #define PARTITION_H_ 10 | 11 | #include "vfs.h" 12 | 13 | int partition_getPartitions(const char *dev_name, void(*partition_callback)(void *context, void*), void *context); 14 | 15 | #endif /* PARTITION_H_ */ 16 | -------------------------------------------------------------------------------- /pci.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pci.h 3 | * 4 | * Created on: 10.03.2013 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef PCI_H_ 9 | #define PCI_H_ 10 | 11 | #include "stdint.h" 12 | #include "stddef.h" 13 | #include "list.h" 14 | 15 | typedef enum{ 16 | BAR_UNDEFINED, BAR_INVALID, BAR_UNUSED, BAR_32, BAR_64LO, BAR_64HI, BAR_IO 17 | }TYPE_t; 18 | 19 | typedef struct{ 20 | uint32_t Address; 21 | size_t Size; 22 | TYPE_t Type; 23 | }pciBar_t; 24 | 25 | typedef struct{ 26 | uint8_t Bus, Slot, Function; 27 | uint16_t DeviceID, VendorID; 28 | uint8_t ClassCode, Subclass, RevisionID, ProgIF, HeaderType; 29 | uint8_t irq; 30 | pciBar_t BAR[6]; 31 | }pciDevice_t; 32 | 33 | extern list_t pciDevices; 34 | 35 | void pci_Init(); 36 | uint32_t pci_readConfig(uint8_t bus, uint8_t slot, uint8_t func, uint8_t reg, uint8_t length); 37 | void pci_writeConfig(uint8_t bus, uint8_t slot, uint8_t func, uint8_t reg, uint8_t length, uint32_t Data); 38 | 39 | #endif /* PCI_H_ */ 40 | -------------------------------------------------------------------------------- /pic.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PIC.c 3 | * 4 | * Created on: 14.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #include "pic.h" 9 | #include "util.h" 10 | #include "display.h" 11 | 12 | //Master 13 | #define PIC_MASTER_COMMAND 0x20 14 | #define PIC_MASTER_DATA 0x21 15 | #define PIC_MASTER_IMR 0x21 16 | 17 | //Slave 18 | #define PIC_SLAVE_COMMAND 0xA0 19 | #define PIC_SLAVE_DATA 0xA1 20 | #define PIC_SLAVE_IMR 0xA1 21 | 22 | //EOI 23 | #define EOI 0x20 24 | 25 | /* 26 | * Intitialisiert den PIC 27 | */ 28 | void pic_Init() 29 | { 30 | //IRQs fangen bei Interrupt 32 an 31 | pic_Remap(32); 32 | 33 | //Maskiere alle nicht gebrauchten IRQs (alle ausser PS/2 Port 1 und 2) 34 | pic_MaskIRQ(0x0); 35 | SysLog("PIC", "Initialisierung abgeschlossen"); 36 | } 37 | 38 | /* 39 | * Initialisiert den PIC auf eine bestimmte Interruptnummer 40 | * Parameter: Interrupt = Nummer des Interrupts, an den der IRQ 0 sein soll (vielfaches von 8) 41 | */ 42 | void pic_Remap(uint8_t Interrupt) 43 | { 44 | //Master PIC 45 | outb(PIC_MASTER_COMMAND, 0x11); //0x11 bedeuted, dass wir Initialisieren wollen und es 46 | //zwei PICs gibt 47 | outb(PIC_MASTER_DATA, Interrupt); //Interruptnummer senden 48 | outb(PIC_MASTER_DATA, 0x04); //Interruptnummer des Slaves übergeben (Bit-Maske) 49 | outb(PIC_MASTER_DATA, 0x01); //Wir befinden uns im 8086-Mode 50 | 51 | //Slave PIC 52 | outb(PIC_SLAVE_COMMAND, 0x11); //0x11 bedeuted, dass wir Initialisieren wollen und es 53 | //zwei PICs gibt 54 | outb(PIC_SLAVE_DATA, Interrupt + 8);//Interruptnummer senden 55 | outb(PIC_SLAVE_DATA, 2); //Interruptnummer des Slaves übergeben 56 | outb(PIC_SLAVE_DATA, 0x01); //Wir befinden uns im 8086-Mode 57 | } 58 | 59 | /* 60 | * Maskiert einzelne IRQs (deaktiviert sie) 61 | * Parameter: Mask = Bitmaske (0 = entsprechender IRQ aktiviert) 62 | */ 63 | void pic_MaskIRQ(uint16_t Mask) 64 | { 65 | outb(PIC_MASTER_IMR, (uint8_t)Mask); 66 | outb(PIC_SLAVE_IMR, (uint8_t)Mask >> 8); 67 | } 68 | 69 | /* 70 | * Sendet den EOI (End of Interrupt) an den PIC 71 | * Parameter: irq = IRQ-Nummer 72 | */ 73 | void pic_SendEOI(uint8_t irq) 74 | { 75 | outb(PIC_MASTER_COMMAND, EOI); 76 | if(irq > 7) 77 | outb(PIC_SLAVE_COMMAND, EOI); 78 | } 79 | -------------------------------------------------------------------------------- /pic.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pic.h 3 | * 4 | * Created on: 14.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef PIC_H_ 9 | #define PIC_H_ 10 | 11 | #include "stdint.h" 12 | 13 | void pic_Init(void); 14 | void pic_Remap(uint8_t Interrupt); 15 | void pic_MaskIRQ(uint16_t Mask); 16 | void pic_SendEOI(uint8_t irq); 17 | 18 | #endif /* PIC_H_ */ 19 | -------------------------------------------------------------------------------- /pit.c: -------------------------------------------------------------------------------- 1 | /* 2 | * pit.c 3 | * 4 | * Created on: 16.03.2014 5 | * Author: pascal 6 | */ 7 | 8 | #include "pit.h" 9 | #include "util.h" 10 | #include "list.h" 11 | #include "stdlib.h" 12 | #include "scheduler.h" 13 | #include "lock.h" 14 | 15 | #define CH0 0x40 16 | #define CH1 0x41 17 | #define CH2 0x42 18 | #define CH_BASE CH0 19 | #define REGINIT 0x43 20 | 21 | #define FRQB 1193182 22 | 23 | typedef struct{ 24 | thread_t *thread; 25 | uint64_t timeout; 26 | }timer_t; 27 | 28 | static list_t Timerlist; 29 | static lock_t Timerlist_lock = LOCK_INIT; 30 | 31 | void pit_Init(uint32_t freq) 32 | { 33 | pit_InitChannel(0, 2, (uint64_t)(FRQB / freq)); 34 | 35 | Timerlist = NULL; 36 | Uptime = 0; 37 | } 38 | 39 | void pit_InitChannel(uint8_t channel, uint8_t mode, uint16_t data) 40 | { 41 | if(channel > 2) return; 42 | outb(REGINIT, 0 | ((mode & 0x7) << 1) | (0x3 << 4) | (channel << 6)); 43 | outb(CH_BASE + channel, data & 0xFF); 44 | outb(CH_BASE + channel, data >> 8); 45 | } 46 | 47 | //Registriert einen Timer 48 | void pit_RegisterTimer(thread_t *thread, uint64_t msec) 49 | { 50 | if(msec != 0) 51 | { 52 | timer_t *Timer; 53 | size_t i; 54 | uint64_t t; 55 | 56 | Timer = malloc(sizeof(timer_t)); 57 | 58 | Timer->thread = thread; 59 | Timer->timeout = ((t = Uptime + msec) < Uptime) ? -1ul : t; 60 | 61 | LOCKED_TASK(Timerlist_lock, { 62 | if(Timerlist == NULL) 63 | Timerlist = list_create(); 64 | 65 | //Timerliste sortiere, sodass das Element vorne immer das Element ist, welches 66 | //zuerst abläuft 67 | timer_t *item; 68 | for(i = 0; (item = list_get(Timerlist, i)); i++) 69 | { 70 | if(item->timeout > Timer->timeout) 71 | break; 72 | } 73 | 74 | list_insert(Timerlist, i, Timer); 75 | }); 76 | 77 | //Entsprechenden Thread schlafen legen 78 | thread_block_self(NULL, NULL, THREAD_BLOCKED_WAIT_TIMER); 79 | } 80 | else 81 | { 82 | //Thread switchen 83 | yield(); 84 | } 85 | } 86 | 87 | void pit_Handler(void) 88 | { 89 | timer_t *Timer; 90 | size_t i = 0; 91 | Uptime++; 92 | if(Timerlist) 93 | { 94 | LOCKED_TRY_TASK(Timerlist_lock, { 95 | while((Timer = list_get(Timerlist, i))) 96 | { 97 | if(Timer->timeout > Uptime) 98 | break; 99 | if(thread_try_unblock(Timer->thread)) 100 | free(list_remove(Timerlist, i)); 101 | else 102 | break; 103 | i++; 104 | } 105 | }); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /pit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pit.h 3 | * 4 | * Created on: 16.03.2014 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef PIT_H_ 9 | #define PIT_H_ 10 | 11 | #include "stdint.h" 12 | #include "thread.h" 13 | 14 | volatile uint64_t Uptime; //Zeit in Milisekunden seit dem Starten des Computers 15 | 16 | void pit_Init(uint32_t freq); 17 | void pit_RegisterTimer(thread_t *thread, uint64_t msec); 18 | void pit_InitChannel(uint8_t channel, uint8_t mode, uint16_t data); 19 | 20 | #endif /* PIT_H_ */ 21 | -------------------------------------------------------------------------------- /sound.c: -------------------------------------------------------------------------------- 1 | /* 2 | * sound.c 3 | * 4 | * Created on: 18.03.2014 5 | * Author: pascal 6 | */ 7 | 8 | #include "sound.h" 9 | #include "pit.h" 10 | #include "util.h" 11 | 12 | #define PIT_FRQ 1193182 13 | 14 | static void switch_on() 15 | { 16 | outb(0x61, inb(0x61) | 0x3); 17 | } 18 | 19 | static void switch_off() 20 | { 21 | outb(0x61, inb(0x61) & ~0x3); 22 | } 23 | 24 | void sound_Play(uint32_t freq, uint64_t sleep) 25 | { 26 | pit_InitChannel(2, 3, PIT_FRQ / freq); 27 | 28 | switch_on(); 29 | Sleep(sleep); 30 | switch_off(); 31 | } 32 | -------------------------------------------------------------------------------- /sound.h: -------------------------------------------------------------------------------- 1 | /* 2 | * sound.h 3 | * 4 | * Created on: 18.03.2014 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef SOUND_H_ 9 | #define SOUND_H_ 10 | 11 | #include "stdint.h" 12 | 13 | void sound_Play(uint32_t freq, uint64_t sleep); 14 | 15 | #endif /* SOUND_H_ */ 16 | -------------------------------------------------------------------------------- /start.S: -------------------------------------------------------------------------------- 1 | .code64 2 | .extern main 3 | .global _start 4 | .global stack 5 | 6 | _start: 7 | #Initialisiere Stack 8 | mov $(stack),%rsp 9 | xor %ebp, %ebp 10 | 11 | #Lege Multiboot-Struktur-Adresse auf den Stack 12 | #push %rbx 13 | #Multiboot-Struktur_Adresse in edi übergeben, weil der gcc das so verlangt laut disassembler 14 | mov %rbx,%rdi 15 | call main 16 | _stop: 17 | cli 18 | hlt 19 | jmp _stop 20 | 21 | .section .bss 22 | .align 0x10 23 | .space 0x10000 #64KB Platz für den Kernelstack 24 | stack: 25 | -------------------------------------------------------------------------------- /syscalls.h: -------------------------------------------------------------------------------- 1 | /* 2 | * syscalls.h 3 | * 4 | * Created on: 17.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef SYSCALLS_H_ 9 | #define SYSCALLS_H_ 10 | 11 | void syscall_Init(); 12 | 13 | #endif /* SYSCALLS_H_ */ 14 | -------------------------------------------------------------------------------- /tasks/cleaner.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cleaner.c 3 | * 4 | * Created on: 29.05.2015 5 | * Author: pascal 6 | */ 7 | 8 | #include "cleaner.h" 9 | #include "stack.h" 10 | #include "stdlib.h" 11 | #include "scheduler.h" 12 | 13 | extern thread_t *cleanerThread; 14 | 15 | static stack_t *cleanStack; 16 | 17 | void __attribute__((noreturn)) cleaner() 18 | { 19 | while(1) 20 | { 21 | clean_entry_t *entry; 22 | while(stack_pop(cleanStack, (void**)&entry)) 23 | { 24 | switch(entry->type) 25 | { 26 | case CL_PROCESS: 27 | pm_DestroyTask(entry->data); 28 | break; 29 | case CL_THREAD: 30 | while(((thread_t*)entry->data)->Status.status != THREAD_BLOCKED) yield(); 31 | thread_destroy(entry->data, true); 32 | } 33 | free(entry); 34 | } 35 | thread_block_self(NULL, NULL, THREAD_BLOCKED_WAIT); 36 | } 37 | } 38 | 39 | void cleaner_Init() 40 | { 41 | cleanStack = stack_create(); 42 | } 43 | 44 | //FIXME 45 | void cleaner_cleanProcess(process_t *process) 46 | { 47 | clean_entry_t *entry = malloc(sizeof(clean_entry_t)); 48 | 49 | entry->type = CL_PROCESS; 50 | entry->data = process; 51 | 52 | stack_push(cleanStack, entry); 53 | thread_unblock(cleanerThread); 54 | } 55 | 56 | void cleaner_cleanThread(thread_t *thread) 57 | { 58 | clean_entry_t *entry = malloc(sizeof(clean_entry_t)); 59 | 60 | entry->type = CL_THREAD; 61 | entry->data = thread; 62 | 63 | stack_push(cleanStack, entry); 64 | thread_unblock(cleanerThread); 65 | thread_block_self(NULL, NULL, THREAD_BLOCKED_WAIT); 66 | } 67 | -------------------------------------------------------------------------------- /tasks/cleaner.h: -------------------------------------------------------------------------------- 1 | /* 2 | * cleaner.h 3 | * 4 | * Created on: 29.05.2015 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef CLEANER_H_ 9 | #define CLEANER_H_ 10 | 11 | #include "pm.h" 12 | #include "thread.h" 13 | 14 | typedef enum{ 15 | CL_PROCESS, CL_THREAD 16 | }clean_type_t; 17 | 18 | typedef struct{ 19 | void *data; 20 | clean_type_t type; 21 | }clean_entry_t; 22 | 23 | void cleaner(); 24 | 25 | void cleaner_Init(); 26 | void cleaner_cleanProcess(process_t *process); 27 | void cleaner_cleanThread(thread_t *thread); 28 | 29 | #endif /* CLEANER_H_ */ 30 | -------------------------------------------------------------------------------- /tasks/dispatcher.c: -------------------------------------------------------------------------------- 1 | /* 2 | * dispatcher.c 3 | * 4 | * Created on: 14.06.2017 5 | * Author: pascal 6 | */ 7 | 8 | #include "dispatcher.h" 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | typedef struct{ 16 | dispatcher_task_handler_t func; 17 | void *opaque; 18 | }dispatcher_task_t; 19 | 20 | static lock_t dispatcher_lock = LOCK_INIT; 21 | static dispatcher_task_t *queue; 22 | static size_t queue_size; 23 | static uint64_t queue_start, queue_end; 24 | 25 | void dispatcher_init(size_t max_count) 26 | { 27 | queue_size = max_count; 28 | queue = calloc(queue_size, sizeof(dispatcher_task_t)); 29 | queue_start = queue_end = 0; 30 | } 31 | 32 | void dispatcher_enqueue(dispatcher_task_handler_t handler, void *opaque) 33 | { 34 | LOCKED_TASK(dispatcher_lock, { 35 | if((queue_end >= queue_start && queue_end < queue_size) 36 | || (queue_end < queue_start && queue_start > 0)) 37 | { 38 | dispatcher_task_t *task = &queue[queue_end++]; 39 | task->func = handler; 40 | task->opaque = opaque; 41 | } 42 | if(queue_end == queue_size && queue_start > 0) 43 | queue_end = 0; 44 | }); 45 | } 46 | 47 | static ihs_t *dispatch_wrapper(ihs_t *state, uintptr_t ret, dispatcher_task_handler_t func, void *opaque) 48 | { 49 | //Is mostly a no-op because the return value of the interrupt handler should not be modified 50 | *((uintptr_t*)state - 1) = ret; 51 | func(opaque); 52 | return state; 53 | } 54 | 55 | ihs_t *dispatcher_dispatch(ihs_t *state) 56 | { 57 | static const ihs_t init_state = { 58 | .cs = 0x8, 59 | .ss = 0x10, 60 | .es = 0x10, 61 | .ds = 0x10, 62 | .gs = 0x10, 63 | .fs = 0x10, 64 | 65 | //IRQs einschalten (IF = 1) 66 | .rflags = 0x202, 67 | 68 | //Interrupt ist beim Schedulen 32 69 | .interrupt = 32 70 | }; 71 | static ihs_t new_state; 72 | 73 | LOCKED_TRY_TASK(dispatcher_lock, { 74 | if(queue_start != queue_end) 75 | { 76 | dispatcher_task_t *task = &queue[queue_start++]; 77 | 78 | if(queue_start == queue_size) 79 | queue_start = 0; 80 | 81 | memcpy(&new_state, &init_state, sizeof(ihs_t)); 82 | new_state.rip = (uintptr_t)dispatch_wrapper; 83 | new_state.rsp = (uintptr_t)state - 8; 84 | 85 | new_state.rdi = (uintptr_t)state; 86 | new_state.rsi = *((uintptr_t*)state - 1); 87 | new_state.rdx = (uintptr_t)task->func; 88 | new_state.rcx = (uintptr_t)task->opaque; 89 | state = &new_state; 90 | } 91 | }); 92 | 93 | return state; 94 | } 95 | -------------------------------------------------------------------------------- /tasks/dispatcher.h: -------------------------------------------------------------------------------- 1 | /* 2 | * dispatcher.h 3 | * 4 | * Created on: 14.06.2017 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef DISPATCHER_H_ 9 | #define DISPATCHER_H_ 10 | 11 | #include 12 | 13 | typedef void (*dispatcher_task_handler_t)(void *opaque); 14 | 15 | void dispatcher_init(); 16 | void dispatcher_enqueue(dispatcher_task_handler_t handler, void *opaque); 17 | 18 | ihs_t *dispatcher_dispatch(ihs_t *state); 19 | 20 | #endif /* DISPATCHER_H_ */ 21 | -------------------------------------------------------------------------------- /tasks/pm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pm.h 3 | * 4 | * Created on: 30.12.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef PM_H_ 9 | #define PM_H_ 10 | 11 | #include "isr.h" 12 | #include "stdint.h" 13 | #include "vmm.h" 14 | #include "list.h" 15 | #include "hashmap.h" 16 | #include "avl.h" 17 | #include "lock.h" 18 | #include 19 | #include 20 | 21 | typedef _pid_t pid_t; 22 | typedef _tid_t tid_t; 23 | ERROR_TYPEDEF(pid_t); 24 | 25 | typedef enum{ 26 | PM_BLOCKED, PM_RUNNING, PM_TERMINATED 27 | }pm_status_t; 28 | 29 | typedef struct process_t{ 30 | context_t *Context; 31 | pid_t PID; 32 | tid_t next_tid; 33 | struct process_t *parent; 34 | char *cmd; 35 | pm_status_t Status; 36 | avl_tree *threads; 37 | list_t terminated_childs, waiting_threads, waiting_threads_pid; 38 | hashmap_t *streams; 39 | void *nextThreadStack; 40 | lock_t lock; 41 | int exit_status; 42 | }process_t; 43 | ERROR_TYPEDEF_POINTER(process_t); 44 | 45 | extern process_t *currentProcess; //Aktueller Prozess 46 | 47 | void pm_Init(void); 48 | ERROR_TYPE_POINTER(process_t) pm_InitTask(process_t *parent, void *entry, char* cmd, const char **env, const char *stdin, const char *stdout, const char *stderr); 49 | void pm_DestroyTask(process_t *process); 50 | void pm_ExitTask(int code); 51 | void pm_BlockTask(process_t *process); 52 | void pm_ActivateTask(process_t *process); 53 | process_t *pm_getTask(pid_t PID); 54 | pid_t pm_WaitChild(pid_t pid, int *status); 55 | 56 | //syscalls 57 | void pm_syscall_exit(int status); 58 | pid_t pm_syscall_wait(pid_t pid, int *status); 59 | 60 | #endif /* PM_H_ */ 61 | -------------------------------------------------------------------------------- /tasks/scheduler.c: -------------------------------------------------------------------------------- 1 | /* 2 | * scheduler.c 3 | * 4 | * Created on: 20.02.2015 5 | * Author: pascal 6 | */ 7 | 8 | #include "scheduler.h" 9 | #include "ring.h" 10 | #include "lock.h" 11 | #include "stdbool.h" 12 | 13 | extern thread_t *fpuThread; 14 | 15 | process_t kernel_process = { 16 | .Context = &kernel_context, 17 | .cmd = "kernel", 18 | .next_tid = 1 19 | }; 20 | thread_t* idleThread; 21 | 22 | static ring_t* scheduleList; 23 | static lock_t schedule_lock = LOCK_INIT; 24 | static bool active = false; 25 | thread_t *currentThread; 26 | process_t *currentProcess; 27 | 28 | /* 29 | * Initialisiert den Scheduler 30 | */ 31 | void scheduler_Init() 32 | { 33 | scheduleList = ring_create(); 34 | } 35 | 36 | /* 37 | * Aktiviert den Scheduler 38 | */ 39 | void scheduler_activate() 40 | { 41 | active = true; 42 | } 43 | 44 | /* 45 | * Fügt einen Thread der Schedulingliste hinzu 46 | * 47 | * Parameter: thread = Thread, der hinzugefügt werden soll 48 | */ 49 | bool scheduler_try_add(thread_t *thread) 50 | { 51 | bool res = false; 52 | LOCKED_TRY_TASK(schedule_lock, { 53 | ring_add(scheduleList, &thread->ring_entry); 54 | res = true; 55 | }); 56 | return res; 57 | } 58 | 59 | /* 60 | * Fügt einen Thread der Schedulingliste hinzu 61 | * 62 | * Parameter: thread = Thread, der hinzugefügt werden soll 63 | */ 64 | void scheduler_add(thread_t *thread) 65 | { 66 | while(!scheduler_try_add(thread)) CPU_PAUSE(); 67 | } 68 | 69 | /* 70 | * Entfernt ein Thread aus der Schedulingliste 71 | * 72 | * Parameter: thread = Thread, der entfernt werden soll 73 | */ 74 | void scheduler_remove(thread_t *thread) 75 | { 76 | LOCKED_TASK(schedule_lock, { 77 | if(ring_contains(scheduleList, &thread->ring_entry)) 78 | ring_remove(scheduleList, &thread->ring_entry); 79 | }); 80 | } 81 | 82 | /* 83 | * Wechselt den aktuellen Thread 84 | * 85 | * Rückgabe: Neuer Thread, der ausgeführt werden soll 86 | */ 87 | ihs_t *scheduler_schedule(ihs_t *state) 88 | { 89 | thread_t *newThread; 90 | 91 | if(!active) 92 | return state; 93 | 94 | if(currentThread != NULL) 95 | { 96 | currentThread->State = state; 97 | } 98 | 99 | lock_node_t lock_node; 100 | if(try_lock(&schedule_lock, &lock_node)) 101 | { 102 | newThread = (thread_t*)ring_getNext(scheduleList); 103 | if(newThread == NULL) 104 | newThread = idleThread; 105 | unlock(&schedule_lock, &lock_node); 106 | 107 | if(newThread != currentThread) 108 | { 109 | if(currentProcess != newThread->process) 110 | activateContext(newThread->process->Context); 111 | thread_prepare(newThread); 112 | 113 | currentProcess = newThread->process; 114 | currentThread = newThread; 115 | 116 | if(fpuThread == currentThread) 117 | { 118 | asm volatile("clts"); 119 | } 120 | else 121 | { 122 | //TS-Bit setzen 123 | uint64_t cr0 = cpu_readControlRegister(CPU_CR0); 124 | cpu_writeControlRegister(CPU_CR0, cr0 | (1 << 3)); 125 | } 126 | } 127 | } 128 | 129 | return currentThread->State; 130 | } 131 | 132 | /* 133 | * Wechselt den aktuellen Thread 134 | */ 135 | //TODO: Interrupt für wechsel 136 | void yield() 137 | { 138 | asm volatile("int $0xFF"); 139 | } 140 | -------------------------------------------------------------------------------- /tasks/scheduler.h: -------------------------------------------------------------------------------- 1 | /* 2 | * scheduler.h 3 | * 4 | * Created on: 20.02.2015 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef SCHEDULER_H_ 9 | #define SCHEDULER_H_ 10 | 11 | #include "pm.h" 12 | #include "thread.h" 13 | #include "cpu.h" 14 | #include "stdbool.h" 15 | #include "isr.h" 16 | 17 | extern process_t kernel_process; 18 | extern thread_t *currentThread; 19 | extern process_t *currentProcess; 20 | 21 | void scheduler_Init(); 22 | void scheduler_activate(); 23 | void scheduler_add(thread_t *thread); 24 | bool scheduler_try_add(thread_t *thread); 25 | void scheduler_remove(thread_t *thread); 26 | 27 | ihs_t *scheduler_schedule(ihs_t *state); 28 | 29 | void yield(); 30 | 31 | #endif /* SCHEDULER_H_ */ 32 | -------------------------------------------------------------------------------- /tss.c: -------------------------------------------------------------------------------- 1 | /* 2 | * tss.c 3 | * 4 | * Created on: 02.11.2012 5 | * Author: pascal 6 | */ 7 | 8 | #include "tss.h" 9 | #include "gdt.h" 10 | #include "string.h" 11 | #include 12 | 13 | #define SELECTOR 5 14 | 15 | typedef struct{ 16 | uint16_t Selector; 17 | }__attribute__((packed)) tr_t; 18 | 19 | typedef struct{ 20 | uint32_t IGN; 21 | uint64_t rsp0; 22 | uint64_t rsp1; 23 | uint64_t rsp2; 24 | uint64_t IGN2; 25 | uint64_t ist[7]; 26 | uint64_t IGN3; 27 | uint16_t IGN4; 28 | uint16_t MapBaseAddress; 29 | uint8_t IOPD[8192]; 30 | }__attribute__((packed)) tss_entry_t; 31 | 32 | tss_entry_t tss; 33 | 34 | void TSS_Init() 35 | { 36 | //GDT-Eintrag erstellen 37 | GDT_SetSystemDescriptor(SELECTOR, (uintptr_t)&tss, sizeof(tss), 0x89, 0x0); 38 | 39 | //Task-Segment Selector 40 | tr_t tr; 41 | tr.Selector = SELECTOR << 3; 42 | 43 | //TSS initialisieren 44 | tss.MapBaseAddress = 0x96; 45 | memset(tss.IOPD, 0, 8192); 46 | 47 | //Taskergister laden 48 | asm volatile("ltr %0" : : "m"(tr)); 49 | } 50 | 51 | void TSS_setStack(void *stack) 52 | { 53 | tss.rsp0 = (uint64_t)stack; 54 | } 55 | 56 | void TSS_setIST(uint32_t ist, void *ist_stack) { 57 | ist--; 58 | assert(ist < 7); 59 | tss.ist[ist] = (uint64_t)ist_stack; 60 | } 61 | -------------------------------------------------------------------------------- /tss.h: -------------------------------------------------------------------------------- 1 | /* 2 | * tss.h 3 | * 4 | * Created on: 02.11.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef TSS_H_ 9 | #define TSS_H_ 10 | 11 | #include 12 | 13 | void TSS_Init(void); 14 | void TSS_setStack(void *stack); 15 | void TSS_setIST(uint32_t ist, void *ist_stack); 16 | 17 | #endif /* TSS_H_ */ 18 | -------------------------------------------------------------------------------- /util/avl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * avl.h 3 | * 4 | * Created on: 18.09.2015 5 | * Author: pascal 6 | */ 7 | 8 | /* 9 | * Copyright by Andris Suter-Dörig 10 | * MIT License 11 | */ 12 | 13 | #ifndef AVL_H_ 14 | #define AVL_H_ 15 | 16 | #include "stdbool.h" 17 | #include "stdint.h" 18 | 19 | typedef enum avl_visiting_method_e { 20 | avl_visiting_pre_order, 21 | avl_visiting_in_order, 22 | avl_visiting_post_order 23 | } avl_visiting_method; 24 | 25 | typedef struct avl_tree_s avl_tree; 26 | 27 | /* 28 | * Fügt Element element in *root ein. Gibt zurück ob eingefügt 29 | */ 30 | bool avl_add_s(avl_tree** root, void* element, int (*comp)(const void*, const void*, void*), void* context); 31 | 32 | /* 33 | * Löscht element aus *root. Gibt zurück ob gelöscht 34 | */ 35 | bool avl_remove_s(avl_tree** root, void* element, int (*comp)(const void*, const void*, void*), void* context); 36 | 37 | /* 38 | * Sucht element in root. Gibt zurück ob gefunden 39 | */ 40 | bool avl_search_s(avl_tree* root, void* element, int (*comp)(const void*, const void*, void*), void* context); 41 | 42 | /* 43 | * Besucht alle Knoten. 44 | */ 45 | int avl_visit_s(avl_tree* root, avl_visiting_method method, void (*visiter)(const void*, void*), void* context); 46 | 47 | /* 48 | * Fügt element hinzu 49 | */ 50 | bool avl_add(avl_tree** root, void* element, int (*comp)(const void*, const void*)); 51 | bool avl_remove(avl_tree** root, void* element, int (*comp)(const void*, const void*)); 52 | bool avl_search(avl_tree* root, void* element, int (*comp)(const void*, const void*)); 53 | int avl_visit(avl_tree* root, avl_visiting_method method, void (*visiter)(const void*)); 54 | 55 | /* 56 | * Löscht den gesamten Baum 57 | */ 58 | void avl_free(avl_tree* tree, void (*action)(void*)); 59 | 60 | #endif /* AVL_H_ */ 61 | -------------------------------------------------------------------------------- /util/bit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * bit.h 3 | * 4 | * Created on: 05.06.2018 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef BIT_H_ 9 | #define BIT_H_ 10 | 11 | #define BIT_MASK(bit) (1ul << bit) 12 | #define BIT_EXTRACT(x, bit) (!!(x & BIT_MASK(bit))) 13 | #define BIT_SET(x, bit) (x | BIT_MASK(bit)) 14 | #define BIT_CLEAR(x, bit) (x & ~BIT_MASK(bit)) 15 | 16 | #endif /* BIT_H_ */ 17 | -------------------------------------------------------------------------------- /util/debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * debug.h 3 | * 4 | * Created on: 15.03.2013 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef DEBUG_H_ 9 | #define DEBUG_H_ 10 | 11 | #include "isr.h" 12 | #include "stdbool.h" 13 | 14 | #define DEBUG_CONTINUE 0x0 15 | #define DEBUG_SINGLESTEP 0x1 16 | 17 | volatile bool Debugged; 18 | 19 | void Debug_Init(void); 20 | void Debug_Main(ihs_t *ihs); 21 | 22 | uint64_t traceRegistersToString(ihs_t *ihs, char *out); 23 | uint64_t traceStackToString(uint64_t rsp, uint64_t *rbp, uint8_t length, char *out); 24 | 25 | #endif /* DEBUG_H_ */ 26 | -------------------------------------------------------------------------------- /util/hash_helpers.c: -------------------------------------------------------------------------------- 1 | /* 2 | * hash_helpers.c 3 | * 4 | * Created on: 07.01.2018 5 | * Author: pascal 6 | */ 7 | 8 | #include "hash_helpers.h" 9 | #include 10 | #include 11 | 12 | //Murmur2 hash taken from https://github.com/aappleby/smhasher 13 | uint64_t string_hash(const void *key, __attribute__((unused)) void *context) 14 | { 15 | size_t len = strlen((const char*)key); 16 | const uint64_t m = 0xc6a4a7935bd1e995lu; 17 | const int r = 47; 18 | 19 | uint64_t h = len * m; 20 | 21 | const uint64_t *data = (const uint64_t*)key; 22 | const uint64_t *end = data + (len / 8); 23 | 24 | while(data != end) 25 | { 26 | uint64_t k = *data++; 27 | 28 | k *= m; 29 | k ^= k >> r; 30 | k *= m; 31 | 32 | h ^= k; 33 | h *= m; 34 | } 35 | 36 | const unsigned char *data2 = (const unsigned char*)data; 37 | 38 | switch(len & 7) 39 | { 40 | case 7: h ^= (uint64_t)data2[6] << 48; 41 | /* no break */ 42 | case 6: h ^= (uint64_t)data2[5] << 40; 43 | /* no break */ 44 | case 5: h ^= (uint64_t)data2[4] << 32; 45 | /* no break */ 46 | case 4: h ^= (uint64_t)data2[3] << 24; 47 | /* no break */ 48 | case 3: h ^= (uint64_t)data2[2] << 16; 49 | /* no break */ 50 | case 2: h ^= (uint64_t)data2[1] << 8; 51 | /* no break */ 52 | case 1: h ^= (uint64_t)data2[0]; 53 | h *= m; 54 | }; 55 | 56 | h ^= h >> r; 57 | h *= m; 58 | h ^= h >> r; 59 | 60 | return h; 61 | } 62 | 63 | bool string_equal(const void *a, const void *b, __attribute__((unused)) void *context) 64 | { 65 | const char *stra = a; 66 | const char *strb = b; 67 | return strcmp(stra, strb) == 0; 68 | } 69 | -------------------------------------------------------------------------------- /util/hash_helpers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * hash_helpers.h 3 | * 4 | * Created on: 07.01.2018 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef HASH_HELPERS_H_ 9 | #define HASH_HELPERS_H_ 10 | 11 | #include 12 | #include 13 | 14 | uint64_t string_hash(const void *key, void *context); 15 | bool string_equal(const void *a, const void *b, void *context); 16 | 17 | #endif /* HASH_HELPERS_H_ */ 18 | -------------------------------------------------------------------------------- /util/hashmap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * hashmap.h 3 | * 4 | * Created on: 12.11.2015 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef HASHMAP_H_ 9 | #define HASHMAP_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #define HASH_MAP_SUCCESS 0 16 | #define HASH_MAP_SUCCESS_FOUND 1 17 | 18 | #define HASH_MAP_DUPLICATE_KEY -1 19 | #define HASH_MAP_NO_MEMORY -10 20 | 21 | typedef struct hashmap hashmap_t; 22 | 23 | hashmap_t* hashmap_create( 24 | uint64_t (*hash1)(const void* key, void* context), /*Hash function used for lookup / insertion. Has to satisfy equal(key1, key2) => hash(key1) == hash(key2).*/ 25 | uint64_t (*hash2)(const void* key, void* context), /*Hash function used for collision resolution. Has to satisfy equal(key1, key2) => hash(key1) == hash(key2).*/ 26 | bool (*equal)(const void* key1, const void* key2, void* context), /*Function used to test for key equality.*/ 27 | void (*free_key)(const void* key), 28 | void (*free_obj)(const void* obj), 29 | void* context, /*value passed to hash and equality functions as context parameter*/ 30 | void (*free_cntx)(const void* cntx), 31 | size_t min_size /*expected amount of entries in hashtable*/ 32 | ); 33 | 34 | hashmap_t* hashmap_create_min( 35 | uint64_t (*hash)(const void* key, void* context), /*Hash function used for lookup / insertion. Has to satisfy equal(key1, key2) => hash(key1) == hash(key2).*/ 36 | bool (*equal)(const void* key1, const void* key2, void* context) /*Function used to test for key equality.*/ 37 | ); 38 | 39 | void hashmap_destroy(hashmap_t* map); 40 | 41 | int hashmap_search(hashmap_t* map, const void* key, void** result); 42 | int hashmap_delete(hashmap_t* map, const void* key); 43 | int hashmap_set(hashmap_t* map, const void* key, const void* obj); 44 | 45 | size_t hashmap_size(hashmap_t* map); 46 | 47 | void hashmap_visit(hashmap_t* map, void (*visitor)(const void* key, const void* obj, void* context), void* context); 48 | 49 | #endif /* HASHMAP_H_ */ 50 | -------------------------------------------------------------------------------- /util/mutex.c: -------------------------------------------------------------------------------- 1 | /* 2 | * mutex.c 3 | * 4 | * Created on: 08.11.2017 5 | * Author: pascal 6 | */ 7 | 8 | #include "mutex.h" 9 | #include "assert.h" 10 | #include "scheduler.h" 11 | 12 | void mutex_init(mutex_t *mutex) 13 | { 14 | assert(mutex != NULL); 15 | mutex->owner = 0; 16 | mutex->waiting = queue_create(); 17 | mutex->lock = LOCK_INIT; 18 | } 19 | 20 | void mutex_destroy(mutex_t *mutex) 21 | { 22 | assert(mutex != NULL); 23 | // Set garbage so that the mutex can no longer be used 24 | static lock_node_t lock_node; 25 | lock(&mutex->lock, &lock_node); 26 | queue_destroy(mutex->waiting); 27 | } 28 | 29 | void mutex_lock(mutex_t *mutex) 30 | { 31 | assert(mutex != NULL); 32 | 33 | tid_t self = currentThread->tid; 34 | 35 | while(!__sync_bool_compare_and_swap(&mutex->owner, 0, self)) 36 | { 37 | LOCKED_TASK(mutex->lock, queue_enqueue(mutex->waiting, currentThread)); 38 | while(!thread_block_self((thread_bail_out_t)mutex_unlock, mutex, THREAD_BLOCKED_MUTEX)); 39 | } 40 | } 41 | 42 | int mutex_unlock(mutex_t *mutex) 43 | { 44 | assert(mutex != NULL); 45 | 46 | tid_t self = currentThread->tid; 47 | 48 | if(!__sync_bool_compare_and_swap(&mutex->owner, self, 0)) 49 | return 1; 50 | 51 | LOCKED_TASK(mutex->lock, thread_unblock(queue_dequeue(mutex->waiting))); 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /util/mutex.h: -------------------------------------------------------------------------------- 1 | /* 2 | * mutex.h 3 | * 4 | * Created on: 08.11.2017 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef MUTEX_H_ 9 | #define MUTEX_H_ 10 | 11 | #include "thread.h" 12 | #include "lock.h" 13 | #include "queue.h" 14 | 15 | typedef struct{ 16 | tid_t owner; 17 | queue_t *waiting; 18 | lock_t lock; 19 | }mutex_t; 20 | 21 | void mutex_init(mutex_t *mutex); 22 | void mutex_destroy(mutex_t *mutex); 23 | void mutex_lock(mutex_t *mutex); 24 | int mutex_unlock(mutex_t *mutex); 25 | 26 | #endif /* MUTEX_H_ */ 27 | -------------------------------------------------------------------------------- /util/queue.c: -------------------------------------------------------------------------------- 1 | /* 2 | * queue.c 3 | * 4 | * Created on: 31.08.2015 5 | * Author: pascal 6 | */ 7 | 8 | #include "queue.h" 9 | #include "stdlib.h" 10 | #include "assert.h" 11 | 12 | /* 13 | * Erstellt eine neue Queue. 14 | * 15 | * Rückgabe: Zeiger auf Queuestruktur 16 | */ 17 | queue_t *queue_create() 18 | { 19 | return calloc(1, sizeof(queue_t)); 20 | } 21 | 22 | /* 23 | * Zerstört eine Queue 24 | * 25 | * Parameter: queue = Die freizugebende Queue 26 | */ 27 | void queue_destroy(queue_t *queue) 28 | { 29 | assert(queue != NULL); 30 | 31 | while(queue->size) 32 | queue_dequeue(queue); 33 | free(queue); 34 | } 35 | 36 | size_t queue_size(queue_t* queue) 37 | { 38 | assert(queue != NULL); 39 | 40 | return queue->size; 41 | } 42 | 43 | /* 44 | * Schiebt das Element in die Queue 45 | * 46 | * Parameter: queue = Queue in die das nächste Element geschoben werden soll 47 | * value = Wert des Elements 48 | * Rückabe: Wert des Elements 49 | */ 50 | void *queue_enqueue(queue_t *queue, void *value) 51 | { 52 | assert(queue != NULL); 53 | 54 | queue_entry_t *entry = malloc(sizeof(queue_entry_t)); 55 | if(entry == NULL) 56 | return NULL; 57 | 58 | entry->value = value; 59 | if(queue->size != 0) 60 | queue->begin->next = entry; 61 | queue->begin = entry; 62 | if(queue->end == NULL) 63 | queue->end = entry; 64 | queue->size++; 65 | return value; 66 | } 67 | 68 | /* 69 | * Holt das nächste Element aus der Queue 70 | * 71 | * Parameter: queue = Queue aus der das nächste Element geholt werden soll 72 | * Rückabe: Wert des Elements 73 | */ 74 | void *queue_dequeue(queue_t *queue) 75 | { 76 | assert(queue != NULL); 77 | if(queue->size == 0) 78 | return NULL; 79 | 80 | queue_entry_t *entry = queue->end; 81 | void *value = entry->value; 82 | queue->end = entry->next; 83 | queue->size--; 84 | free(entry); 85 | return value; 86 | } 87 | -------------------------------------------------------------------------------- /util/queue.h: -------------------------------------------------------------------------------- 1 | /* 2 | * queue.h 3 | * 4 | * Created on: 31.08.2015 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef QUEUE_H_ 9 | #define QUEUE_H_ 10 | 11 | #include "stddef.h" 12 | 13 | typedef struct queue_entry_s{ 14 | void *value; 15 | struct queue_entry_s *next; 16 | }queue_entry_t; 17 | 18 | typedef struct{ 19 | queue_entry_t *begin; 20 | queue_entry_t *end; 21 | size_t size; 22 | }queue_t; 23 | 24 | queue_t *queue_create(); 25 | void queue_destroy(queue_t *queue); 26 | size_t queue_size(queue_t* queue); 27 | void *queue_enqueue(queue_t *queue, void *value); 28 | void *queue_dequeue(queue_t *queue); 29 | 30 | #endif /* QUEUE_H_ */ 31 | -------------------------------------------------------------------------------- /util/refcount.c: -------------------------------------------------------------------------------- 1 | /* 2 | * refcount.c 3 | * 4 | * Created on: 21.03.2017 5 | * Author: pascal 6 | */ 7 | 8 | #include "refcount.h" 9 | #include "assert.h" 10 | 11 | void refcount_init(void *obj, size_t offset, void (*free)(const void*)) 12 | { 13 | refcount_t *o = (refcount_t*)((uintptr_t)obj + offset); 14 | o->ref_count = 1; 15 | o->free = free; 16 | } 17 | 18 | void *refcount_retain(void *obj, size_t offset) 19 | { 20 | refcount_t *o = (refcount_t*)((uintptr_t)obj + offset); 21 | uint64_t val, oldval; 22 | 23 | assert(o->ref_count > 0); 24 | 25 | do 26 | { 27 | oldval = o->ref_count; 28 | if(oldval == 0) return NULL; 29 | val = __sync_val_compare_and_swap(&o->ref_count, oldval, oldval + 1); 30 | } 31 | while(val != oldval && val != 0); 32 | 33 | if(val == 0) 34 | return NULL; 35 | else 36 | return obj; 37 | } 38 | 39 | bool refcount_release(void *obj, size_t offset) 40 | { 41 | refcount_t *o = (refcount_t*)((uintptr_t)obj + offset); 42 | if(__sync_add_and_fetch(&o->ref_count, -1) == 0 && o->free != NULL) 43 | { 44 | o->free(obj); 45 | return true; 46 | } 47 | return false; 48 | } 49 | -------------------------------------------------------------------------------- /util/refcount.h: -------------------------------------------------------------------------------- 1 | /* 2 | * refcount.h 3 | * 4 | * Created on: 21.03.2017 5 | * Author: pascal 6 | */ 7 | /** 8 | * \file 9 | * Contains functions for reference counting 10 | */ 11 | 12 | #ifndef REFCOUNT_H_ 13 | #define REFCOUNT_H_ 14 | 15 | #include "stdint.h" 16 | #include "stddef.h" 17 | #include "stdbool.h" 18 | 19 | //Name of the reference count field 20 | #define REFCOUNT_FIELD_NAME __refcount 21 | 22 | /** 23 | * \brief Generates a field needed for reference counting. 24 | * 25 | * This macro generates a structure field which is needed when using reference counting. 26 | */ 27 | #define REFCOUNT_FIELD refcount_t REFCOUNT_FIELD_NAME 28 | 29 | /** 30 | * \brief Initializes the reference counting of an object. 31 | * 32 | * \param obj The reference counted object 33 | * \param free Function which will be called when the object should be freed 34 | */ 35 | #define REFCOUNT_INIT(obj, free) refcount_init(obj, offsetof(typeof(*obj), REFCOUNT_FIELD_NAME), free) 36 | 37 | /** 38 | * \brief Retains a reference counted object. 39 | * 40 | * \param obj Reference counted object 41 | * \return NULL if the object could not be retained otherwise \p obj 42 | */ 43 | #define REFCOUNT_RETAIN(obj) refcount_retain(obj, offsetof(typeof(*obj), REFCOUNT_FIELD_NAME)) 44 | 45 | /** 46 | * \brief Releases a reference counted object. 47 | * 48 | * \param obj Reference counted object 49 | * \return true if object was freed false otherwise 50 | */ 51 | #define REFCOUNT_RELEASE(obj) refcount_release(obj, offsetof(typeof(*obj), REFCOUNT_FIELD_NAME)) 52 | 53 | /** 54 | * \brief Structure holding reference counting information. 55 | * 56 | * This structure is not intended to be used directly in another structure or union. Use the macro #REFCOUNT_FIELD instead. 57 | */ 58 | typedef struct{ 59 | uint64_t ref_count; 60 | void (*free)(const void*); 61 | }refcount_t; 62 | 63 | /** 64 | * \brief Initializes the reference counting of an object. 65 | * 66 | * This function is not intended for direct use. Use the macro #REFCOUNT_INIT instead. 67 | * \param obj The reference counted object 68 | * \param offset Offset in the object of the reference count structure 69 | * \param free Function which will be called when the object should be freed 70 | */ 71 | void refcount_init(void *obj, size_t offset, void (*free)(const void*)); 72 | 73 | /** 74 | * \brief Retains a reference counted object. 75 | * 76 | * This function is not intended for direct use. Use the macro #REFCOUNT_RETAIN instead. 77 | * \param obj Reference counted object 78 | * \param offset Offset in the object of the reference count structure 79 | * \return NULL if the object could not be retained otherwise \p obj 80 | */ 81 | void *refcount_retain(void *obj, size_t offset); 82 | 83 | /** 84 | * \brief Releases a reference counted object. 85 | * 86 | * This function is not intended for direct use. Use the macro #REFCOUNT_RELEASE instead. 87 | * \param obj Reference counted object 88 | * \param offset Offset in the object of the reference count structure 89 | * \return true if object was freed false otherwise 90 | */ 91 | bool refcount_release(void *obj, size_t offset); 92 | 93 | #endif /* REFCOUNT_H_ */ 94 | -------------------------------------------------------------------------------- /util/ring.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ring.c 3 | * 4 | * Created on: 19.02.2015 5 | * Author: pascal 6 | */ 7 | 8 | #include "ring.h" 9 | #include "stdlib.h" 10 | #include "assert.h" 11 | 12 | struct ring_s{ 13 | ring_entry_t* base; 14 | size_t size; 15 | }; 16 | 17 | ring_t *ring_create() 18 | { 19 | ring_t *ring = calloc(1, sizeof(ring_t)); 20 | 21 | return ring; 22 | } 23 | 24 | void ring_destroy(ring_t *ring) 25 | { 26 | assert(ring != NULL); 27 | free(ring); 28 | } 29 | 30 | size_t ring_entries(ring_t *ring) 31 | { 32 | assert(ring != NULL); 33 | return ring->size; 34 | } 35 | 36 | void ring_add(ring_t *ring, ring_entry_t *entry) 37 | { 38 | assert(ring != NULL); 39 | assert(entry != NULL); 40 | 41 | if(ring->size) 42 | { 43 | entry->next = ring->base; 44 | entry->prev = ring->base->prev; 45 | ring->base->prev->next = entry; 46 | ring->base->prev = entry; 47 | } 48 | else 49 | { 50 | ring->base = entry; 51 | entry->next = entry->prev = entry; 52 | } 53 | ring->size++; 54 | } 55 | 56 | ring_entry_t *ring_getNext(ring_t* ring) 57 | { 58 | ring_entry_t* entry; 59 | 60 | assert(ring != NULL); 61 | 62 | if(ring->size == 0) 63 | return NULL; 64 | 65 | entry = ring->base; 66 | ring->base = ring->base->next; 67 | 68 | return entry; 69 | } 70 | 71 | void ring_remove(ring_t* ring, ring_entry_t *entry) 72 | { 73 | assert(ring != NULL); 74 | assert(entry != NULL); 75 | 76 | if(ring->size == 0) 77 | return; 78 | 79 | ring->size--; 80 | 81 | entry->next->prev = entry->prev; 82 | entry->prev->next = entry->next; 83 | if(ring->size == 0) 84 | ring->base = NULL; 85 | else if(ring->base == entry) 86 | ring->base = entry->next; 87 | } 88 | 89 | 90 | bool ring_contains(ring_t *ring, ring_entry_t *entry) 91 | { 92 | assert(ring != NULL); 93 | assert(entry != NULL); 94 | 95 | if(ring->size == 0) 96 | return false; 97 | 98 | ring_entry_t *e = ring->base; 99 | do 100 | { 101 | assert(e != NULL); 102 | if(e == entry) 103 | return true; 104 | e = e->next; 105 | } 106 | while(e != ring->base); 107 | 108 | return false; 109 | } 110 | -------------------------------------------------------------------------------- /util/ring.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ring.h 3 | * 4 | * Created on: 19.02.2015 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef RING_H_ 9 | #define RING_H_ 10 | 11 | #include "stddef.h" 12 | #include "stdbool.h" 13 | 14 | /** 15 | * \brief Type of a ring entry. 16 | */ 17 | typedef struct ring_entry_s{ 18 | 19 | /** 20 | * Pointer to the next entry. 21 | */ 22 | struct ring_entry_s* next; 23 | 24 | /** 25 | * Pointer to the previous entry. 26 | */ 27 | struct ring_entry_s* prev; 28 | }ring_entry_t; 29 | 30 | /** 31 | * \brief Type of a ring. 32 | */ 33 | typedef struct ring_s ring_t; 34 | 35 | /** 36 | * \brief Creates a new ring. 37 | * 38 | * Creates and initializes a new ring. If an error occurs the function returns NULL. 39 | * @return pointer to a newly created and initialized ring or NULL 40 | */ 41 | ring_t *ring_create(); 42 | 43 | /** 44 | * \brief Destroys a ring. 45 | * 46 | * @param ring Ring to be destroyed 47 | */ 48 | void ring_destroy(ring_t *ring); 49 | 50 | /** 51 | * \brief Returns the number of entries in a ring. 52 | * 53 | * Complexity: O(1) 54 | * @param ring Ring 55 | * @return number of entries in the ring 56 | */ 57 | size_t ring_entries(ring_t *ring); 58 | 59 | /** 60 | * \brief Adds an entry to a ring. 61 | * 62 | * Complexity: O(1) 63 | * @param ring Ring where the entry shall be added 64 | * @param entry Entry to be added 65 | */ 66 | void ring_add(ring_t *ring, ring_entry_t *entry); 67 | 68 | /** 69 | * \brief Removes an entry from a ring. 70 | * 71 | * Complexity: O(1) 72 | * @param ring Ring where the entry shall be removed 73 | * @param entry Entry to be removed 74 | */ 75 | void ring_remove(ring_t *ring, ring_entry_t *entry); 76 | 77 | /** 78 | * \brief Gets the next entry of a ring. 79 | * 80 | * Sets the base pointer of a ring to the next entry and returns the entry pointed to. 81 | * Complexity: O(1) 82 | * @param ring Ring to be stepped 83 | * @return next entry in the ring 84 | */ 85 | ring_entry_t *ring_getNext(ring_t *ring); 86 | 87 | /** 88 | * \brief Checks if an entry is contained a ring. 89 | * 90 | * Goes through the ring and searches for the entry. 91 | * Complexity: O(\#entries in ring) 92 | * @param ring Ring where the entry shall be searched 93 | * @param entry Entry to be checked 94 | * @return if entry is contained in ring 95 | */ 96 | bool ring_contains(ring_t *ring, ring_entry_t *entry); 97 | 98 | #endif /* RING_H_ */ 99 | -------------------------------------------------------------------------------- /util/semaphore.c: -------------------------------------------------------------------------------- 1 | /* 2 | * semaphore.c 3 | * 4 | * Created on: 04.09.2015 5 | * Author: pascal 6 | */ 7 | 8 | #include "semaphore.h" 9 | #include "thread.h" 10 | #include "scheduler.h" 11 | #include "assert.h" 12 | 13 | void semaphore_init(semaphore_t *sem, int64_t count) 14 | { 15 | assert(sem != NULL); 16 | sem->lock = LOCK_INIT; 17 | sem->count = count; 18 | sem->waiting = queue_create(); 19 | } 20 | 21 | void semaphore_destroy(semaphore_t *sem) 22 | { 23 | assert(sem != NULL); 24 | // Set garbage so that the semaphore can no longer be used 25 | static lock_node_t lock_node; 26 | lock(&sem->lock, &lock_node); 27 | queue_destroy(sem->waiting); 28 | } 29 | 30 | void semaphore_acquire(semaphore_t *sem) 31 | { 32 | assert(sem != NULL); 33 | retry: 34 | if(__sync_fetch_and_add(&sem->count, -1) <= 0) 35 | { 36 | LOCKED_TASK(sem->lock, queue_enqueue(sem->waiting, currentThread)); 37 | if(!thread_block_self((thread_bail_out_t)semaphore_release, sem, THREAD_BLOCKED_SEMAPHORE)) goto retry; 38 | } 39 | } 40 | 41 | void semaphore_release(semaphore_t *sem) 42 | { 43 | assert(sem != NULL); 44 | __sync_add_and_fetch(&sem->count, 1); 45 | if(queue_size(sem->waiting) > 0) 46 | { 47 | LOCKED_TASK(sem->lock, thread_unblock(queue_dequeue(sem->waiting))); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /util/semaphore.h: -------------------------------------------------------------------------------- 1 | /* 2 | * semaphore.h 3 | * 4 | * Created on: 04.09.2015 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef SEMAPHORE_H_ 9 | #define SEMAPHORE_H_ 10 | 11 | #include "queue.h" 12 | #include "lock.h" 13 | 14 | typedef struct{ 15 | int64_t count; 16 | queue_t *waiting; 17 | lock_t lock; 18 | }semaphore_t; 19 | 20 | void semaphore_init(semaphore_t *sem, int64_t count); 21 | void semaphore_destroy(semaphore_t *sem); 22 | void semaphore_acquire(semaphore_t *sem); 23 | void semaphore_release(semaphore_t *sem); 24 | 25 | #endif /* SEMAPHORE_H_ */ 26 | -------------------------------------------------------------------------------- /util/stack.c: -------------------------------------------------------------------------------- 1 | /* 2 | * stack.c 3 | * 4 | * Created on: 30.03.2017 5 | * Author: pascal 6 | */ 7 | 8 | #include "stack.h" 9 | #include "stdlib.h" 10 | #include "assert.h" 11 | #include "stdint.h" 12 | 13 | typedef struct stack_elem{ 14 | struct stack_elem *next; 15 | void *data; 16 | }stack_elem_t; 17 | 18 | struct stack{ 19 | union{ 20 | uint128_t full_stack; 21 | struct{ 22 | stack_elem_t *head; 23 | uintptr_t tag; 24 | }; 25 | }; 26 | }; 27 | 28 | stack_t *stack_create() 29 | { 30 | return calloc(1, sizeof(stack_t)); 31 | } 32 | 33 | void stack_destroy(stack_t *stack) 34 | { 35 | assert(stack != NULL); 36 | while (stack_pop(stack, NULL)); 37 | free(stack); 38 | } 39 | 40 | void stack_push(stack_t *stack, void *data) 41 | { 42 | assert(stack != NULL); 43 | stack_t prev, new; 44 | stack_elem_t *elem = malloc(sizeof(stack_elem_t)); 45 | elem->data = data; 46 | do 47 | { 48 | prev = *stack; 49 | elem->next = prev.head; 50 | new.head = elem; 51 | new.tag = prev.tag + 1; 52 | } 53 | while(!__sync_bool_compare_and_swap(&stack->full_stack, prev.full_stack, new.full_stack)); 54 | } 55 | 56 | bool stack_pop(stack_t *stack, void **value) 57 | { 58 | assert(stack != NULL); 59 | stack_t prev, new; 60 | 61 | do 62 | { 63 | prev = *stack; 64 | if(prev.head == NULL) 65 | return false; 66 | new.tag = prev.tag; 67 | new.head = prev.head->next; 68 | } 69 | while(!__sync_bool_compare_and_swap(&stack->full_stack, prev.full_stack, new.full_stack)); 70 | 71 | if(value != NULL) 72 | *value = prev.head->data; 73 | free(prev.head); 74 | return true; 75 | } 76 | -------------------------------------------------------------------------------- /util/stack.h: -------------------------------------------------------------------------------- 1 | /* 2 | * stack.h 3 | * 4 | * Created on: 30.03.2017 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef STACK_H_ 9 | #define STACK_H_ 10 | 11 | #include "stdbool.h" 12 | 13 | typedef struct stack stack_t; 14 | 15 | stack_t *stack_create(); 16 | void stack_destroy(stack_t *stack); 17 | void stack_push(stack_t *stack, void *data); 18 | bool stack_pop(stack_t *stack, void **value); 19 | 20 | #endif /* STACK_H_ */ 21 | -------------------------------------------------------------------------------- /util/system.c: -------------------------------------------------------------------------------- 1 | /* 2 | * system.c 3 | * 4 | * Created on: 11.08.2012 5 | * Author: pascal 6 | */ 7 | 8 | #include "system.h" 9 | #include "pmm.h" 10 | #include "console.h" 11 | #include "stdio.h" 12 | #include "debug.h" 13 | #include "lock.h" 14 | #include "scheduler.h" 15 | 16 | extern uint64_t Uptime; 17 | 18 | char system_panic_buffer[25 * 80]; 19 | static lock_t panic_buffer_lock = LOCK_INIT; 20 | 21 | /* 22 | * Speichert Systeminformationen in die übergebene Struktur 23 | * Parameter: Adresse auf die Systeminformationen-Struktur 24 | */ 25 | void getSystemInformation(SIS *Struktur) 26 | { 27 | Struktur->physSpeicher = pmm_getTotalPages() * 4096; 28 | Struktur->physFree = pmm_getFreePages() * 4096; 29 | Struktur->Uptime = Uptime; 30 | } 31 | 32 | void system_panic_enter() 33 | { 34 | // Der lock wird nie mehr freigegeben, deshalb können wir das hier so machen 35 | static lock_node_t lock_node; 36 | if(!try_lock(&panic_buffer_lock, &lock_node)) 37 | { 38 | CPU_STOP(); 39 | } 40 | } 41 | 42 | void system_panic() 43 | { 44 | console_switch(0); 45 | printf("\e[37;41mSystem panic\t\t"); 46 | if(currentThread != NULL) 47 | printf("process: %lu(%.20s), tid: %lu", currentProcess->PID, currentProcess->cmd, currentThread->tid); 48 | printf("\n\nThe following error occurred:\n%s", system_panic_buffer); 49 | CPU_STOP(); 50 | } 51 | -------------------------------------------------------------------------------- /util/system.h: -------------------------------------------------------------------------------- 1 | /* 2 | * system.h 3 | * 4 | * Created on: 11.08.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef SYSTEM_H_ 9 | #define SYSTEM_H_ 10 | 11 | #include 12 | 13 | extern char system_panic_buffer[25 * 80]; 14 | 15 | void getSystemInformation(SIS *Struktur); 16 | void system_panic_enter(); 17 | void system_panic() __attribute__((noreturn)); 18 | 19 | #endif /* SYSTEM_H_ */ 20 | -------------------------------------------------------------------------------- /util/util.c: -------------------------------------------------------------------------------- 1 | /* 2 | * util.c 3 | * 4 | * Created on: 14.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #include "util.h" 9 | #include "pit.h" 10 | 11 | void outb(uint16_t Port, uint8_t Data) 12 | { 13 | asm volatile("outb %0,%1" : :"a" (Data), "d" (Port)); 14 | } 15 | 16 | uint8_t inb(uint16_t Port) 17 | { 18 | uint8_t Data; 19 | asm volatile("inb %1,%0" :"=a"(Data) :"Nd" (Port)); 20 | return Data; 21 | } 22 | 23 | void outw(uint16_t Port, uint16_t Data) 24 | { 25 | asm volatile("outw %0,%1" : :"a" (Data), "d" (Port)); 26 | } 27 | 28 | uint16_t inw(uint16_t Port) 29 | { 30 | uint16_t Data; 31 | asm volatile("inw %1,%0" :"=a"(Data) :"Nd" (Port)); 32 | return Data; 33 | } 34 | 35 | void outd(uint16_t Port, uint32_t Data) 36 | { 37 | asm volatile("out %0,%1" : :"a" (Data), "d" (Port)); 38 | } 39 | 40 | uint32_t ind(uint16_t Port) 41 | { 42 | uint32_t Data; 43 | asm volatile("in %1,%0" :"=a"(Data) :"Nd" (Port)); 44 | return Data; 45 | } 46 | 47 | void outq(uint16_t Port, uint64_t Data) 48 | { 49 | //asm volatile("outl %0,%1" : :"a" (Data), "d" (Port)); 50 | } 51 | 52 | uint64_t inq(uint16_t Port) 53 | { 54 | uint64_t Data; 55 | //asm volatile("inl %1,%0" :"=a"(Data) :"Nd" (Port)); 56 | return Data; 57 | } 58 | 59 | void Sleep(uint64_t msec) 60 | { 61 | uint64_t start = Uptime; 62 | while(1) 63 | { 64 | if(start + msec <= Uptime) 65 | break; 66 | asm volatile("hlt"); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /util/util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * util.h 3 | * 4 | * Created on: 14.07.2012 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef UTIL_H_ 9 | #define UTIL_H_ 10 | 11 | #include "stdint.h" 12 | 13 | void outb(uint16_t Port, uint8_t Data); 14 | uint8_t inb(uint16_t Port); 15 | 16 | void outw(uint16_t Port, uint16_t Data); 17 | uint16_t inw(uint16_t Port); 18 | 19 | void outd(uint16_t Port, uint32_t Data); 20 | uint32_t ind(uint16_t Port); 21 | 22 | void outq(uint16_t Port, uint64_t Data); 23 | uint64_t inq(uint16_t Port); 24 | 25 | void Sleep(uint64_t msec); 26 | 27 | #endif /* UTIL_H_ */ 28 | -------------------------------------------------------------------------------- /version.c: -------------------------------------------------------------------------------- 1 | /* 2 | * version.c 3 | * 4 | * Created on: 31.10.2017 5 | * Author: pascal 6 | */ 7 | 8 | #include "version.h" 9 | 10 | #define VERSION_MAJOR 0 11 | #define VERSION_MINOR 0 12 | #define VERSION_BUGFIX 0 13 | 14 | #define _STR(x) #x 15 | #define STR(x) _STR(x) 16 | 17 | #if (defined(__GNUC__) || defined(__GNUG__)) && !(defined(__clang__) || defined(__INTEL_COMPILER)) 18 | #define COMPILER "gcc " __VERSION__ 19 | #elif (defined(__clang__)) 20 | #define COMPILER "clang " __clang_version__ 21 | #else 22 | #define COMPILER "unknown" 23 | #endif 24 | 25 | #ifndef GIT_BRANCH 26 | #define GIT_BRANCH unknown 27 | #endif 28 | 29 | #ifndef GIT_COMMIT_ID 30 | #define GIT_COMMIT_ID unknown 31 | #endif 32 | 33 | const unsigned version_major = VERSION_MAJOR; 34 | const unsigned version_minor = VERSION_MINOR; 35 | const unsigned version_bugfix = VERSION_BUGFIX; 36 | 37 | const char *version_branch = STR(GIT_BRANCH); 38 | const char *version_commitId = STR(GIT_COMMIT_ID); 39 | 40 | const char *version_buildDate = __DATE__; 41 | const char *version_buildTime = __TIME__; 42 | 43 | const char *version_compiler = COMPILER; 44 | -------------------------------------------------------------------------------- /version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * version.h 3 | * 4 | * Created on: 01.02.2017 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef VERSION_H_ 9 | #define VERSION_H_ 10 | 11 | extern const unsigned version_major; 12 | extern const unsigned version_minor; 13 | extern const unsigned version_bugfix; 14 | 15 | extern const char *version_branch; 16 | extern const char *version_commitId; 17 | 18 | extern const char *version_buildDate; 19 | extern const char *version_buildTime; 20 | 21 | extern const char *version_compiler; 22 | 23 | #endif /* VERSION_H_ */ 24 | -------------------------------------------------------------------------------- /vfs/cdifs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * cdifs.h 3 | * 4 | * Created on: 07.01.2018 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef CDIFS_H_ 9 | #define CDIFS_H_ 10 | 11 | #include 12 | 13 | int cdifs_registerFilesystemDriver(struct cdi_fs_driver *driver); 14 | 15 | #endif /* CDIFS_H_ */ 16 | -------------------------------------------------------------------------------- /vfs/devfs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * devfs.c 3 | * 4 | * Created on: 07.01.2018 5 | * Author: pascal 6 | */ 7 | 8 | #include "devfs.h" 9 | #include "partition.h" 10 | #include "lists.h" 11 | #include "storage.h" 12 | #include "scsi.h" 13 | #include "stdlib.h" 14 | #include "string.h" 15 | #include "assert.h" 16 | 17 | #define GET_BYTE(value, offset) (value >> offset) & 0xFF 18 | #define MIN(val1, val2) ((val1 < val2) ? val1 : val2) 19 | 20 | static list_t nodes; 21 | static vfs_filesystem_driver_t devfs_driver; 22 | static vfs_node_dir_t root; 23 | 24 | static int probe(vfs_filesystem_t *fs __attribute__((unused)), vfs_stream_t *dev) 25 | { 26 | return dev == NULL ? 0 : 1; 27 | } 28 | 29 | static int mount(vfs_filesystem_t *fs, vfs_stream_t *dev __attribute__((unused))) 30 | { 31 | fs->root = &root; 32 | return 0; 33 | } 34 | 35 | static int umount(vfs_filesystem_t *fs __attribute__((unused))) 36 | { 37 | return 0; 38 | } 39 | 40 | static vfs_node_dir_t *get_root() 41 | { 42 | return &root; 43 | } 44 | 45 | static int root_visitChilds(vfs_node_dir_t *node __attribute__((unused)), uint64_t start, vfs_node_dir_callback_t callback, void *context) 46 | { 47 | vfs_node_dev_t *child; 48 | while((child = list_get(nodes, start++)) != NULL && callback(&child->base, context)); 49 | return 0; 50 | } 51 | 52 | static vfs_node_t *root_findChild(vfs_node_dir_t *node __attribute__((unused)), const char *name) 53 | { 54 | vfs_node_dev_t *child; 55 | size_t i = 0; 56 | while((child = list_get(nodes, i++)) != NULL) 57 | { 58 | if(strcmp(child->base.name, name) == 0) 59 | return &child->base; 60 | } 61 | 62 | return NULL; 63 | } 64 | 65 | void devfs_init() 66 | { 67 | //Initialisiere Geräteliste 68 | nodes = list_create(); 69 | 70 | vfs_node_dir_init(&root, "/"); 71 | vfs_registerFilesystemDriver(&devfs_driver); 72 | } 73 | 74 | int devfs_registerDeviceNode(vfs_node_dev_t *node) 75 | { 76 | node->base.parent = &root; 77 | return list_push(nodes, node) == NULL ? 1 : 0; 78 | } 79 | 80 | static vfs_filesystem_driver_t devfs_driver = { 81 | .name = "devfs", 82 | .info = VFS_FILESYSTEM_INFO_VIRTUAL | VFS_FILESYSTEM_INFO_MODULE, 83 | 84 | .probe = probe, 85 | .mount = mount, 86 | .umount = umount, 87 | .get_root = get_root 88 | }; 89 | 90 | static vfs_node_dir_t root = { 91 | .visitChilds = root_visitChilds, 92 | .findChild = root_findChild 93 | }; 94 | -------------------------------------------------------------------------------- /vfs/devfs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * devfs.h 3 | * 4 | * Created on: 07.01.2018 5 | * Author: pascal 6 | */ 7 | 8 | #ifndef DEVFS_H_ 9 | #define DEVFS_H_ 10 | 11 | #include "node.h" 12 | 13 | void devfs_init(); 14 | int devfs_registerDeviceNode(vfs_node_dev_t *node); 15 | 16 | #endif /* DEVFS_H_ */ 17 | -------------------------------------------------------------------------------- /vfs/node.c: -------------------------------------------------------------------------------- 1 | /* 2 | * node.c 3 | * 4 | * Created on: 15.10.2017 5 | * Author: pascal 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | static uint64_t mode_hash(const void *key, __attribute__((unused)) void *context) 15 | { 16 | const vfs_mode_t *mode = key; 17 | return (uint64_t)*mode; 18 | } 19 | 20 | static bool mode_equal(const void *a, const void *b, __attribute__((unused)) void *context) 21 | { 22 | const vfs_mode_t *modea = a; 23 | const vfs_mode_t *modeb = b; 24 | return *modea == *modeb; 25 | } 26 | 27 | /* 28 | * Erstelle eine simple Node. Setzt nicht den Typ der Node und nicht die abhängigen Daten. 29 | * Parameter: parent = Node zu welcher die neue Node hinzugefügt werden soll 30 | * name = Name der Node 31 | * Rückgabe: Pointer zur neuen Node 32 | */ 33 | int vfs_node_init(vfs_node_t *node, const char *name) 34 | { 35 | node->name = strdup(name); 36 | node->lock = LOCK_INIT; 37 | node->parent = NULL; 38 | node->streams = hashmap_create(mode_hash, mode_hash, mode_equal, NULL, NULL, NULL, NULL, 0); 39 | if(node->streams == NULL) 40 | { 41 | free((char*)node->name); 42 | return 1; 43 | } 44 | 45 | return 0; 46 | } 47 | 48 | /* 49 | * Löscht eine Node. Löscht keine Kinder. 50 | * Parameter: node = Node die gelöscht werden soll 51 | */ 52 | void vfs_node_deinit(vfs_node_t *node) 53 | { 54 | assert(node != NULL); 55 | 56 | lock_node_t lock_node; 57 | lock(&node->lock, &lock_node); 58 | free((char*)node->name); 59 | hashmap_destroy(node->streams); 60 | free(node); 61 | } 62 | 63 | int vfs_node_dir_init(vfs_node_dir_t *node, const char *name) 64 | { 65 | int res = vfs_node_init(&node->base, name); 66 | if(res) 67 | return res; 68 | node->base.type = VFS_NODE_DIR; 69 | 70 | node->mounts = list_create(); 71 | if(node->mounts == NULL) 72 | { 73 | vfs_node_deinit(&node->base); 74 | return 1; 75 | } 76 | 77 | return 0; 78 | } 79 | 80 | static void unmount_fs(void *fs) { 81 | REFCOUNT_RELEASE((vfs_filesystem_t*)fs); 82 | } 83 | 84 | void vfs_node_dir_deinit(vfs_node_dir_t *node) 85 | { 86 | list_destroy(node->mounts, unmount_fs); 87 | vfs_node_deinit(&node->base); 88 | } 89 | 90 | int vfs_node_file_init(vfs_node_file_t *node, const char *name) 91 | { 92 | int res = vfs_node_init(&node->base, name); 93 | if(res) 94 | return res; 95 | node->base.type = VFS_NODE_FILE; 96 | 97 | return 0; 98 | } 99 | 100 | void vfs_node_file_deinit(vfs_node_file_t *node) 101 | { 102 | vfs_node_deinit(&node->base); 103 | } 104 | 105 | int vfs_node_link_init(vfs_node_link_t *node, const char *name) 106 | { 107 | int res = vfs_node_init(&node->base, name); 108 | if(res) 109 | return res; 110 | node->base.type = VFS_NODE_LINK; 111 | 112 | return 0; 113 | } 114 | 115 | void vfs_node_link_deinit(vfs_node_link_t *node) 116 | { 117 | vfs_node_deinit(&node->base); 118 | } 119 | 120 | int vfs_node_dev_init(vfs_node_dev_t *node, const char *name) 121 | { 122 | int res = vfs_node_init(&node->base, name); 123 | if(res) 124 | return res; 125 | node->base.type = VFS_NODE_DEV; 126 | 127 | return 0; 128 | } 129 | 130 | void vfs_node_dev_deinit(vfs_node_dev_t *node) 131 | { 132 | vfs_node_deinit(&node->base); 133 | } 134 | --------------------------------------------------------------------------------