Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added lab6/initramfs.cpio
Binary file not shown.
57 changes: 57 additions & 0 deletions lab6/kernel/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
OS := $(shell uname)

ifeq ($(OS), Linux)
ARMGNU = aarch64-linux-gnu
MACHINE = raspi3b
endif

ifeq ($(OS), Darwin)
ARMGNU = aarch64-unknown-linux-gnu
MACHINE = raspi3b
endif

CC = $(ARMGNU)-gcc
LK = $(ARMGNU)-ld
OBJCPY = $(ARMGNU)-objcopy
QEMU = qemu-system-aarch64

A_SRCS = $(wildcard lib/*.S)
C_SRCS = $(wildcard lib/*.c)
SRC_DIR = lib
OBJ_DIR = build
OBJS = $(A_SRCS:$(SRC_DIR)/%.S=$(OBJ_DIR)/%_s.o) $(C_SRCS:$(SRC_DIR)/%.c=$(OBJ_DIR)/%_c.o)
INCLUDE = include
CFLAGS = -ggdb -Wno-implicit -Wno-int-conversion -ffreestanding -nostdlib -nostartfiles -I$(INCLUDE)
CPIO_FILE = ../initramfs.cpio
DTB_FILE = ../bcm2710-rpi-3-b-plus.dtb

IMAGE = kernel8

all: $(IMAGE).img

$(IMAGE).img: $(IMAGE).elf
$(OBJCPY) -O binary $(IMAGE).elf $(IMAGE).img

$(IMAGE).elf: $(OBJS)
$(LK) $(OBJS) -T linker.ld -o $(IMAGE).elf

$(OBJ_DIR)/%_s.o: lib/%.S
@if [ ! -d "$(OBJ_DIR)" ]; then mkdir $(OBJ_DIR); fi
$(CC) -c $< $(CFLAGS) -o $@

$(OBJ_DIR)/%_c.o: lib/%.c
@if [ ! -d "$(OBJ_DIR)" ]; then mkdir $(OBJ_DIR); fi
$(CC) -c $< $(CFLAGS) -o $@

run: $(IMAGE).img
$(QEMU) -machine $(MACHINE) -kernel $(IMAGE).img -initrd $(CPIO_FILE) -dtb $(DTB_FILE) -display none -serial null -serial stdio

run_display: $(IMAGE).img
$(QEMU) -machine $(MACHINE) -kernel $(IMAGE).img -initrd $(CPIO_FILE) -dtb $(DTB_FILE) -serial null -serial stdio

dbg: $(IMAGE).img
$(QEMU) -machine $(MACHINE) -kernel $(IMAGE).img -initrd $(CPIO_FILE) -dtb $(DTB_FILE) -display none -serial null -serial stdio -s -S

.PHONY: clean
clean:
rm -rf $(OBJ_DIR) *.img *.elf */*.elf
34 changes: 34 additions & 0 deletions lab6/kernel/include/cpio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#ifndef CPIO_H
#define CPIO_H

#define CPIO_NEWC_HEADER_MAGIC "070701" // big endian

struct cpio_newc_header
{
char c_magic[6];
char c_ino[8];
char c_mode[8];
char c_uid[8];
char c_gid[8];
char c_nlink[8];
char c_mtime[8];
char c_filesize[8];
char c_devmajor[8];
char c_devminor[8];
char c_rdevmajor[8];
char c_rdevminor[8];
char c_namesize[8];
char c_check[8];
};

/* write pathname,data,next header into corresponding parameter*/
int cpio_newc_parse_header(struct cpio_newc_header *this_header_pointer,
char **pathname, unsigned int *filesize, char **data,
struct cpio_newc_header **next_header_pointer);

int ls(char* working_dir);
int cat(char* thefilepath);
int execfile(char *thefilepath);
char *get_file_start(char *thefilepath);
unsigned int get_file_size(char *thefilepath);
#endif
27 changes: 27 additions & 0 deletions lab6/kernel/include/current.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef CURRENT_H
#define CURRENT_H

#include "sched.h"

// tpidr_el1 : 64 bit system register
// get current thread data structure
// msb 2 bit : thread id
static inline thread_context_t *get_current_ctx(void)
{
thread_context_t *cur;
__asm__ __volatile__(
"mrs %0, tpidr_el1\n\t"
: "=r"(cur));
return cur;
}

static inline void set_current_ctx(thread_context_t *thread_context)
{
__asm__ __volatile__(
"msr tpidr_el1, %0\n\t"
::"r"(thread_context));
}

#define current_ctx get_current_ctx()

#endif
33 changes: 33 additions & 0 deletions lab6/kernel/include/dtb.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#ifndef DTB_H
#define DTB_H
#include "uint.h"


struct fdt_header {
unsigned int magic;
unsigned int totalsize;
unsigned int off_dt_struct;
unsigned int off_dt_strings;
unsigned int off_mem_rsvmap;
unsigned int version;
unsigned int last_comp_version;
unsigned int boot_cpuid_phys;
unsigned int size_dt_strings;
unsigned int size_dt_struct;
};
extern char* cpio_start;
extern char* cpio_end;

#define FDT_BEGIN_NODE 0x1 /* Start node: full name */
#define FDT_END_NODE 0x2 /* End node */
#define FDT_PROP 0x3 /* Property: name off, size, content */
#define FDT_NOP 0x4 /* nop */
#define FDT_END 0x9
typedef void (*dtb_callback)(unsigned int node_type, char *name, void *value, unsigned int name_size);

unsigned int endian_big2little(unsigned int x);
void fdt_traverse(dtb_callback callback);
void dtb_callback_show_tree(uint32_t node_type, char *name, void *value, uint32_t name_size);
void initramfs_callback(unsigned int node_type, char *name, void *value, unsigned int name_size);

#endif
27 changes: 27 additions & 0 deletions lab6/kernel/include/gpio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include <mmu.h>

#ifndef GPIO_H
#define GPIO_H

#define MMIO_BASE PHYS_TO_VIRT(0x3F000000)

#define GPFSEL0 ((volatile unsigned int*)(MMIO_BASE+0x00200000))
#define GPFSEL1 ((volatile unsigned int*)(MMIO_BASE+0x00200004))
#define GPFSEL2 ((volatile unsigned int*)(MMIO_BASE+0x00200008))
#define GPFSEL3 ((volatile unsigned int*)(MMIO_BASE+0x0020000C))
#define GPFSEL4 ((volatile unsigned int*)(MMIO_BASE+0x00200010))
#define GPFSEL5 ((volatile unsigned int*)(MMIO_BASE+0x00200014))
#define GPSET0 ((volatile unsigned int*)(MMIO_BASE+0x0020001C))
#define GPSET1 ((volatile unsigned int*)(MMIO_BASE+0x00200020))
#define GPCLR0 ((volatile unsigned int*)(MMIO_BASE+0x00200028))
#define GPLEV0 ((volatile unsigned int*)(MMIO_BASE+0x00200034))
#define GPLEV1 ((volatile unsigned int*)(MMIO_BASE+0x00200038))
#define GPEDS0 ((volatile unsigned int*)(MMIO_BASE+0x00200040))
#define GPEDS1 ((volatile unsigned int*)(MMIO_BASE+0x00200044))
#define GPHEN0 ((volatile unsigned int*)(MMIO_BASE+0x00200064))
#define GPHEN1 ((volatile unsigned int*)(MMIO_BASE+0x00200068))
#define GPPUD ((volatile unsigned int*)(MMIO_BASE+0x00200094))
#define GPPUDCLK0 ((volatile unsigned int*)(MMIO_BASE+0x00200098))
#define GPPUDCLK1 ((volatile unsigned int*)(MMIO_BASE+0x0020009C))

#endif
94 changes: 94 additions & 0 deletions lab6/kernel/include/irq.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#ifndef IRQ_H
#define IRQ_H


#include "mmu.h"

#define CORE0_INTERRUPT_SOURCE ((volatile unsigned int *)(PHYS_TO_VIRT(0x40000060)))

#define PERIPHERAL_INTERRUPT_BASE PHYS_TO_VIRT(0x3F000000)
#define IRQ_BASIC_PENDING ((volatile unsigned int *)(PERIPHERAL_INTERRUPT_BASE + 0x0000B200))

#define INTERRUPT_SOURCE_TIMER (1 << 1)
#define INTERRUPT_SOURCE_CNTPNSIRQ 1<<1
#define INTERRUPT_SOURCE_GPU (1 << 8)
#define IRQ_PENDING_1_AUX_INT (1 << 29)

#define IRQ_PENDING_1 ((volatile unsigned int *)(PERIPHERAL_INTERRUPT_BASE + 0x0000B204))
#define IRQ_PENDING_2 ((volatile unsigned int *)(PERIPHERAL_INTERRUPT_BASE + 0x0000B208))


#define FIQ_CONTROL ((volatile unsigned int *)(PERIPHERAL_INTERRUPT_BASE + 0x0000B20C))
#define ENABLE_IRQS_1 ((volatile unsigned int *)(PERIPHERAL_INTERRUPT_BASE + 0x0000B210))
#define ENABLE_IRQS_2 ((volatile unsigned int *)(PERIPHERAL_INTERRUPT_BASE + 0x0000B214))
#define ENABLE_BASIC_IRQS ((volatile unsigned int *)(PERIPHERAL_INTERRUPT_BASE + 0x0000B218))
#define DISABLE_IRQS_1 ((volatile unsigned int *)(PERIPHERAL_INTERRUPT_BASE + 0x0000B21C))
#define DISABLE_IRQS_2 ((volatile unsigned int *)(PERIPHERAL_INTERRUPT_BASE + 0x0000B220))
#define DISABLE_BASIC_IRQS ((volatile unsigned int *)(PERIPHERAL_INTERRUPT_BASE + 0x0000B224))


#define DATA_ABORT_LOWER 0b100100
#define INS_ABORT_LOWER 0b100000

#define TF_LEVEL0 0b000100
#define TF_LEVEL1 0b000101
#define TF_LEVEL2 0b000110
#define TF_LEVEL3 0b000111




// trapframe register
typedef struct trapframe
{
unsigned long x0;
unsigned long x1;
unsigned long x2;
unsigned long x3;
unsigned long x4;
unsigned long x5;
unsigned long x6;
unsigned long x7;
unsigned long x8;
unsigned long x9;
unsigned long x10;
unsigned long x11;
unsigned long x12;
unsigned long x13;
unsigned long x14;
unsigned long x15;
unsigned long x16;
unsigned long x17;
unsigned long x18;
unsigned long x19;
unsigned long x20;
unsigned long x21;
unsigned long x22;
unsigned long x23;
unsigned long x24;
unsigned long x25;
unsigned long x26;
unsigned long x27;
unsigned long x28;
unsigned long x29;
unsigned long x30;
unsigned long spsr_el1;
unsigned long elr_el1;
unsigned long sp_el0;

} trapframe_t;

void enable_interrupt();
void disable_interrupt();
void irq_handler();
void invalid_exception_handler(unsigned long long x0);
void cpacr_el1_off();
void sync_el0_64_handler(trapframe_t *tpf, unsigned long x1);

void highp();
void lowp();
void test_preemption();

void lock();
void unlock();
#endif
46 changes: 46 additions & 0 deletions lab6/kernel/include/list.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#ifndef LIST_H
#define LIST_H



typedef struct list_head {
struct list_head *next, *prev;
} list_head_t;

extern list_head_t task_list;
extern list_head_t *timer_event_list;

#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) list_head_t name = LIST_HEAD_INIT(name)

#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
#define list_for_each_prev(pos, head) \
for (pos = (head)->prev; prefetch(pos->prev), pos != (head); pos = pos->prev)

#define offsetof(TYPE, MEMBER) ((unsigned int) &((TYPE *)0)->MEMBER)

#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})

#define list_entry(ptr,type,member) \
container_of(ptr, type, member)

void INIT_LIST_HEAD(list_head_t *head);
int list_empty(const list_head_t *head);
static void __list_add(list_head_t *new_lst, list_head_t *prev, list_head_t *next);
void list_add(list_head_t *new_lst, list_head_t *head);
void list_add_tail( list_head_t *new_lst, list_head_t *head);
void list_insert(list_head_t *new_lst, list_head_t *prev, list_head_t *next);
static void __list_del(list_head_t * prev, list_head_t * next);
void list_del(list_head_t * entry);
int list_size(const list_head_t *head);

static inline int list_is_head(const struct list_head *list, const struct list_head *head)
{
return list == head;
}


#endif
52 changes: 52 additions & 0 deletions lab6/kernel/include/malloc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#ifndef MALLOC_H
#define MALLOC_H

#include "list.h"
#include "uart.h"
#include "irq.h"
#include "dtb.h"

#define MAXORDER 6
#define MAXCACHEORDER 4 // 32, 64, 128, 256, 512 (for every 32bytes)

// simple_malloc
void *smalloc(unsigned int size);

#define BUDDYSYSTEM_START PHYS_TO_VIRT(0x0) //0x10000000L
#define BUDDYSYSTEM_PAGE_COUNT 0x3C000
//buddy system (for >= 4K pages)
void *allocpage(unsigned int size);
void freepage(void *ptr);

//Basic Exercise 2 - Dynamic Memory Allocator - 30%
//For (< 4K)
//small memory allocation
//store listhead in cache first 16 bytes
void *alloccache(unsigned int size);
void freecache(void *ptr);
void page2caches(int order);

void *malloc(unsigned int size);
void free(void *ptr);

typedef struct frame
{
list_head_t listhead;
int val; // val is order
int isused;
int cacheorder; // -1 means isn't used for cache
unsigned int idx;
} frame_t;

void init_allocator();
frame_t *release_redundant(frame_t *frame);
frame_t *get_buddy(frame_t *frame);
frame_t *coalesce(frame_t* f);
void dump_freelist_info();
void dump_cachelist_info();
void memory_reserve(unsigned long long start, unsigned long long end);
void alloctest();
void *memcpy(void *dest, const void *src, unsigned long long n);
#endif


Loading