Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

310555003 lab6 #167

Open
wants to merge 25 commits into
base: 310555003
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
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
10 changes: 7 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,12 @@ LIB_ASM_FILES += $(shell find "$(SRC_DIR)/$(LIB_DIR)" -name "*.S")
LIB_OBJ_FILES = $(patsubst $(SRC_DIR)/$(LIB_DIR)/%.c,$(BUILD_DIR)/$(LIB_DIR)/%_c.o,$(LIB_C_FILES))
LIB_OBJ_FILES += $(patsubst $(SRC_DIR)/$(LIB_DIR)/%.S,$(BUILD_DIR)/$(LIB_DIR)/%_s.o,$(LIB_ASM_FILES))

ifdef DEBUG
CFLAGS += -g -DDEBUG
ifdef MM_DEBUG
CFLAGS += -g -DMM_DEBUG
endif

ifdef DEMANDING_PAGE_DEBUG
CFLAGS += -g -DDEMANDING_PAGE_DEBUG
endif

all: $(KERNEL_IMG) $(BOOTLOADER_IMG)
Expand Down Expand Up @@ -89,7 +93,7 @@ $(INITRAMFS_CPIO): $(INITRAMFS_FILES)
cd initramfs; find . | cpio -o -H newc > ../$(INITRAMFS_CPIO)

qemu: all $(INITRAMFS_CPIO) $(RPI3_DTB)
qemu-system-aarch64 -M raspi3 -kernel $(BOOTLOADER_IMG) -display none \
qemu-system-aarch64 -M raspi3 -kernel $(BOOTLOADER_IMG) \
-initrd $(INITRAMFS_CPIO) \
-dtb $(RPI3_DTB) \
-chardev pty,id=pty0,logfile=pty.log,signal=off \
Expand Down
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ make

* Build kernel8.img with some debug information:
```
make DEBUG=1
# Options:
# MM_DEBUG
# DEMANDING_PAGE_DEBUG
make MM_DEBUG=1
make DEMANDING_PAGE_DEBUG=1
```

* Build myos.img (which you can dd to SD card):
Expand All @@ -35,6 +39,18 @@ make image
make qemu
```

* You should either attach gdb to qemu, or just remove the arugments `-s -S` passed to qemu in the Makefile

* Qemu will emulate the bootloader and you can then attach to the bootloader shell with:
```
sudo screen /dev/pts/<pts_idx>
```

* In the bootloader shell, you can use the command `load` to ask the bootloader to load the kernel image. After entering the `load` command, you can send the kernel image to the bootloader with the following command:
```
sudo ./tools/loadkernel.py /dev/pts/<pts_id> build/kernel8.img
```

## How to burn it into pi3

```
Expand Down
File renamed without changes.
1 change: 1 addition & 0 deletions include/lib/rpi3.h → include/bootloader/rpi3.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ struct arm_memory_info {
unsigned int size;
};

void mailbox_call(unsigned char channel, unsigned int *mb);
unsigned int get_board_revision(void);
void get_arm_memory(struct arm_memory_info *);

Expand Down
54 changes: 54 additions & 0 deletions include/kernel/BCM2837.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#ifndef _BCM2837_H
#define _BCM2837_H
// Ref: https://www.raspberrypi.org/app/uploads/2012/02/BCM2835-ARM-Peripherals.pdf

#define PERIPHERALS_BASE 0x3f000000
#define BUS_BASE 0x7e000000

#define BUS_TO_PERIPHERALS(addr) (addr - BUS_BASE + PERIPHERALS_BASE)

// Auxiliaries: UART1 & SPI1, SPI2
#define AUX_IRQ BUS_TO_PERIPHERALS(0x7E215000)
#define AUX_ENABLES BUS_TO_PERIPHERALS(0x7E215004)
#define AUX_MU_IO_REG BUS_TO_PERIPHERALS(0x7E215040)
#define AUX_MU_IER_REG BUS_TO_PERIPHERALS(0x7E215044)
#define AUX_MU_IIR_REG BUS_TO_PERIPHERALS(0x7E215048)
#define AUX_MU_LCR_REG BUS_TO_PERIPHERALS(0x7E21504c)
#define AUX_MU_MCR_REG BUS_TO_PERIPHERALS(0x7E215050)
#define AUX_MU_LSR_REG BUS_TO_PERIPHERALS(0x7E215054)
#define AUX_MU_MSR_REG BUS_TO_PERIPHERALS(0x7E215058)
#define AUX_MU_SCRATCH BUS_TO_PERIPHERALS(0x7E21505c)
#define AUX_MU_CNTL_REG BUS_TO_PERIPHERALS(0x7E215060)
#define AUX_MU_STAT_REG BUS_TO_PERIPHERALS(0x7E215064)
#define AUX_MU_BAUD_REG BUS_TO_PERIPHERALS(0x7E215068)
#define AUX_SPI0_CNTL0_REG BUS_TO_PERIPHERALS(0x7E215080)
#define AUX_SPI0_CNTL1_REG BUS_TO_PERIPHERALS(0x7E215084)
#define AUX_SPI0_STAT_REG BUS_TO_PERIPHERALS(0x7E215088)
#define AUX_SPI0_IO_REG BUS_TO_PERIPHERALS(0x7E215090)
#define AUX_SPI0_PEEK_REG BUS_TO_PERIPHERALS(0x7E215094)
#define AUX_SPI1_CNTL0_REG BUS_TO_PERIPHERALS(0x7E2150c0)
#define AUX_SPI1_CNTL1_REG BUS_TO_PERIPHERALS(0x7E2150c4)
#define AUX_SPI1_STAT_REG BUS_TO_PERIPHERALS(0x7E2150c8)
#define AUX_SPI1_IO_REG BUS_TO_PERIPHERALS(0x7E2150d0)
#define AUX_SPI1_PEEK_REG BUS_TO_PERIPHERALS(0x7E2150d4)

