fixes for A2
mostly include some things that should and remove some things that shouldn't have been included in the handout (yes this does hint at some places that need to be touched for A2)
This commit is contained in:
22
.clang-tidy
22
.clang-tidy
@@ -1,6 +1,26 @@
|
||||
FormatStyle: google
|
||||
HeaderFilterRegex: '.*'
|
||||
WarningsAsErrors: 'readability*'
|
||||
Checks: 'readability*,google-readability-casting,google-explicit-constructor,bugprone*,-bugprone-narrowing-conversions,-bugprone-reserved-identifier,-readability-else-after-return,-readability-magic-numbers,-readability-identifier-length,-readability-braces-around-statements,cppcoreguidelines-*,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-avoid-c-arrays,-cppcoreguidelines-pro-*,-cppcoreguidelines-avoid-do-while,-cppcoreguidelines-owning-memory'
|
||||
Checks: >
|
||||
google-readability-casting,
|
||||
google-explicit-constructor,
|
||||
readability*,
|
||||
-readability-braces-around-statements,
|
||||
-readability-else-after-return,
|
||||
-readability-function-cognitive-complexity
|
||||
-readability-identifier-length,
|
||||
-readability-magic-numbers,
|
||||
bugprone*,
|
||||
-bugprone-easily-swappable-parameters,
|
||||
-bugprone-narrowing-conversions,
|
||||
-bugprone-reserved-identifier,
|
||||
cppcoreguidelines-*,
|
||||
-cppcoreguidelines-avoid-c-arrays,
|
||||
-cppcoreguidelines-avoid-do-while,
|
||||
-cppcoreguidelines-avoid-magic-numbers,
|
||||
-cppcoreguidelines-avoid-non-const-global-variables,
|
||||
-cppcoreguidelines-owning-memory,
|
||||
-cppcoreguidelines-pro-*,
|
||||
CheckOptions:
|
||||
readability-simplify-boolean-expr.IgnoreMacros: 'true'
|
||||
readability-identifier-length.IgnoreNames: 'me'
|
||||
|
||||
3
LICENSE
3
LICENSE
@@ -8,7 +8,6 @@ Diese Vorlage dient als Grundlage für Lehrveranstaltungen und darf nicht ohne v
|
||||
Es ist erlaubt und wünschenswert, diese Vorlage als Inspiration für eigene Projekte zu verwenden, es wird allerdings erbeten, dass die Vorgabe nicht mit deiner Lösung veröffentlicht wird.
|
||||
Wir, als Lehrende, möchten alle teilnehmenden Studierenden dazu ermutigen eine eigene Lösung zu erstellen; eine veröffentlichte Lösung ist ein Anreiz zum Abschreiben, den wir gerne vermeiden möchten.
|
||||
|
||||
|
||||
This skeleton is provided as a foundation for educational purposes and therefore MUST NOT BE DISTRIBUTED OR PUBLISHED without prior, written consent of the copyright holders.
|
||||
You are free to use this skeleton as inspiration for your projects, but, please, do not publish it along with your solution.
|
||||
We, as lecturers, want to encourage every participating student to write a solution themself; a public solution is an allurement to copying we want to avoid.
|
||||
We, as lecturers, want to encourage every participating student to write a solution on their own; a public solution is an allurement to copying we want to avoid.
|
||||
|
||||
3175
kernel/assets/osg.h
3175
kernel/assets/osg.h
File diff suppressed because it is too large
Load Diff
@@ -96,13 +96,11 @@ Module *getModule(unsigned i) {
|
||||
|
||||
unsigned getModuleCount() { return multiboot_addr->mods.size; }
|
||||
|
||||
void *Memory::getStartAddress() const {
|
||||
return reinterpret_cast<void *>(static_cast<uintptr_t>(addr));
|
||||
}
|
||||
void *Memory::getStartAddress() const { return reinterpret_cast<void *>(addr); }
|
||||
|
||||
void *Memory::getEndAddress() const {
|
||||
uint64_t end = addr + len;
|
||||
return reinterpret_cast<void *>(static_cast<uintptr_t>(end));
|
||||
return reinterpret_cast<void *>(end);
|
||||
}
|
||||
|
||||
bool Memory::isAvailable() const { return type == AVAILABLE; }
|
||||
|
||||
@@ -21,7 +21,6 @@ OutputStream* copyout = ©stream;
|
||||
#include "./device/ps2controller.h"
|
||||
#include "./interrupt/guard.h"
|
||||
#include "./sync/semaphore.h"
|
||||
#include "./thread/thread.h"
|
||||
Semaphore koutsem(1);
|
||||
TextStream kout(0, 80, 1, 17, true);
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ assert_size(ErrorCode, 4);
|
||||
uint64_t err) {
|
||||
PageFault::ErrorCode error(err);
|
||||
// Get the faulting address
|
||||
uintptr_t virt;
|
||||
uintptr_t virt = 0;
|
||||
asm volatile("mov %%cr2, %0" : "=r"(virt));
|
||||
DBG << "Page fault at " << hex << virt << dec << endl;
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#include "syscall/handler.h"
|
||||
|
||||
#include "arch/core.h"
|
||||
#include "arch/core_interrupt.h"
|
||||
#include "arch/gdt.h"
|
||||
#include "arch/idt.h"
|
||||
#include "debug/kernelpanic.h"
|
||||
#include "debug/output.h"
|
||||
@@ -26,12 +24,12 @@ namespace Syscall {
|
||||
* by the system call number -- allowing up to five parameters for the system
|
||||
* call.
|
||||
*
|
||||
* \param sysnum identifier for the system call
|
||||
* \param p1 first parameter
|
||||
* \param p2 second parameter
|
||||
* \param p3 third parameter
|
||||
* \param p4 fourth parameter
|
||||
* \param p5 fifth parameter
|
||||
* \param sysnum identifier for the system call
|
||||
* \param user pointer to the interrupt \ref context (for example to determine
|
||||
* instruction pointer)
|
||||
* \return system call return value
|
||||
|
||||
@@ -32,15 +32,13 @@ void Scheduler::resume(bool ready) {
|
||||
Thread *me = dispatcher.active();
|
||||
assert(me != nullptr && "Pointer to active thread should never be nullptr");
|
||||
|
||||
if (true) {
|
||||
// Be careful, never put the idle thread into the ready list
|
||||
bool is_idle_thread = static_cast<Thread *>(&idleThread) == me;
|
||||
// Be careful, never put the idle thread into the ready list
|
||||
bool is_idle_thread = static_cast<Thread *>(&idleThread) == me;
|
||||
|
||||
if (ready && readylist.is_empty()) {
|
||||
return;
|
||||
} else if (!is_idle_thread) {
|
||||
if (ready) readylist.enqueue(*me);
|
||||
}
|
||||
if (ready && readylist.is_empty()) {
|
||||
return;
|
||||
} else if (!is_idle_thread) {
|
||||
if (ready) readylist.enqueue(*me);
|
||||
}
|
||||
|
||||
dispatcher.dispatch(getNext());
|
||||
@@ -56,6 +54,8 @@ void Scheduler::kill(Thread *that) {
|
||||
if (dispatcher.active() == that) {
|
||||
exit();
|
||||
}
|
||||
|
||||
readylist.remove(that);
|
||||
}
|
||||
|
||||
bool Scheduler::isEmpty() const { return readylist.is_empty(); }
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
#include "device/textstream.h"
|
||||
@@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "outputstream.h"
|
||||
#include "stub.h"
|
||||
|
||||
class IOStream : public OutputStream {
|
||||
private:
|
||||
IOStream(IOStream ©); // no copy
|
||||
int fd;
|
||||
|
||||
public:
|
||||
explicit IOStream(int sysfd = 0) : fd(sysfd) {}
|
||||
|
||||
~IOStream() {
|
||||
if (pos > 0) {
|
||||
sys_write(fd, buffer, pos);
|
||||
}
|
||||
}
|
||||
|
||||
void flush() override {
|
||||
sys_write(fd, buffer, pos);
|
||||
pos = 0;
|
||||
}
|
||||
};
|
||||
@@ -1,68 +0,0 @@
|
||||
#include "rand.h"
|
||||
|
||||
// Mersenne Twister (32 bit pseudorandom number generator)
|
||||
// https://en.wikipedia.org/wiki/Mersenne_Twister
|
||||
|
||||
static const uint32_t N = 624;
|
||||
static const uint32_t M = 397;
|
||||
static const uint32_t R = 31;
|
||||
static const uint32_t A = 0x9908B0DF;
|
||||
|
||||
// initialization multiplier
|
||||
static const uint32_t F = 1812433253;
|
||||
|
||||
static const uint32_t U = 11;
|
||||
|
||||
static const uint32_t S = 7;
|
||||
static const uint32_t B = 0x9D2C5680;
|
||||
|
||||
static const uint32_t T = 15;
|
||||
static const uint32_t C = 0xEFC60000;
|
||||
|
||||
static const uint32_t L = 18;
|
||||
|
||||
static const uint32_t MASK_LOWER = (1ULL << R) - 1;
|
||||
static const uint32_t MASK_UPPER = (1ULL << R);
|
||||
|
||||
static uint32_t mt[N];
|
||||
static uint16_t index;
|
||||
|
||||
void srand(const uint32_t seed) {
|
||||
mt[0] = seed;
|
||||
|
||||
for (uint32_t i = 1; i < N; i++) {
|
||||
mt[i] = (F * (mt[i - 1] ^ (mt[i - 1] >> 30)) + i);
|
||||
}
|
||||
|
||||
index = N;
|
||||
}
|
||||
|
||||
uint32_t rand() {
|
||||
uint16_t v = index;
|
||||
|
||||
if (index >= N) {
|
||||
// Twist
|
||||
for (uint32_t i = 0; i < N; i++) {
|
||||
uint32_t x = (mt[i] & MASK_UPPER) + (mt[(i + 1) % N] & MASK_LOWER);
|
||||
|
||||
uint32_t xA = x >> 1;
|
||||
|
||||
if ((x & 0x1) != 0) {
|
||||
xA ^= A;
|
||||
}
|
||||
|
||||
mt[i] = mt[(i + M) % N] ^ xA;
|
||||
}
|
||||
v = index = 0;
|
||||
}
|
||||
|
||||
uint32_t y = mt[v];
|
||||
index = v + 1;
|
||||
|
||||
y ^= (y >> U);
|
||||
y ^= (y << S) & B;
|
||||
y ^= (y << T) & C;
|
||||
y ^= (y >> L);
|
||||
|
||||
return y;
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
|
||||
const uint32_t RAND_MAX = UINT32_MAX;
|
||||
|
||||
void srand(uint32_t seed);
|
||||
|
||||
uint32_t rand();
|
||||
0
nix-develop.sh
Normal file → Executable file
0
nix-develop.sh
Normal file → Executable file
@@ -99,7 +99,7 @@ $(BUILDDIR)/%.asm.o : %.asm $(MAKEFILE_LIST)
|
||||
# The standard target 'clean' removes the whole generated system, the object files, and the dependency files.
|
||||
clean::
|
||||
rm -rf "$(BUILDDIR)"
|
||||
|
||||
rm -rf doc
|
||||
|
||||
# Target issuing a nested call to make generating a fully optimized systems without assertions.
|
||||
%-$(OPTTAG):
|
||||
@@ -120,6 +120,9 @@ clean::
|
||||
%-$(VERBOSETAG):
|
||||
$(VERBOSE) $(MAKE) BUILDDIR="$(BUILDDIR)/$(VERBOSETAG)" ISODIR="$(ISODIR)/$(VERBOSETAG)" CXXFLAGS_OPT="-DVERBOSE" $*
|
||||
|
||||
# Build the doxygen docs
|
||||
doc:
|
||||
PROJECT_NAME=StuBS doxygen ../doxygen/doxy-sra.cfg
|
||||
|
||||
# Documentation
|
||||
help::
|
||||
@@ -134,7 +137,8 @@ help::
|
||||
"To get a verbose make output, clear VERBOSE, e.g. \e[3mmake VERBOSE=\e[0m.\n" \
|
||||
"The following targets are available (each target can be suffixed by \e[3m-noopt\e[0m\n" \
|
||||
"and \e[3m-verbose\e[0m):\n\n" \
|
||||
" \e[3mall\e[0m Builds $(PROJECT), generating an ELF binary\n\n"
|
||||
" \e[3mall\e[0m Builds $(PROJECT), generating an ELF binary\n\n" \
|
||||
" \e[3mdoc\e[0m Builds the documention (doc/html/index.html)\n" \
|
||||
|
||||
|
||||
# Print warnings, if appropriate
|
||||
@@ -150,4 +154,4 @@ endif
|
||||
|
||||
|
||||
# Phony targets
|
||||
.PHONY: clean help
|
||||
.PHONY: clean doc help
|
||||
|
||||
0
tools/cpplint.py
vendored
Normal file → Executable file
0
tools/cpplint.py
vendored
Normal file → Executable file
69
user/imgbuilder.cc
Normal file
69
user/imgbuilder.cc
Normal file
@@ -0,0 +1,69 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <format>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <print>
|
||||
#include <vector>
|
||||
|
||||
constexpr size_t block_size = 4096;
|
||||
const uint8_t zeros[block_size] = {};
|
||||
|
||||
template <class... Args>
|
||||
static void die(std::format_string<Args...> fmt, Args &&...args) {
|
||||
auto msg = std::format(fmt, std::forward<Args>(args)...);
|
||||
perror(msg.c_str());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static void writeBuffer(const void *data, size_t size) {
|
||||
std::cout.write(reinterpret_cast<const char *>(data), size);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc < 2) {
|
||||
std::println(stderr, "usage: {} <list of flat binaries>\n", argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
} else if (argc > 1000) {
|
||||
std::println(stderr, "Only a maximum of 1000 apps are supported\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// HEADER: Number of apps + size of each app
|
||||
std::array<uint32_t, block_size / sizeof(uint32_t)> size{0};
|
||||
size[0] = static_cast<uint32_t>(argc - 1);
|
||||
|
||||
for (size_t i = 1; i < argc; ++i) {
|
||||
struct stat sb;
|
||||
if (stat(argv[i], &sb) != 0) die("stat");
|
||||
// 4 GB Limit
|
||||
if (sb.st_size >= UINT32_MAX) {
|
||||
errno = EFBIG;
|
||||
die("stat");
|
||||
}
|
||||
size[i] = sb.st_size;
|
||||
}
|
||||
writeBuffer(size.data(), block_size);
|
||||
|
||||
// DATA: Each App
|
||||
for (size_t i = 1; i < argc; ++i) {
|
||||
std::vector<char> buf(size[i]);
|
||||
std::ifstream input(argv[i], std::ios::binary);
|
||||
if (!input) die("fopen");
|
||||
|
||||
input.read(buf.data(), size[i]);
|
||||
|
||||
writeBuffer(buf.data(), size[i]);
|
||||
|
||||
// Fill to block size, if required
|
||||
if (size[i] % block_size != 0)
|
||||
writeBuffer(zeros, block_size - (size[i] % block_size));
|
||||
}
|
||||
|
||||
std::cout.flush();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
73
user/init.cc
Normal file
73
user/init.cc
Normal file
@@ -0,0 +1,73 @@
|
||||
#include <../libsys/stub.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void _init();
|
||||
extern void _fini();
|
||||
extern void main();
|
||||
|
||||
extern void (*__preinit_array_start[])();
|
||||
extern void (*__preinit_array_end[])();
|
||||
extern void (*__init_array_start[])();
|
||||
extern void (*__init_array_end[])();
|
||||
extern void (*__fini_array_start[])();
|
||||
extern void (*__fini_array_end[])();
|
||||
[[gnu::used]] [[noreturn]] void start() {
|
||||
const unsigned int preinit_size =
|
||||
__preinit_array_end - __preinit_array_start;
|
||||
for (unsigned int i = 0; i != preinit_size; ++i)
|
||||
(*__preinit_array_start[i])();
|
||||
|
||||
const unsigned int init_size = __init_array_end - __init_array_start;
|
||||
for (unsigned int i = 0; i != init_size; ++i) (*__init_array_start[i])();
|
||||
|
||||
main();
|
||||
|
||||
const unsigned int fini_size = __fini_array_end - __fini_array_start;
|
||||
for (unsigned int i = 0; i != fini_size; ++i) (*__fini_array_start[i])();
|
||||
|
||||
sys_exit();
|
||||
|
||||
while (true) {
|
||||
}
|
||||
}
|
||||
|
||||
// additional C++ stuff
|
||||
void __cxa_pure_virtual() {
|
||||
// pure virtual error
|
||||
}
|
||||
|
||||
// For libraries
|
||||
int __cxa_atexit(void (*func)(void *), void *arg, void *dso_handle) {
|
||||
(void)func;
|
||||
(void)arg;
|
||||
(void)dso_handle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
void *operator new([[maybe_unused]] __SIZE_TYPE__ n) {
|
||||
return reinterpret_cast<void *>(0xdeadbeef);
|
||||
}
|
||||
|
||||
void *operator new[]([[maybe_unused]] __SIZE_TYPE__ n) {
|
||||
return reinterpret_cast<void *>(0xdeadbeef);
|
||||
}
|
||||
|
||||
void operator delete[](void *ptr) { operator delete(ptr); }
|
||||
|
||||
void operator delete[](void *ptr, [[maybe_unused]] __SIZE_TYPE__ size) {
|
||||
operator delete(ptr);
|
||||
}
|
||||
|
||||
void operator delete([[maybe_unused]] void *ptr) {}
|
||||
|
||||
void operator delete(void *ptr, [[maybe_unused]] __SIZE_TYPE__ size) {
|
||||
operator delete(ptr);
|
||||
}
|
||||
@@ -38,6 +38,7 @@
|
||||
with pkgs;
|
||||
[
|
||||
# for all tasks and maintenance
|
||||
gnumake
|
||||
gdb
|
||||
qemu_kvm
|
||||
nasm
|
||||
@@ -49,6 +50,8 @@
|
||||
python3
|
||||
bear # make compile_commands.json
|
||||
clang-tools # for clangd and clang-format
|
||||
doxygen
|
||||
graphviz # make doc
|
||||
]
|
||||
++ (lib.filter (
|
||||
pkg: lib.isDerivation pkg && pkg.pname or "" != "glibc"
|
||||
|
||||
Reference in New Issue
Block a user