Skip to content

Commit

Permalink
Merge branch 'lab8' into 310551038
Browse files Browse the repository at this point in the history
  • Loading branch information
abt8601 committed Jun 29, 2023
2 parents 049852c + 8b0fd4e commit 4f696ab
Show file tree
Hide file tree
Showing 633 changed files with 43,052 additions and 0 deletions.
1 change: 1 addition & 0 deletions lab5/c/.clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
BasedOnStyle: LLVM
1 change: 1 addition & 0 deletions lab5/c/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
102 changes: 102 additions & 0 deletions lab5/c/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
DEFAULT_PROFILE = DEBUG
SRC_DIR = src
BUILD_DIR = build

AS = aarch64-linux-gnu-as
CC = aarch64-linux-gnu-gcc
CPP = aarch64-linux-gnu-cpp
OBJCOPY = aarch64-linux-gnu-objcopy

CPPFLAGS_BASE = -Iinclude

ASFLAGS_DEBUG = -g

CFLAGS_BASE = -std=c17 -pedantic-errors -Wall -Wextra -ffreestanding \
-mcpu=cortex-a53+nofp+nosimd -mstrict-align
CFLAGS_DEBUG = -g
CFLAGS_RELEASE = -O3 -flto

LDFLAGS_BASE = -nostdlib -Xlinker --build-id=none
LDFLAGS_RELEASE = -flto -Xlinker --gc-sections

LDLIBS_BASE = -lgcc

OBJS = start main console devicetree initrd panic shell \
drivers/aux drivers/gpio drivers/l1ic drivers/l2ic drivers/mailbox \
drivers/mini-uart drivers/pm \
mem/malloc mem/page-alloc mem/startup-alloc mem/types mem/vm \
sched/idle-thread sched/periodic-sched sched/run-signal-handler \
sched/sched sched/schedule sched/sig-handler-main \
sched/thread-main sched/user-program-main \
timer/delay timer/timeout \
xcpt/default-handler xcpt/irq-handler xcpt/svc-handler \
xcpt/syscall-table xcpt/task-queue xcpt/vector-table xcpt/xcpt \
xcpt/syscall/enosys xcpt/syscall/getpid xcpt/syscall/uart-read \
xcpt/syscall/uart-write xcpt/syscall/exec xcpt/syscall/fork \
xcpt/syscall/fork-impl xcpt/syscall/fork-child-ret \
xcpt/syscall/exit xcpt/syscall/mbox-call xcpt/syscall/kill \
xcpt/syscall/signal xcpt/syscall/signal-kill \
xcpt/syscall/sigreturn xcpt/syscall/sigreturn-check \
libc/ctype libc/stdio libc/stdlib/qsort libc/string \
utils/core-id utils/fmt utils/heapq utils/rb
LD_SCRIPT = $(SRC_DIR)/linker.ld

# ------------------------------------------------------------------------------

PROFILE = $(DEFAULT_PROFILE)
OUT_DIR = $(BUILD_DIR)/$(PROFILE)

CPPFLAGS = $(CPPFLAGS_BASE) $(CPPFLAGS_$(PROFILE))
ASFLAGS = $(ASFLAGS_BASE) $(ASFLAGS_$(PROFILE))
CFLAGS = $(CFLAGS_BASE) $(CFLAGS_$(PROFILE))
LDFLAGS = $(LDFLAGS_BASE) $(LDFLAGS_$(PROFILE))
LDLIBS = $(LDLIBS_BASE) $(LDLIBS_$(PROFILE))

OBJ_PATHS = $(addprefix $(OUT_DIR)/,$(addsuffix .o,$(OBJS)))

# ------------------------------------------------------------------------------

.PHONY: all qemu qemu-debug gdb clean-profile clean

all: $(OUT_DIR)/kernel8.img

$(OUT_DIR)/kernel8.img: $(OUT_DIR)/kernel8.elf
@mkdir -p $(@D)
$(OBJCOPY) -O binary $^ $@

$(OUT_DIR)/kernel8.elf: $(OBJ_PATHS) $(LD_SCRIPT)
@mkdir -p $(@D)
$(CC) -T $(LD_SCRIPT) $(LDFLAGS) $(filter-out $(LD_SCRIPT),$^) $(LDLIBS) -o $@

$(OUT_DIR)/%.o: $(SRC_DIR)/%.c
@mkdir -p $(@D)
$(CC) $(CPPFLAGS) $(CFLAGS) -c -MMD -MP -MF $(OUT_DIR)/$*.d $< -o $@

$(OUT_DIR)/%.o: $(OUT_DIR)/%.s
@mkdir -p $(@D)
$(AS) $(ASFLAGS) $^ -o $@

$(OUT_DIR)/%.s: $(SRC_DIR)/%.S
@mkdir -p $(@D)
$(CPP) $(CPPFLAGS) $^ -o $@

qemu: $(OUT_DIR)/kernel8.img
qemu-system-aarch64 -M raspi3b -kernel $< -initrd ../tests/initramfs.cpio \
-dtb ../tests/bcm2710-rpi-3-b-plus.dtb -display gtk -serial null \
-serial stdio

