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
5 changes: 4 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{
"files.associations": {
"fork.h": "c"
"fork.h": "c",
"string.h": "c",
"mbr.h": "c",
"vfs.h": "c"
}
}
Binary file added lab6/bcm2710-rpi-3-b-plus.dtb
Binary file not shown.
3 changes: 3 additions & 0 deletions lab6/config.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
kernel=bootloader.img
arm_64bit=1
initramfs initramfs.cpio 0x20000000
49 changes: 49 additions & 0 deletions lab6/include/cpio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#ifndef __CPIO_H__
#define __CPIO_H__

/*
Each file system object in a cpio archive comprises a header record with
basic numeric metadata followed by the full pathname of the entry and the
file data. The header record stores a series of integer values that gen-
erally follow the fields in struct stat. (See stat(2) for details.) The
variants differ primarily in how they store those integers (binary, oc-
tal, or hexadecimal). The header is followed by the pathname of the en-
try (the length of the pathname is stored in the header) and any file
data. The end of the archive is indicated by a special record with the
pathname "TRAILER!!!"
*/

#define CPIO_HEADER_MAGIC "070701"
#define CPIO_FOOTER_MAGIC "TRAILER!!!"
#define PI_CPIO_BASE ((void*) (0x20000000))
#define QEMU_CPIO_BASE ((void*) (0x8000000))

#include "devtree.h"

extern void *DEVTREE_CPIO_BASE;

struct cpio_newc_header {
char c_magic[6]; // 070701
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]; // ignored by readers
};

void initramfs_callback (char *, char *, struct fdt_prop *);
void cpio_ls ();
void cpio_cat ();
void cpio_exec ();

unsigned int hexstr_to_uint(char *s, unsigned int len);

#endif
64 changes: 64 additions & 0 deletions lab6/include/devtree.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#ifndef _DEVTREE_H
#define _DEVTREE_H

/*
magic; 0xd00dfeed (big-endian)

totalsize; total size in bytes of the devicetree
data structure

off_dt_struct; offset in bytes of the structure block
from the beginning of the header

off_dt_strings; offset in bytes of the strings block
from the beginning of the header

off_mem_rsvmap; offset in bytes of the memory reservation
block from the beginning of the header

version; version of the devicetree data structure

last_comp_version; lowest version of the devicetree data
structure with which the version used is backwards compatible

boot_cpuid_phys; physical ID of the system’s boot CPU

size_dt_strings; length in bytes of the strings block
section of the devicetree blob

size_dt_struct; length in bytes of the structure block
section of the devicetree blob
*/

#define FDT_HEADER_MAGIC 0xd00dfeed
#define FDT_BEGIN_NODE 0x00000001
#define FDT_END_NODE 0x00000002
#define FDT_PROP 0x00000003
#define FDT_NOP 0x00000004
#define FDT_END 0x00000009

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;
};

struct fdt_prop {
unsigned int len;
unsigned int nameoff;
};

void devtree_getaddr ();
void fdt_traverse ( void (*callback)(char *, char *, struct fdt_prop *) );

// ARM uses little endian
unsigned long to_lendian (unsigned long);

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

#define S_FRAME_SIZE 272 // size of all saved registers
#define S_X0 0

#define SYNC_INVALID_EL1t 0
#define IRQ_INVALID_EL1t 1
#define FIQ_INVALID_EL1t 2
#define ERROR_INVALID_EL1t 3

#define SYNC_INVALID_EL1h 4
#define IRQ_INVALID_EL1h 5
#define FIQ_INVALID_EL1h 6
#define ERROR_INVALID_EL1h 7

#define SYNC_INVALID_EL0_64 8
#define IRQ_INVALID_EL0_64 9
#define FIQ_INVALID_EL0_64 10
#define ERROR_INVALID_EL0_64 11

#define SYNC_INVALID_EL0_32 12
#define IRQ_INVALID_EL0_32 13
#define FIQ_INVALID_EL0_32 14
#define ERROR_INVALID_EL0_32 15

#define SYNC_ERROR 16
#define SYSCALL_ERROR 17

#define ESR_ELx_EC_SHIFT 26
#define ESR_ELx_EC_SVC64 0x15

#ifndef __ASSEMBLER__

void ret_from_fork();

#endif

#endif
7 changes: 7 additions & 0 deletions lab6/include/exception.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef _EXCEPTION_H
#define _EXCEPTION_H

void enable_interrupt();
void disable_interrupt();

#endif
27 changes: 27 additions & 0 deletions lab6/include/fork.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef _FORK_H
#define _FORK_H

#include "sched.h"

#define PSR_MODE_EL0t 0x00000000
#define PSR_MODE_EL1t 0x00000004
#define PSR_MODE_EL1h 0x00000005
#define PSR_MODE_EL2t 0x00000008
#define PSR_MODE_EL2h 0x00000009
#define PSR_MODE_EL3t 0x0000000c
#define PSR_MODE_EL3h 0x0000000d

int copy_process(unsigned long, unsigned long, unsigned long/*, unsigned long*/);
int move_to_user_mode(unsigned long, unsigned long, unsigned long);
struct pt_regs *task_pt_regs(struct task_struct *);
void new_user_process(unsigned long);
int copy_virt_memory(struct task_struct *);

struct pt_regs {
unsigned long regs[31];
unsigned long sp;
unsigned long pc;
unsigned long pstate;
};

