├── .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 |
--------------------------------------------------------------------------------