// GPIO
#define GPFSEL0 BUS_TO_PERIPHERALS(0x7E200000)
#define GPFSEL1 BUS_TO_PERIPHERALS(0x7E200004)
#define GPFSEL2 BUS_TO_PERIPHERALS(0x7E200008)
#define GPFSEL3 BUS_TO_PERIPHERALS(0x7E20000c)
#define GPFSEL4 BUS_TO_PERIPHERALS(0x7E200010)
#define GPFSEL5 BUS_TO_PERIPHERALS(0x7E200014)

#define GPPUD BUS_TO_PERIPHERALS(0x7E200094)
#define GPPUDCLK0 BUS_TO_PERIPHERALS(0x7E200098)
#define GPPUDCLK1 BUS_TO_PERIPHERALS(0x7E20009c)

// Interrupt
#define IRQ_ENABLE_1_REG BUS_TO_PERIPHERALS(0x7E00B210)

void BCM2837_reset(int tick);
void BCM2837_cancel_reset();


#endif /* _BCM2837_H */
28 changes: 28 additions & 0 deletions include/kernel/arm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef _ARM_H
#define _ARM_H

/* ==== PAR_EL1 related ==== */
#define PAR_FAILED(par) (par & 1)
#define PAR_PA(par) (par & 0x0000fffffffff000)

/* ==== ESR_EL1 related ==== */
#define EC_SVC_64 0x15
#define EC_IA_LE 0x20
#define EC_DA_LE 0x24

#define ISS_FSC(esr) (esr->iss & 0x3f)

#define FSC_TF_L0 0b000100
#define FSC_TF_L1 0b000101
#define FSC_TF_L2 0b000110
#define FSC_TF_L3 0b000111

#define ISS_WnR(esr) (esr->iss & 0x40)

typedef struct {
unsigned int iss:25, // Instruction specific syndrome
il:1, // Instruction length bit
ec:6; // Exception class
} esr_el1_t;

#endif /* _ARM_H */
8 changes: 4 additions & 4 deletions include/kernel/cpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ void cpio_cat(char *cpio, char *filename);

/*
* Allocate a memory chunk and load the @filename program onto it. Then return
* the address of the chunk. This memory chunk needs to be passed to kfree()
* manually.
* the address of the chunk by @output_data. @output_data needs to be passed
* to kfree() manually.
*
* Return NULL if failed.
* Return output_data length, return 0 if no such file.
*/
char *cpio_load_prog(char *cpio, char *filename);
uint32 cpio_load_prog(char *cpio, const char *filename, char **output_data);

void initramfs_init(void);

Expand Down
20 changes: 20 additions & 0 deletions include/kernel/current.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef _CURRENT_H
#define _CURRENT_H

#include <utils.h>

struct _task_struct;

static inline struct _task_struct *get_current(void)
{
return (struct _task_struct *)read_sysreg(tpidr_el1);
}

static inline void set_current(struct _task_struct *task)
{
write_sysreg(tpidr_el1, task);
}

#define current get_current()

#endif /* _CURRENT_H */
9 changes: 9 additions & 0 deletions include/kernel/entry.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef _ENTRY_H
#define _ENTRY_H

#include <types.h>
#include <trapframe.h>

void el0_sync_handler(trapframe *regs, uint32 syn);

#endif /* _ENTRY_H */
9 changes: 6 additions & 3 deletions include/kernel/exec.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
#ifndef _EXEC_H
#define _EXEC_H

// Change current EL to EL0 and execute the user program at @mem
// Set user stack to @user_sp
void exec_user_prog(char *mem, char *user_sp);
// TODO: Add argv & envp
void sched_new_user_prog(char *filename);

void exit_user_prog(void);

void exec_user_prog(void *entry, char *user_sp, char *kernel_sp);

