Skip to content

Commit

Permalink
MMU configuration for kernel mode
Browse files Browse the repository at this point in the history
  • Loading branch information
TheLortex committed Apr 22, 2017
1 parent 40522c9 commit b669e20
Show file tree
Hide file tree
Showing 15 changed files with 373 additions and 206 deletions.
36 changes: 13 additions & 23 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ RAMFS = ramfs_content/
TARGET = img/kernel.img
TARGET_QEMU = img/kernel_qemu.img

RAMIMG = img/ram.img
RAMIMG_QEMU = img/ram_qemu.img

IMGDIR = img/

LINKER = kernel.ld
Expand All @@ -20,7 +17,7 @@ LINKER_QEMU = kernel_qemu.ld
# recursive wildcard.
rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))

OBJECTS = $(patsubst $(SOURCE)%.S,$(BUILD)%.o,$(wildcard $(SOURCE)*.S))
OBJECTS = $(BUILD)fs.img $(patsubst $(SOURCE)%.S,$(BUILD)%.o,$(wildcard $(SOURCE)*.S))
OBJECTS_C = $(patsubst $(SOURCE)%.c,$(BUILD)%.o,$(call rwildcard, $(SOURCE), *.c))
RAMFS_OBJ = $(call rwildcard, $(RAMFS), *)

Expand All @@ -44,10 +41,10 @@ $(shell mkdir -p $(DEPDIR) >/dev/null)
$(shell mkdir -p $(BUILD) >/dev/null)

#all: builds the kernel image for the real hardware. RPI2 flag by default.
all: $(RAMIMG)
all: $(TARGET)

#qemu: builds the kernel image for qemu emulation.
qemu: $(RAMIMG_QEMU)
qemu: $(TARGET_QEMU)

#rpi: sets the flag for the RPI1 build.
rpi: RPI_FLAG = -D RPI
Expand All @@ -58,29 +55,24 @@ rpi: all
rpi2: RPI_FLAG = -D RPI2
rpi2: all

# Builds a 1MB filesystem
$(BUILD)fs.img: $(RAMFS_OBJ)
genext2fs -b 4096 -d $(RAMFS) $(BUILD)fs.img
genext2fs -b 1024 -d $(RAMFS) $(BUILD)fs.tmp
$(ARMGNU)-ld -b binary -r -o $(BUILD)fs.ren $(BUILD)fs.tmp
$(ARMGNU)-objcopy --rename-section .data=.fs \
--set-section-flags .data=alloc,code,load \
$(BUILD)fs.ren $(BUILD)fs.img

run: $(RAMIMG_QEMU)
$(QEMU) -kernel $(RAMIMG_QEMU) -m 256 -M raspi2 -monitor stdio -serial pty
run: $(TARGET_QEMU)
$(QEMU) -kernel $(TARGET_QEMU) -m 256 -M raspi2 -monitor stdio -serial pty -serial pty

runs: $(RAMIMG_QEMU)
$(QEMU) -kernel $(RAMIMG_QEMU) -m 256 -M raspi2 -serial pty -serial stdio
runs: $(TARGET_QEMU)
$(QEMU) -kernel $(TARGET_QEMU) -m 256 -M raspi2 -serial pty -serial stdio


minicom:
minicom -b 115200 -o -D /dev/pts/2

$(RAMIMG): $(TARGET) $(BUILD)fs.img
qemu-img create $(RAMIMG) 20M
dd if=$(TARGET) of=$(RAMIMG) bs=2048 conv=notrunc
dd if=$(BUILD)fs.img of=$(RAMIMG) bs=2048 seek=8M oflag=seek_bytes

$(RAMIMG_QEMU): $(TARGET_QEMU) $(BUILD)fs.img
qemu-img create $(RAMIMG_QEMU) 20M
dd if=$(TARGET_QEMU) of=$(RAMIMG_QEMU) bs=2048 conv=notrunc
dd if=$(BUILD)fs.img of=$(RAMIMG_QEMU) bs=2048 seek=8M oflag=seek_bytes

$(TARGET) : $(BUILD)output.elf
$(ARMGNU)-objcopy $(BUILD)output.elf -O binary $(TARGET)

Expand Down Expand Up @@ -118,5 +110,3 @@ clean:
@rm -fr $(BUILD)*
@rm -f $(TARGET)
@rm -f $(TARGET_QEMU)
@rm -f $(RAMIMG)
@rm -f $(RAMIMG_QEMU)
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,12 @@ make

# Génerer un système de fichiers ext2 grâce à genext2fs
genext2fs -b 1024 -d ramfs_content/ fs.out