qemu-debug: $(OUT_DIR)/kernel8.img
qemu-system-aarch64 -M raspi3b -kernel $< -initrd ../tests/initramfs.cpio \
-dtb ../tests/bcm2710-rpi-3-b-plus.dtb -display gtk -serial null \
-serial stdio -S -s

gdb: $(OUT_DIR)/kernel8.elf
gdb -s $< -ex 'target remote :1234'

clean-profile:
$(RM) -r $(OUT_DIR)

clean:
$(RM) -r $(BUILD_DIR)

-include $(OUT_DIR)/*.d
141 changes: 141 additions & 0 deletions lab5/c/include/oscos/console.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/// \file include/oscos/console.h
/// \brief Serial console.
///
/// The serial console reads and writes data to the mini UART.
///
/// Before using the serial console, it must be initialized by calling
/// console_init(void) exactly once. Initializing the serial console twice or
/// operating on the serial console before initialization are not checked and
/// may have unintended consequences.
///
/// The serial console implements two modes: text mode and binary mode. In text
/// mode, automatic newline translation is performed. A "\r" character received
/// by the mini UART will be read as "\n", and writing "\n" to the serial
/// console will send "\r\n" down the mini UART. In binary mode, automatic
/// newline translation is not performed. Any byte received by the mini UART
/// will be read as-is, and every character written to the serial console will
/// also be sent as-is. Upon initialization, the mode is set to text mode.

#ifndef OSCOS_CONSOLE_H
#define OSCOS_CONSOLE_H

#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>

/// \brief The mode of the serial console.
typedef enum {
CM_TEXT, ///< Text mode. Performs newline translation.
CM_BINARY ///< Binary mode. Every byte are sent/received as-is.
} console_mode_t;

/// \brief Initializes the serial console.
///
/// See the file-level documentation for requirements on initialization.
void console_init(void);

/// \brief Sets the mode of the serial console.
///
/// \param mode The mode. Must be `CM_TEXT` or `CM_BINARY`.
void console_set_mode(console_mode_t mode);

/// \brief Reads a character from the serial console.
///
/// When calling this function, the serial console must be initialized.
unsigned char console_getc(void);

/// \brief Reads a character from the serial console without blocking.
///
/// When calling this function, the serial console must be initialized.
///
/// \return The character read, or a negative number if the read would block.
int console_getc_nonblock(void);

/// \brief Reads as many characters from the serial console as possible without
/// blocking.
///
/// When calling this function, the serial console must be initialized.
///
/// \return The number of characters read.
size_t console_read_nonblock(void *buf, size_t count);

/// \brief Writes a character to the serial console.
///
/// When calling this function, the serial console must be initialized.
///
/// \return \p c
unsigned char console_putc(unsigned char c);

/// \brief Writes a character to the serial console without blocking.
///
/// When calling this function, the serial console must be initialized.
///
/// \return \p c if the operation is successful, or a negative number if the
/// write operation would block.
int console_putc_nonblock(unsigned char c);

/// \brief Writes characters to the serial console.
///
/// When calling this function, the serial console must be initialized.
///
/// \return \p count
size_t console_write(const void *buf, size_t count);

/// \brief Writes as many characters to the serial console as possible without
/// blocking.
///
/// When calling this function, the serial console must be initialized.
///
/// \return The number of characters written.
size_t console_write_nonblock(const void *buf, size_t count);

/// \brief Writes a string to the serial console without trailing newline.
///
/// When calling this function, the serial console must be initialized.
void console_fputs(const char *s);

/// \brief Writes a string to the serial console with trailing newline.
///
/// When calling this function, the serial console must be initialized.
void console_puts(const char *s);

/// \brief Performs string formatting and writes the result to the serial
/// console.
///
/// When calling this function, the serial console must be initialized.
///
/// \return The number of characters written.
int console_vprintf(const char *restrict format, va_list ap)
__attribute__((format(printf, 1, 0)));

/// \brief Performs string formatting and writes the result to the serial
/// console.
///
/// When calling this function, the serial console must be initialized.
///
/// \return The number of characters written.
int console_printf(const char *restrict format, ...)
__attribute__((format(printf, 1, 2)));

/// \brief Registers the notification callback for read readiness.
///
/// \param callback The callback that will be called.
/// \param arg The argument that will be passed to \p callback.
/// \return true if the registration succeeds.
/// \return false if the registration fails because an earlier callback has not
/// been called.
bool console_notify_read_ready(void (*callback)(void *), void *arg);

/// \brief Registers the notification callback for write readiness.
///
/// \param callback The callback that will be called.
/// \param arg The argument that will be passed to \p callback.
/// \return true if the registration succeeds.
/// \return false if the registration fails because an earlier callback has not
/// been called.
bool console_notify_write_ready(void (*callback)(void *), void *arg);

/// \brief Interrupt handler. Not meant to be called directly.
void mini_uart_interrupt_handler(void);

#endif
Loading

0 comments on commit 4f696ab

Please sign in to comment.