#endif
7 changes: 7 additions & 0 deletions lab6/include/mailbox.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef _MAILBOX_H
#define _MAILBOX_H

void get_board_revision ();
void get_arm_memory ();

#endif
7 changes: 7 additions & 0 deletions lab6/include/math.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef _MATH_H
#define _MATH_H

int log(int, int);
int pow(int, int);

#endif
8 changes: 8 additions & 0 deletions lab6/include/memory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef _MEMORY_H
#define _MEMORY_H

#define MAX_HEAP_SIZE 0x10000000

void* simple_malloc(unsigned int);

#endif
10 changes: 10 additions & 0 deletions lab6/include/mini_uart.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef _MINI_UART_H
#define _MINI_UART_H

void uart_init ( void );
char uart_recv ( void );
void uart_send ( char c );
void uart_send_string ( char* str );
void printf ( char *fmt, ... );

#endif /*_MINI_UART_H */
61 changes: 61 additions & 0 deletions lab6/include/mm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#ifndef _MM_H
#define _MM_H

#define MEM_REGION_BEGIN 0x0
#define MEM_REGION_END 0x3C000000
#define PAGE_SIZE 4096
#define MAX_ORDER 8 // largest: PAGE_SIZE*2^(MAX_ORDER)

#define ALLOCABLE 0
#define ALLOCATED -1
#define C_NALLOCABLE -2
#define RESERVED -3

#define NULL 0

#define MAX_POOL_PAGES 8
#define MAX_POOLS 8
#define MIN_CHUNK_SIZE 8

#define MAX_RESERVABLE 8

struct frame {
unsigned int index;
int val;
int state;
struct frame *prev, *next;
};

struct node {
struct node *next;
};

struct dynamic_pool {
unsigned int chunk_size;
unsigned int chunks_per_page;
unsigned int chunks_allocated;
unsigned int page_new_chunk_off;
unsigned int pages_used;
void *page_base_addrs[MAX_POOL_PAGES];
struct node *free_head;
};

#include "sched.h"

unsigned long allocate_user_page(struct task_struct *, unsigned long);
unsigned long allocate_kernel_page();

void *malloc(unsigned int);
void free(void *);
void init_mm();
void init_pool(struct dynamic_pool*, unsigned int);
int register_chunk(unsigned int);
void *chunk_alloc(unsigned int);
void chunk_free(void *);
void memory_reserve(void*, void*);
void init_mm_reserve();

void memcpy(unsigned long dst, unsigned long src, unsigned long n);
void memzero(unsigned long, unsigned long);

#endif /*_MM_H */
51 changes: 51 additions & 0 deletions lab6/include/mmu.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#ifndef _MMU_H
#define _MMU_H

#define VA_START 0xffff000000000000
#define VA_MASK 0x0000ffffffffffff

#define PAGE_MASK 0xfffffffffffff000

#define TCR_CONFIG_REGION_48bit (((64 - 48) << 0) | ((64 - 48) << 16))
#define TCR_CONFIG_4KB ((0b00 << 14) | (0b10 << 30))
#define TCR_CONFIG_DEFAULT (TCR_CONFIG_REGION_48bit | TCR_CONFIG_4KB)

#define MAIR_DEVICE_nGnRnE 0b00000000
#define MAIR_NORMAL_NOCACHE 0b01000100
#define MAIR_IDX_DEVICE_nGnRnE 0
#define MAIR_IDX_NORMAL_NOCACHE 1
#define MAIR_VALUE \
( \
(MAIR_DEVICE_nGnRnE << (MAIR_IDX_DEVICE_nGnRnE * 8)) | \
(MAIR_NORMAL_NOCACHE << (MAIR_IDX_NORMAL_NOCACHE * 8)) \
)

#define PD_TABLE 0b11
#define PD_BLOCK 0b01
#define PT_ENTRY 0b11
#define PD_ACCESS (1 << 10)
#define BOOT_PGD_ATTR PD_TABLE
#define BOOT_PUD_ATTR (PD_ACCESS | (MAIR_IDX_DEVICE_nGnRnE << 2) | PD_BLOCK)

#define PTE_USR_RO_PTE (PD_ACCESS | (0b11<<6) | (MAIR_IDX_NORMAL_NOCACHE<<2) | PT_ENTRY)
#define PTE_USR_RW_PTE (PD_ACCESS | (0b01<<6) | (MAIR_IDX_NORMAL_NOCACHE<<2) | PT_ENTRY)

#define SCTLR_MMU_DISABLED 0
#define SCTLR_MMU_ENABLED 1

#define PGD_SHIFT (12 + 3*9)
#define PUD_SHIFT (12 + 2*9)
#define PMD_SHIFT (12 + 9)

#ifndef __ASSEMBLER__

#include "sched.h"

void map_page(struct task_struct *task, unsigned long va, unsigned long page);
unsigned long map_table(unsigned long *table, unsigned long shift, unsigned long va, int* new_table);
void map_table_entry(unsigned long *pte, unsigned long va, unsigned long pa);
unsigned long va2phys(unsigned long va);

#endif

#endif
9 changes: 9 additions & 0 deletions lab6/include/peripherals/base.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef _P_BASE_H
#define _P_BASE_H

#include "mmu.h"

#define DEVICE_BASE 0x3F000000
#define PBASE (VA_START+DEVICE_BASE)

#endif /*_P_BASE_H */
Loading