#endif /* _EXEC_H */
5 changes: 4 additions & 1 deletion include/kernel/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ void irq_init();
/*
* On success, 0 is returned
*/
int irq_add_tasks(void (*task)(void *), void *args, uint32 prio);
int irq_run_task(void (*task)(void *),
void *args,
void (*fini)(void),
uint32 prio);

void irq_handler();
void exception_default_handler(uint32 n);
Expand Down
15 changes: 15 additions & 0 deletions include/kernel/kthread.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef _KTHREAD_H
#define _KTHREAD_H

#include <task.h>

void kthread_init(void);

void kthread_create(void (*start)(void));
void kthread_fini(void);

void kthread_add_wait_queue(task_struct *task);

void kthread_kill_zombies(void);

#endif /* _KTHREAD_H */
12 changes: 7 additions & 5 deletions include/kernel/mini_uart.h
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
#ifndef _MINI_UART_H
#define _MINI_UART_H

#include <stdarg.h>
#include <types.h>

uint32 uart_recvline(char *buff, int maxlen);
void uart_init(void);
char uart_recv(void);
void uart_recvn(char *buff, int n);
uint32 uart_recv_uint(void);
void uart_send(char c);
void uart_sendn(char *str, int n);
void uart_printf(char *fmt, ...);
void uart_sendn(const char *str, int n);
void uart_printf(const char *fmt, ...);

void uart_sync_printf(char *fmt, ...);
void uart_sync_printf(const char *fmt, ...);
void uart_sync_vprintf(const char *fmt, va_list args);

void uart_irq_check(void);
void uart_irq_handler(void);
int uart_irq_check(void);

/* Switch asynchronous/synchronous mode for uart RW */
int uart_switch_mode(void);
Expand Down
2 changes: 1 addition & 1 deletion include/kernel/mm/page_alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void *alloc_page(void);

void free_page(void *page);

#ifdef DEBUG
#ifdef MM_DEBUG
void page_allocator_test(void);
#endif

Expand Down
2 changes: 1 addition & 1 deletion include/kernel/mm/sc_alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ void *sc_alloc(int size);
*/
int sc_free(void *sc);

#ifdef DEBUG
#ifdef MM_DEBUG
void sc_test(void);
#endif

Expand Down
81 changes: 81 additions & 0 deletions include/kernel/mmu.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#ifndef _MMU_H
#define _MMU_H

#include <types.h>
#include <list.h>
#include <arm.h>
#include <trapframe.h>

#define PAGE_TABLE_SIZE 0x1000

#define PT_R 0x0001
#define PT_W 0x0002
#define PT_X 0x0004

#define VMA_R PT_R
#define VMA_W PT_W
#define VMA_X PT_X
// PA
#define VMA_PA 0x0008
// Kernel VA
#define VMA_KVA 0x0010
// Anonymous
#define VMA_ANON 0x0020

typedef uint64 pd_t;

/* TODO: The vm_area_t linked list is not sorted, making it an ordered list. */
typedef struct _vm_area_t {
/* @list links to next vm_area_t */
struct list_head list;
uint64 va_begin;
uint64 va_end;
uint64 flag;
/* @kva: Mapped kernel virtual address */
uint64 kva;
} vm_area_t;

typedef struct {
/* @vma links all vm_area_t */
struct list_head vma;
} vm_area_meta_t;

/*
* Set identity paging, enable MMU
*/
void mmu_init(void);

pd_t *pt_create(void);
void pt_free(pd_t *pt);

/*
* Create a @size mapping of @va -> @pa.
* @pt is PGD.
*/
void pt_map(pd_t *pt, void *va, uint64 size, void *pa, uint64 flag);

vm_area_meta_t *vma_meta_create(void);
void vma_meta_free(vm_area_meta_t *vma_meta, pd_t *page_table);
void vma_meta_copy(vm_area_meta_t *to, vm_area_meta_t *from, pd_t *page_table);

void vma_map(vm_area_meta_t *vma_meta, void *va, uint64 size,
uint64 flag, void *addr);

void mem_abort(esr_el1_t *esr);

/* syscalls */
#define PROT_NONE 0
#define PROT_READ 1
#define PROT_WRITE 2
#define PROT_EXEC 4

#define MAP_ANONYMOUS 0x0020
#define MAP_POPULATE 0x8000

/*
* TODO: @fd, @file_offset are ignored currently.
*/
void syscall_mmap(trapframe *frame, void *addr, size_t len, int prot,
int flags, int fd, int file_offset);

#endif /* _MMU_H */
8 changes: 8 additions & 0 deletions include/kernel/mode_switch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef _MODE_SWITCH_H
#define _MODE_SWITCH_H

#include <trapframe.h>

void exit_to_user_mode(trapframe regs);

#endif /* _MODE_SWITCH_H */
6 changes: 6 additions & 0 deletions include/kernel/panic.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef _PANIC_H
#define _PANIC_H

void panic(const char *fmt, ...);

#endif /* _PANIC_H */
Loading