0x00000000 -> 0x7fffffff = user process memory (not mapped)
0x80000000 -> 0xbeffffff = mapped to physical memory
0xbf000000 -> 0xbfffffff => 0x20000000 -> 0x20ffffff RPI1
=> 0x3f000000 -> 0x3fffffff RPI2
(peripherals are also mapped in the same way but with cache disabled)
0xc0000000 -> 0xefffffff = kernel dynamic data (=> mapped to KERNEL_IMAGE_SIZE (blocks allocated on the run with sbrk))
0xf0000000 -> (0xf0000000 + KERNEL_IMAGE_SIZE + kstart) = kernel code (=> mapped to 0x0 -> (KERNEL_IMAGE_SIZE + kstart))
76 changes: 34 additions & 42 deletions kernel.ld
Original file line number Diff line number Diff line change
@@ -1,51 +1,43 @@
/******************************************************************************
* kernel.ld
* by Alex Chadwick
*
* A linker script for generation of raspberry pi kernel images.
******************************************************************************/

SEARCH_DIR("=/usr/lib/arm-none-eabi/lib");

SECTIONS {
/*
* INFO: 0x10000 for QEMU and 0x8000 for raspi2
*/
__start = 0x8000;
.init 0x8000 : {
*(.init)
/* Loader section that boots and setup the mmu before going into virtual
* addressing
*/
. = 0x8000;
__start = .;
.init : {
build/loader.o(.text* .data* .bss* .rodata*)
}

__text_start = .;
.text :
{
KEEP(*(.text.boot))
*(.text)
.initsys : {
build/initsys.o(.text* .data* .bss* .rodata*)
}
. = ALIGN(4096);
__text_end = .;

__rodata_start = .;
.rodata :
{
*(.rodata)
}
. = ALIGN(4096);
__rodata_end = .;

__data_start = .;
.data :
{
*(.data)
__kernel_phy_start = ALIGN(4k);
.text (__kernel_phy_start + 0xf0000000) : AT(__kernel_phy_start) {
*(.text*)
}
. = ALIGN(4096);
__data_end = .;
__bss_start = .;
.bss :
{
bss = .;
*(.bss)
. = ALIGN(4K);
.rodata : {
*(.rodata*)
}
. = ALIGN(4096);
__bss_end = .;
__end = .;
. = ALIGN(4K);
.data : {
*(.data)
}
. = ALIGN(4K);
.bss : {
__kernel_bss_start = ABSOLUTE(.);
*(.bss)
*(COMMON)
__kernel_bss_end = ABSOLUTE(.);
}
. = ALIGN(4K);
__ramfs_start = .;
.fs : {
build/fs.img(.data*)
}
__kernel_phy_end = . - 0xf0000000;

}
75 changes: 34 additions & 41 deletions kernel_qemu.ld
Original file line number Diff line number Diff line change
@@ -1,50 +1,43 @@
/******************************************************************************
* kernel.ld
* by Alex Chadwick
*
* A linker script for generation of raspberry pi kernel images.
******************************************************************************/

SEARCH_DIR("=/usr/lib/arm-none-eabi/lib");

SECTIONS {
/*
* INFO: 0x10000 for QEMU and 0x8000 for raspi2
*/
__start = 0x10000;
.init 0x10000 : {
*(.init)
/* Loader section that boots and setup the mmu before going into virtual
* addressing
*/
. = 0x10000;
__start = .;
.init : {
build/loader.o(.text* .data* .bss* .rodata*)
}

__text_start = .;
.text :
{
KEEP(*(.text.boot))
*(.text)
.initsys : {
build/initsys.o(.text* .data* .bss* .rodata*)
}
. = ALIGN(4096);
__text_end = .;

__rodata_start = .;
.rodata :
{
*(.rodata)

__kernel_phy_start = ALIGN(4k);
.text (__kernel_phy_start + 0xf0000000) : AT(__kernel_phy_start) {
*(.text*)
}
. = ALIGN(4096);
__rodata_end = .;
__data_start = .;
.data :
{
*(.data)
. = ALIGN(4K);
.rodata : {
*(.rodata*)
}
. = ALIGN(4096);
__data_end = .;
__bss_start = .;
.bss :
{
bss = .;
*(.bss)
. = ALIGN(4K);
.data : {
*(.data)
}
. = ALIGN(4096);
__bss_end = .;
__end = .;
. = ALIGN(4K);
.bss : {
__kernel_bss_start = ABSOLUTE(.);
*(.bss)
*(COMMON)
__kernel_bss_end = ABSOLUTE(.);
}
. = ALIGN(4K);
__ramfs_start = .;
.fs : {
build/fs.img(.data*)
}
__kernel_phy_end = . - 0xf0000000;

}
48 changes: 42 additions & 6 deletions src/cstubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,52 @@
#include "stddef.h"
#include "stdint.h"

#include "memalloc.h"
#include "mmu.h"

intptr_t _sbrk(int incr) {
static char* heap_end = 0;
char* prev_heap_end;
if(heap_end == 0) // first initialization of heap.
heap_end = (char*) (16*1024*1024); // TODO: not hardcode that and maybe place it somewhere else.

//#define HEAP_BASE 0xc0000000
#define HEAP_BASE 0xc0000000
#define KERNEL_TTB_ADDRESS 0x4000

extern int __kernel_phy_end;

uintptr_t _sbrk(int incr) {
static uintptr_t heap_end = 0;
static uint32_t allocated_pages = 0;
uintptr_t prev_heap_end;
if(heap_end == 0) { // first initialization of heap.
heap_end = (uintptr_t) HEAP_BASE;
allocated_pages = 1;

mmu_add_section(KERNEL_TTB_ADDRESS,
HEAP_BASE,
(int)&__kernel_phy_end,
DC_CLIENT | ENABLE_CACHE | ENABLE_WRITE_BUFFER);
}

prev_heap_end = heap_end;
heap_end += incr;
return (intptr_t)prev_heap_end;
uint32_t n_sections = (heap_end - HEAP_BASE + 1024*1024 - 1) >> 20;
if (n_sections > allocated_pages) {
// TODO: Proper error handling
page_list_t* res = paging_allocate(n_sections - allocated_pages);
while (res != NULL) {
for (int i=0;i<res->size;i++) {
mmu_add_section(
KERNEL_TTB_ADDRESS,
HEAP_BASE + allocated_pages*PAGE_SECTION,
(res->address + i)*PAGE_SECTION,
DC_CLIENT | ENABLE_CACHE | ENABLE_WRITE_BUFFER);
allocated_pages++;
}
res = res->next;
}
} else if (n_sections < allocated_pages) {
// TODO: Deallocate
}

return (uintptr_t)prev_heap_end;
}

int min(int const a, int const b) {
Expand Down
55 changes: 55 additions & 0 deletions src/initsys.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include "stdint.h"
#include "stddef.h"
#include "mmu.h"

#define KERNEL_TTB_ADDRESS 0x4000

extern int __kernel_phy_end;



void init_map(uintptr_t from, uintptr_t to, uint32_t flags) {
uintptr_t address_section = (KERNEL_TTB_ADDRESS | (uintptr_t)((from & 0xFFF00000) >> 18));
uint32_t value_section = (0xFFF00000 & to) | flags | SECTION;
*((uint32_t*)(address_section)) = value_section;
}

void init_setup_ttb() {
uintptr_t i;
const int section_size = 0x00100000;
for(i=0;i<0x80000000;i+=section_size) { // temporary linear mapping (deleted as soon as we enter real kernel mode)
init_map(i,i,ENABLE_CACHE | ENABLE_WRITE_BUFFER | DC_CLIENT);
}

for(;i<0xbf000000;i+=section_size) { // physical ram mapping for kernel.
init_map(i,i-0x80000000,ENABLE_CACHE | ENABLE_WRITE_BUFFER | DC_CLIENT);
}

for(;i<0xc0000000;i+=section_size) { // peripherals mapping
#ifdef RPI2
init_map(i,i-0x80000000,DC_CLIENT);
#else
init_map(i,i-0x9f000000,DC_CLIENT);
#endif
}
for(i=0xf0000000;i<0xf0000001+(uintptr_t)&__kernel_phy_end;i+=section_size) { // kernel data & code mapping
init_map(i,i-0xf0000000,ENABLE_CACHE | ENABLE_WRITE_BUFFER | DC_CLIENT);
}
}

int init_get_ram() {
uint32_t* atags_ptr = (uint32_t*)0x100;

#define ATAG_NONE 0
#define ATAG_CORE 0x54410001
#define ATAG_MEM 0x54410002

while (*(atags_ptr+1) != ATAG_NONE) {
if (*(atags_ptr+1) == ATAG_MEM) {
return *(atags_ptr+2);
}
atags_ptr += (*atags_ptr);
}
while(1){}
return 0;
}
2 changes: 1 addition & 1 deletion src/interrupts.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ void __attribute__ ((interrupt("ABORT"))) prefetch_abort_vector(void) {
}

void __attribute__ ((interrupt("ABORT"))) data_abort_vector(void) {
kdebug(D_IRQ, 0, "DATA_ABORT.\n");
while(1);
kdebug(D_IRQ, 0, "DATA_ABORT.\n");
}

static rpi_irq_controller_t* rpiIRQController =
Expand Down
Loading

0 comments on commit b669e20

Please sign in to comment.