mirror of
https://github.com/drasko/codezero.git
synced 2026-02-26 16:53:14 +01:00
More changes for cleaner initialization and support for containers.
This commit is contained in:
@@ -27,7 +27,7 @@ import cml2header
|
|||||||
import cmlconfigure
|
import cmlconfigure
|
||||||
|
|
||||||
# The linker script to link the final executable
|
# The linker script to link the final executable
|
||||||
linker_script = join(headers_root, 'l4/arch/arm/mylink.lds')
|
linker_script = join(headers_root, 'l4/arch/arm/linker.lds')
|
||||||
|
|
||||||
# Environment to build sources
|
# Environment to build sources
|
||||||
#env = None
|
#env = None
|
||||||
|
|||||||
@@ -16,14 +16,10 @@ extern unsigned long arm_high_vector[];
|
|||||||
extern unsigned long _end_vectors[];
|
extern unsigned long _end_vectors[];
|
||||||
extern unsigned long _start_kip[];
|
extern unsigned long _start_kip[];
|
||||||
extern unsigned long _end_kip[];
|
extern unsigned long _end_kip[];
|
||||||
extern unsigned long _start_ptab[];
|
extern unsigned long _start_init[];
|
||||||
extern unsigned long _end_ptab[];
|
extern unsigned long _end_init[];
|
||||||
extern unsigned long _bootstack[];
|
extern unsigned long _bootstack[];
|
||||||
extern unsigned long _end_kernel[];
|
extern unsigned long _end_kernel[];
|
||||||
extern unsigned long _start_kspace[];
|
|
||||||
extern unsigned long _start_pmd[];
|
|
||||||
extern unsigned long _end_pmd[];
|
|
||||||
extern unsigned long _end_kspace[];
|
|
||||||
extern unsigned long _end[];
|
extern unsigned long _end[];
|
||||||
|
|
||||||
/* Link markers that get modified at runtime */
|
/* Link markers that get modified at runtime */
|
||||||
|
|||||||
@@ -1,36 +1,32 @@
|
|||||||
/*
|
/*
|
||||||
*
|
|
||||||
* Simple linker script
|
* Simple linker script
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007 Bahadir Balban
|
* Copyright (C) 2007 Bahadir Balban
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* FIXME:
|
/* FIXME:
|
||||||
* Currently we can't include cpp #defines in linker script.
|
* Currently we can't include cpp #defines in linker script.
|
||||||
* Check that below offsets are coherent with offsets.h
|
* Check that below offsets are coherent with offsets.h
|
||||||
*/
|
*/
|
||||||
phys_addr_base = 0x100000;
|
kernel_offset = 0xF0000000;
|
||||||
kern_offset = 0xF0000000;
|
kernel_physical = 0x8000;
|
||||||
virt_addr_base = phys_addr_base + kern_offset;
|
kernel_virtual = kernel_physical + kernel_offset;
|
||||||
|
|
||||||
/* A temporary boot stack is used before a proper kernel stack is set up */
|
/* A temporary boot stack is used before a proper kernel stack is set up */
|
||||||
_bootstack_physical = _bootstack - kern_offset;
|
_bootstack_physical = _bootstack - kernel_offset;
|
||||||
|
|
||||||
/* The symbols are linked at virtual addresses. So is _start.
|
/* The symbols are linked at virtual addresses. So is _start.
|
||||||
* We must set the entry point to a physical address, so that
|
* We must set the entry point to a physical address, so that
|
||||||
* when the image is loaded, it doesn't jump to a non existing
|
* when the image is loaded, it doesn't jump to a non existing
|
||||||
* virtual address.
|
* virtual address.
|
||||||
*/
|
*/
|
||||||
_start_physical = phys_addr_base;
|
ENTRY(kernel_physical)
|
||||||
|
|
||||||
ENTRY(_start_physical)
|
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = virt_addr_base;
|
. = kernel_virtual;
|
||||||
_start_kernel = .;
|
_start_kernel = .;
|
||||||
.text : AT (ADDR(.text) - kern_offset)
|
.text : AT (ADDR(.text) - kernel_offset)
|
||||||
{
|
{
|
||||||
_start_text = .;
|
_start_text = .;
|
||||||
/* Make sure head.S comes first */
|
/* Make sure head.S comes first */
|
||||||
@@ -41,9 +37,9 @@ SECTIONS
|
|||||||
}
|
}
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
/* rodata is needed else your strings will link at physical! */
|
/* rodata is needed else your strings will link at physical! */
|
||||||
.rodata : AT (ADDR(.rodata) - kern_offset) { *(.rodata) }
|
.rodata : AT (ADDR(.rodata) - kernel_offset) { *(.rodata) }
|
||||||
.rodata1 : AT (ADDR(.rodata1) - kern_offset) { *(.rodata1) }
|
.rodata1 : AT (ADDR(.rodata1) - kernel_offset) { *(.rodata1) }
|
||||||
.data : AT (ADDR(.data) - kern_offset)
|
.data : AT (ADDR(.data) - kernel_offset)
|
||||||
{
|
{
|
||||||
_start_data = .;
|
_start_data = .;
|
||||||
*(.data)
|
*(.data)
|
||||||
@@ -61,7 +57,7 @@ SECTIONS
|
|||||||
_end_syscalls = .;
|
_end_syscalls = .;
|
||||||
_end_data = .;
|
_end_data = .;
|
||||||
}
|
}
|
||||||
.bss : AT (ADDR(.bss) - kern_offset)
|
.bss : AT (ADDR(.bss) - kernel_offset)
|
||||||
{
|
{
|
||||||
*(.bss)
|
*(.bss)
|
||||||
}
|
}
|
||||||
@@ -69,19 +65,20 @@ SECTIONS
|
|||||||
. += 0x2000; /* This is required as the link counter does not seem
|
. += 0x2000; /* This is required as the link counter does not seem
|
||||||
* to increment for the bss section
|
* to increment for the bss section
|
||||||
* TODO: Change this with PAGE_SIZE */
|
* TODO: Change this with PAGE_SIZE */
|
||||||
|
|
||||||
|
/* Below part is to be discarded after boot */
|
||||||
|
_start_init = .;
|
||||||
|
.init : AT (ADDR(.init) - kernel_offset)
|
||||||
|
{
|
||||||
|
. = ALIGN(16K); /* For initial pgd */
|
||||||
|
*(.init.pgd)
|
||||||
|
*(.init.data)
|
||||||
|
*(.init.bootmem)
|
||||||
|
}
|
||||||
|
/* Space for boot stack */
|
||||||
|
. += 0x1000;
|
||||||
|
_end_init = .;
|
||||||
_bootstack = .;
|
_bootstack = .;
|
||||||
_end_kernel = .;
|
_end_kernel = .;
|
||||||
. = ALIGN(1M);
|
|
||||||
.kspace : AT(ADDR(.kspace) - kern_offset)
|
|
||||||
{
|
|
||||||
_start_kspace = .;
|
|
||||||
*(.kspace.pgd)
|
|
||||||
. = ALIGN(4K);
|
|
||||||
_start_pmd = .;
|
|
||||||
*(.kspace.pmd)
|
|
||||||
_end_pmd = .;
|
|
||||||
_end_kspace = .;
|
|
||||||
}
|
|
||||||
_end = .;
|
_end = .;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,6 +137,9 @@ void arch_hardware_flush(pgd_table_t *pgd);
|
|||||||
void add_section_mapping_init(unsigned int paddr, unsigned int vaddr,
|
void add_section_mapping_init(unsigned int paddr, unsigned int vaddr,
|
||||||
unsigned int size, unsigned int flags);
|
unsigned int size, unsigned int flags);
|
||||||
|
|
||||||
|
void add_boot_mapping(unsigned int paddr, unsigned int vaddr,
|
||||||
|
unsigned int size, unsigned int flags);
|
||||||
|
|
||||||
struct address_space;
|
struct address_space;
|
||||||
int delete_page_tables(struct address_space *space);
|
int delete_page_tables(struct address_space *space);
|
||||||
int copy_user_tables(struct address_space *new, struct address_space *orig);
|
int copy_user_tables(struct address_space *new, struct address_space *orig);
|
||||||
|
|||||||
13
include/l4/generic/bootmem.h
Normal file
13
include/l4/generic/bootmem.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2009 Bahadir Balban
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __BOOTMEM_H__
|
||||||
|
#define __BOOTMEM_H__
|
||||||
|
|
||||||
|
void *alloc_bootmem(int size, int alignment);
|
||||||
|
pmd_table_t *alloc_boot_pmd(void);
|
||||||
|
|
||||||
|
extern pgd_table_t init_pgd;
|
||||||
|
|
||||||
|
#endif /* __BOOTMEM_H__ */
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
#define page_align(addr) (((unsigned int)(addr)) & \
|
#define page_align(addr) (((unsigned int)(addr)) & \
|
||||||
(~PAGE_MASK))
|
(~PAGE_MASK))
|
||||||
|
|
||||||
#define is_aligned(val, mask) (!(((unsigned long)(val)) & mask))
|
#define is_aligned(val, size) (!(((unsigned long)(val)) & ((size) - 1)))
|
||||||
#define is_page_aligned(val) (!(((unsigned long)(val)) & PAGE_MASK))
|
#define is_page_aligned(val) (!(((unsigned long)(val)) & PAGE_MASK))
|
||||||
#define page_boundary(x) is_page_aligned(x)
|
#define page_boundary(x) is_page_aligned(x)
|
||||||
|
|
||||||
@@ -80,13 +80,6 @@ static inline void be32_to_cpu(unsigned int x)
|
|||||||
#define TASK_AVERAGE_SIZE SZ_16MB
|
#define TASK_AVERAGE_SIZE SZ_16MB
|
||||||
#define TASKS_PER_1MB_GRANT 28
|
#define TASKS_PER_1MB_GRANT 28
|
||||||
|
|
||||||
extern pgd_table_t kspace;
|
|
||||||
extern pmd_table_t pmd_tables[];
|
|
||||||
extern unsigned long pmdtab_i;
|
|
||||||
|
|
||||||
void init_pmd_tables(void);
|
|
||||||
pmd_table_t *alloc_boot_pmd(void);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Each time a pager grants memory to the kernel, these parameters are called
|
* Each time a pager grants memory to the kernel, these parameters are called
|
||||||
* for in order to distribute the granted memory for different purposes.
|
* for in order to distribute the granted memory for different purposes.
|
||||||
@@ -104,13 +97,9 @@ typedef struct grant_kmem_usage {
|
|||||||
} grant_kmem_usage_t;
|
} grant_kmem_usage_t;
|
||||||
|
|
||||||
void paging_init(void);
|
void paging_init(void);
|
||||||
void init_pmd_tables(void);
|
|
||||||
void init_clear_ptab(void);
|
|
||||||
|
|
||||||
unsigned int space_flags_to_ptflags(unsigned int flags);
|
unsigned int space_flags_to_ptflags(unsigned int flags);
|
||||||
|
|
||||||
void add_boot_mapping(unsigned int paddr, unsigned int vaddr,
|
|
||||||
unsigned int size, unsigned int flags);
|
|
||||||
void add_mapping_pgd(unsigned int paddr, unsigned int vaddr,
|
void add_mapping_pgd(unsigned int paddr, unsigned int vaddr,
|
||||||
unsigned int size, unsigned int flags,
|
unsigned int size, unsigned int flags,
|
||||||
pgd_table_t *pgd);
|
pgd_table_t *pgd);
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
#define PB926_SIC_BASE 0x10003000 /* Secondary IC */
|
#define PB926_SIC_BASE 0x10003000 /* Secondary IC */
|
||||||
#define PB926_UART0_BASE 0x101F1000 /* Console port (UART0) */
|
#define PB926_UART0_BASE 0x101F1000 /* Console port (UART0) */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Uart virtual address until a file-based console access
|
* Uart virtual address until a file-based console access
|
||||||
* is available for userspace
|
* is available for userspace
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ void read_bootdesc(void)
|
|||||||
* End of the kernel image is where bootdesc resides. Note this is
|
* End of the kernel image is where bootdesc resides. Note this is
|
||||||
* not added to the page_map because it's meant to be discarded.
|
* not added to the page_map because it's meant to be discarded.
|
||||||
*/
|
*/
|
||||||
add_mapping(virt_to_phys(_end), (unsigned long)_end, PAGE_SIZE,
|
// add_mapping(virt_to_phys(_end), (unsigned long)_end, PAGE_SIZE,
|
||||||
MAP_USR_DEFAULT_FLAGS);
|
// MAP_USR_DEFAULT_FLAGS);
|
||||||
|
|
||||||
/* Get original bootdesc */
|
/* Get original bootdesc */
|
||||||
bootdesc = (struct bootdesc *)_end;
|
bootdesc = (struct bootdesc *)_end;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include <l4/lib/string.h>
|
#include <l4/lib/string.h>
|
||||||
#include <l4/generic/scheduler.h>
|
#include <l4/generic/scheduler.h>
|
||||||
#include <l4/generic/space.h>
|
#include <l4/generic/space.h>
|
||||||
|
#include <l4/generic/bootmem.h>
|
||||||
#include <l4/api/errno.h>
|
#include <l4/api/errno.h>
|
||||||
#include INC_SUBARCH(mm.h)
|
#include INC_SUBARCH(mm.h)
|
||||||
#include INC_SUBARCH(mmu_ops.h)
|
#include INC_SUBARCH(mmu_ops.h)
|
||||||
@@ -30,7 +31,7 @@
|
|||||||
*/
|
*/
|
||||||
void remove_section_mapping(unsigned long vaddr)
|
void remove_section_mapping(unsigned long vaddr)
|
||||||
{
|
{
|
||||||
pgd_table_t *pgd = TASK_PGD(current);
|
pgd_table_t *pgd = &init_pgd;;
|
||||||
pgd_t pgd_i = PGD_INDEX(vaddr);
|
pgd_t pgd_i = PGD_INDEX(vaddr);
|
||||||
if (!((pgd->entry[pgd_i] & PGD_TYPE_MASK)
|
if (!((pgd->entry[pgd_i] & PGD_TYPE_MASK)
|
||||||
& PGD_TYPE_SECTION))
|
& PGD_TYPE_SECTION))
|
||||||
@@ -55,7 +56,7 @@ void __add_section_mapping_init(unsigned int paddr,
|
|||||||
unsigned int l1_offset;
|
unsigned int l1_offset;
|
||||||
|
|
||||||
/* 1st level page table address */
|
/* 1st level page table address */
|
||||||
l1_ptab = virt_to_phys(&kspace);
|
l1_ptab = virt_to_phys(&init_pgd);
|
||||||
|
|
||||||
/* Get the section offset for this vaddr */
|
/* Get the section offset for this vaddr */
|
||||||
l1_offset = (vaddr >> 18) & 0x3FFC;
|
l1_offset = (vaddr >> 18) & 0x3FFC;
|
||||||
@@ -199,6 +200,51 @@ void attach_pmd(pgd_table_t *pgd, pmd_table_t *pmd, unsigned int vaddr)
|
|||||||
pgd->entry[pgd_i] |= PGD_TYPE_COARSE;
|
pgd->entry[pgd_i] |= PGD_TYPE_COARSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Same as normal mapping but with some boot tweaks.
|
||||||
|
*/
|
||||||
|
void add_boot_mapping(unsigned int paddr, unsigned int vaddr,
|
||||||
|
unsigned int size, unsigned int flags)
|
||||||
|
{
|
||||||
|
pmd_table_t *pmd;
|
||||||
|
pgd_table_t *pgd = &init_pgd;
|
||||||
|
unsigned int numpages = (size >> PAGE_BITS);
|
||||||
|
|
||||||
|
if (size < PAGE_SIZE) {
|
||||||
|
printascii("Error: Mapping size must be in bytes not pages.\n");
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
if (size & PAGE_MASK)
|
||||||
|
numpages++;
|
||||||
|
|
||||||
|
/* Convert generic map flags to pagetable-specific */
|
||||||
|
BUG_ON(!(flags = space_flags_to_ptflags(flags)));
|
||||||
|
|
||||||
|
/* Map all consecutive pages that cover given size */
|
||||||
|
for (int i = 0; i < numpages; i++) {
|
||||||
|
/* Check if another mapping already has a pmd attached. */
|
||||||
|
pmd = pmd_exists(pgd, vaddr);
|
||||||
|
if (!pmd) {
|
||||||
|
/*
|
||||||
|
* If this is the first vaddr in
|
||||||
|
* this pmd, allocate new pmd
|
||||||
|
*/
|
||||||
|
pmd = alloc_boot_pmd();
|
||||||
|
|
||||||
|
/* Attach pmd to its entry in pgd */
|
||||||
|
attach_pmd(pgd, pmd, vaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attach paddr to this pmd */
|
||||||
|
__add_mapping(page_align(paddr),
|
||||||
|
page_align(vaddr), flags, pmd);
|
||||||
|
|
||||||
|
/* Go to the next page to be mapped */
|
||||||
|
paddr += PAGE_SIZE;
|
||||||
|
vaddr += PAGE_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Maps @paddr to @vaddr, covering @size bytes also allocates new pmd if
|
* Maps @paddr to @vaddr, covering @size bytes also allocates new pmd if
|
||||||
* necessary. This flavor explicitly supplies the pgd to modify. This is useful
|
* necessary. This flavor explicitly supplies the pgd to modify. This is useful
|
||||||
@@ -212,6 +258,7 @@ void add_mapping_pgd(unsigned int paddr, unsigned int vaddr,
|
|||||||
pmd_table_t *pmd;
|
pmd_table_t *pmd;
|
||||||
unsigned int numpages = (size >> PAGE_BITS);
|
unsigned int numpages = (size >> PAGE_BITS);
|
||||||
|
|
||||||
|
|
||||||
if (size < PAGE_SIZE) {
|
if (size < PAGE_SIZE) {
|
||||||
printascii("Error: Mapping size must be in bytes not pages.\n");
|
printascii("Error: Mapping size must be in bytes not pages.\n");
|
||||||
while(1);
|
while(1);
|
||||||
@@ -553,6 +600,7 @@ out_error:
|
|||||||
|
|
||||||
extern pmd_table_t *pmd_array;
|
extern pmd_table_t *pmd_array;
|
||||||
|
|
||||||
|
#if 0
|
||||||
/*
|
/*
|
||||||
* Moves the section mapped kspace that resides far apart from kernel as close
|
* Moves the section mapped kspace that resides far apart from kernel as close
|
||||||
* as possible to the kernel image, and unmaps the old 1MB kspace section which
|
* as possible to the kernel image, and unmaps the old 1MB kspace section which
|
||||||
@@ -611,6 +659,7 @@ void relocate_page_tables(void)
|
|||||||
__KERNELNAME__, virt_to_phys(&kspace),
|
__KERNELNAME__, virt_to_phys(&kspace),
|
||||||
virt_to_phys(TASK_PGD(current)));
|
virt_to_phys(TASK_PGD(current)));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Useful for upgrading to page-grained control over a section mapping:
|
* Useful for upgrading to page-grained control over a section mapping:
|
||||||
@@ -629,18 +678,14 @@ void remap_as_pages(void *vstart, void *vend)
|
|||||||
pgd_table_t *pgd = (pgd_table_t *)TASK_PGD(current);
|
pgd_table_t *pgd = (pgd_table_t *)TASK_PGD(current);
|
||||||
pmd_table_t *pmd = alloc_pmd();
|
pmd_table_t *pmd = alloc_pmd();
|
||||||
u32 pmd_phys = virt_to_phys(pmd);
|
u32 pmd_phys = virt_to_phys(pmd);
|
||||||
int numpages = __pfn(page_align_up(pend) - pstart);
|
int numpages = __pfn(pend - pstart);
|
||||||
|
|
||||||
BUG_ON((unsigned long)vstart & ARM_SECTION_MASK);
|
|
||||||
BUG_ON(pmd_i);
|
|
||||||
|
|
||||||
/* Fill in the pmd first */
|
/* Fill in the pmd first */
|
||||||
while (pmd_i < numpages) {
|
for (int n = 0; n < numpages; n++) {
|
||||||
pmd->entry[pmd_i] = paddr;
|
pmd->entry[pmd_i + n] = paddr;
|
||||||
pmd->entry[pmd_i] |= PMD_TYPE_SMALL; /* Small page type */
|
pmd->entry[pmd_i + n] |= PMD_TYPE_SMALL; /* Small page type */
|
||||||
pmd->entry[pmd_i] |= space_flags_to_ptflags(MAP_SVC_DEFAULT_FLAGS);
|
pmd->entry[pmd_i + n] |= space_flags_to_ptflags(MAP_SVC_DEFAULT_FLAGS);
|
||||||
paddr += PAGE_SIZE;
|
paddr += PAGE_SIZE;
|
||||||
pmd_i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill in the type to produce a complete pmd translator information */
|
/* Fill in the type to produce a complete pmd translator information */
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
Import('env')
|
Import('env')
|
||||||
|
|
||||||
# The set of source files associated with this SConscript file.
|
# The set of source files associated with this SConscript file.
|
||||||
src_local = ['physmem.c', 'irq.c', 'scheduler.c', 'time.c', 'tcb.c', 'pgalloc.c', 'kmalloc.c', 'space.c']
|
src_local = ['physmem.c', 'irq.c', 'scheduler.c', 'time.c', 'tcb.c', 'pgalloc.c', 'kmalloc.c', 'space.c', 'bootm.c']
|
||||||
|
|
||||||
obj = env.Object(src_local)
|
obj = env.Object(src_local)
|
||||||
Return('obj')
|
Return('obj')
|
||||||
|
|||||||
52
src/generic/bootm.c
Normal file
52
src/generic/bootm.c
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Boot memory allocator
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Bahadir Balban
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include INC_ARCH(linker.h)
|
||||||
|
#include INC_GLUE(memory.h)
|
||||||
|
#include <l4/lib/printk.h>
|
||||||
|
|
||||||
|
/* All memory allocated here is discarded after boot */
|
||||||
|
|
||||||
|
#define BOOTMEM_SIZE SZ_32K
|
||||||
|
|
||||||
|
SECTION(".init.pgd") pgd_table_t init_pgd;
|
||||||
|
SECTION(".init.bootmem") char bootmem[BOOTMEM_SIZE];
|
||||||
|
|
||||||
|
static unsigned long cursor = (unsigned long)&bootmem;
|
||||||
|
|
||||||
|
void *alloc_bootmem(int size, int alignment)
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
/* If alignment is required */
|
||||||
|
if (alignment) {
|
||||||
|
/* And cursor is not aligned */
|
||||||
|
if (!is_aligned(cursor, alignment))
|
||||||
|
/* Align the cursor to alignment */
|
||||||
|
cursor = align_up(cursor, alignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate from cursor */
|
||||||
|
ptr = (void *)cursor;
|
||||||
|
|
||||||
|
/* Update cursor */
|
||||||
|
cursor += size;
|
||||||
|
|
||||||
|
/* Check if cursor is passed bootmem area */
|
||||||
|
if (cursor >= (unsigned long)&bootmem[BOOTMEM_SIZE]) {
|
||||||
|
printk("Fatal: Insufficient boot memory.\n");
|
||||||
|
BUG();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
pmd_table_t *alloc_boot_pmd(void)
|
||||||
|
{
|
||||||
|
return alloc_bootmem(sizeof(pmd_table_t), sizeof(pmd_table_t));
|
||||||
|
}
|
||||||
|
|
||||||
56
src/generic/kresource.c
Normal file
56
src/generic/kresource.c
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Initialize system resource management.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Bahadir Balban
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Here are the steps used to initialize system resources:
|
||||||
|
*
|
||||||
|
* Check total physical memory
|
||||||
|
* Check container memory capabilities
|
||||||
|
* Find biggest unused physical memory region
|
||||||
|
* Calculate how much memory is used by all containers
|
||||||
|
* Initialize a slab-like allocator for all resources.
|
||||||
|
* Copy boot allocations to real allocations accounted to containers and kernel.
|
||||||
|
* E.g. initial page table may become page table of a container pager.
|
||||||
|
* First few pmds used belong to kernel usage, etc.
|
||||||
|
* Delete all boot memory and add it to physical memory pool.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MEM_FLAGS_VIRTUAL (1 << 0)
|
||||||
|
#define MEM_AREA_CACHED (1 << 1)
|
||||||
|
|
||||||
|
struct mem_area {
|
||||||
|
struct link list;
|
||||||
|
l4id_t mid;
|
||||||
|
unsigned long start;
|
||||||
|
unsigned long end;
|
||||||
|
unsigned long npages;
|
||||||
|
unsigned long flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void init_system_resources()
|
||||||
|
{
|
||||||
|
struct mem_area *physmem = alloc_bootmem(sizeof(physmem), 4);
|
||||||
|
struct mem_area *kernel_used = alloc_bootmem(sizeof(physmem), 4);
|
||||||
|
|
||||||
|
/* Initialize the first memory descriptor for total physical memory */
|
||||||
|
physmem.start = PHYS_MEM_START;
|
||||||
|
physmem.end = PHYS_MEM_END;
|
||||||
|
physmem.mid = 0;
|
||||||
|
physmem.npages = (physmem.end - physmem.start) >> PAGE_BITS;
|
||||||
|
|
||||||
|
/* Figure out current kernel usage */
|
||||||
|
kernel_used.start = virt_to_phys(_kernel_start);
|
||||||
|
kernel_used.end = virt_to_phys(_kernel_end);
|
||||||
|
|
||||||
|
/* Figure out each container's physical memory usage */
|
||||||
|
for (int i = 0; i < containers->total; i++) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -152,12 +152,7 @@ void *alloc_page(void)
|
|||||||
|
|
||||||
void *alloc_pmd(void)
|
void *alloc_pmd(void)
|
||||||
{
|
{
|
||||||
pmd_table_t *pmd;
|
return pgalloc_from_cache(PGALLOC_PMD_CACHE);
|
||||||
|
|
||||||
if (!(pmd = alloc_boot_pmd()))
|
|
||||||
pmd = pgalloc_from_cache(PGALLOC_PMD_CACHE);
|
|
||||||
|
|
||||||
return pmd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *alloc_pgd(void)
|
void *alloc_pgd(void)
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <l4/generic/scheduler.h>
|
#include <l4/generic/scheduler.h>
|
||||||
#include <l4/generic/space.h>
|
#include <l4/generic/space.h>
|
||||||
#include <l4/generic/tcb.h>
|
#include <l4/generic/tcb.h>
|
||||||
|
#include <l4/generic/bootmem.h>
|
||||||
#include INC_ARCH(linker.h)
|
#include INC_ARCH(linker.h)
|
||||||
#include INC_ARCH(asm.h)
|
#include INC_ARCH(asm.h)
|
||||||
#include INC_ARCH(bootdesc.h)
|
#include INC_ARCH(bootdesc.h)
|
||||||
@@ -30,27 +31,22 @@
|
|||||||
|
|
||||||
unsigned int kernel_mapping_end;
|
unsigned int kernel_mapping_end;
|
||||||
|
|
||||||
void init_locks(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
struct address_space pager_space;
|
|
||||||
|
|
||||||
/* Maps the early memory regions needed to bootstrap the system */
|
/* Maps the early memory regions needed to bootstrap the system */
|
||||||
void init_kernel_mappings(void)
|
void init_kernel_mappings(void)
|
||||||
{
|
{
|
||||||
init_clear_ptab();
|
memset(&init_pgd, 0, sizeof(pgd_table_t));
|
||||||
|
|
||||||
/* Map kernel area to its virtual region */
|
/* Map kernel area to its virtual region */
|
||||||
add_section_mapping_init(virt_to_phys(_start_text),
|
add_section_mapping_init(align(virt_to_phys(_start_text),SZ_1MB),
|
||||||
(unsigned int)_start_text, 1,
|
align((unsigned int)_start_text, SZ_1MB), 1,
|
||||||
cacheable | bufferable);
|
cacheable | bufferable);
|
||||||
|
|
||||||
/* Map kernel one-to-one to its physical region */
|
/* Map kernel one-to-one to its physical region */
|
||||||
add_section_mapping_init(virt_to_phys(_start_text),
|
add_section_mapping_init(align(virt_to_phys(_start_text),SZ_1MB),
|
||||||
virt_to_phys(_start_text),
|
align(virt_to_phys(_start_text),SZ_1MB),
|
||||||
1, 0);
|
1, 0);
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* Map page table to its virtual region */
|
/* Map page table to its virtual region */
|
||||||
add_section_mapping_init(virt_to_phys(_start_kspace),
|
add_section_mapping_init(virt_to_phys(_start_kspace),
|
||||||
(unsigned int)_start_kspace,
|
(unsigned int)_start_kspace,
|
||||||
@@ -67,7 +63,8 @@ void init_kernel_mappings(void)
|
|||||||
current->space = &pager_space;
|
current->space = &pager_space;
|
||||||
|
|
||||||
/* Access physical address of pager_space to assign with initial pgd */
|
/* Access physical address of pager_space to assign with initial pgd */
|
||||||
((struct address_space *)virt_to_phys(current->space))->pgd = &kspace;
|
((struct address_space *)virt_to_phys(current->space))->pgd = &init_pgd;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_sections(void)
|
void print_sections(void)
|
||||||
@@ -83,11 +80,9 @@ void print_sections(void)
|
|||||||
dprintk("_start_kip: ", (unsigned int) _start_kip);
|
dprintk("_start_kip: ", (unsigned int) _start_kip);
|
||||||
dprintk("_end_kip: ", (unsigned int) _end_kip);
|
dprintk("_end_kip: ", (unsigned int) _end_kip);
|
||||||
dprintk("_bootstack: ", (unsigned int)_bootstack);
|
dprintk("_bootstack: ", (unsigned int)_bootstack);
|
||||||
dprintk("_end_kernel: ", (unsigned int)_end_kernel);
|
dprintk("_end_kernel: ", (unsigned int)_end_kernel);
|
||||||
dprintk("_start_kspace: ", (unsigned int)_start_kspace);
|
dprintk("_start_init: ", (unsigned int)_start_init);
|
||||||
dprintk("_start_pmd: ", (unsigned int)_start_pmd);
|
dprintk("_end_init: ", (unsigned int)_end_init);
|
||||||
dprintk("_end_pmd: ", (unsigned int)_end_pmd);
|
|
||||||
dprintk("_end_kspace: ", (unsigned int)_end_kspace);
|
|
||||||
dprintk("_end: ", (unsigned int)_end);
|
dprintk("_end: ", (unsigned int)_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,11 +96,11 @@ void start_vm()
|
|||||||
* TTB must be 16K aligned. This is because first level tables are
|
* TTB must be 16K aligned. This is because first level tables are
|
||||||
* sized 16K.
|
* sized 16K.
|
||||||
*/
|
*/
|
||||||
if ((unsigned int)&kspace & 0x3FFF)
|
if ((unsigned int)&init_pgd & 0x3FFF)
|
||||||
dprintk("kspace not properly aligned for ttb:",
|
dprintk("kspace not properly aligned for ttb:",
|
||||||
(u32)&kspace);
|
(u32)&init_pgd);
|
||||||
memset((void *)&kspace, 0, sizeof(pgd_table_t));
|
// memset((void *)&kspace, 0, sizeof(pgd_table_t));
|
||||||
arm_set_ttb(virt_to_phys(&kspace));
|
arm_set_ttb(virt_to_phys(&init_pgd));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This sets all 16 domains to zero and domain 0 to 1. The outcome
|
* This sets all 16 domains to zero and domain 0 to 1. The outcome
|
||||||
@@ -208,8 +203,8 @@ void vectors_init()
|
|||||||
unsigned int size = ((u32)_end_vectors - (u32)arm_high_vector);
|
unsigned int size = ((u32)_end_vectors - (u32)arm_high_vector);
|
||||||
|
|
||||||
/* Map the vectors in high vector page */
|
/* Map the vectors in high vector page */
|
||||||
add_mapping(virt_to_phys(arm_high_vector),
|
add_boot_mapping(virt_to_phys(arm_high_vector),
|
||||||
ARM_HIGH_VECTOR, size, 0);
|
ARM_HIGH_VECTOR, size, 0);
|
||||||
arm_enable_high_vectors();
|
arm_enable_high_vectors();
|
||||||
|
|
||||||
/* Kernel memory trapping is enabled at this point. */
|
/* Kernel memory trapping is enabled at this point. */
|
||||||
@@ -361,8 +356,9 @@ void init_tasks()
|
|||||||
void start_kernel(void)
|
void start_kernel(void)
|
||||||
{
|
{
|
||||||
printascii("\n"__KERNELNAME__": start kernel...\n");
|
printascii("\n"__KERNELNAME__": start kernel...\n");
|
||||||
|
|
||||||
/* Print section boundaries for kernel image */
|
/* Print section boundaries for kernel image */
|
||||||
//print_sections();
|
print_sections();
|
||||||
|
|
||||||
/* Initialise section mappings for the kernel area */
|
/* Initialise section mappings for the kernel area */
|
||||||
init_kernel_mappings();
|
init_kernel_mappings();
|
||||||
@@ -370,9 +366,6 @@ void start_kernel(void)
|
|||||||
/* Enable virtual memory and jump to virtual addresses */
|
/* Enable virtual memory and jump to virtual addresses */
|
||||||
start_vm();
|
start_vm();
|
||||||
|
|
||||||
/* PMD tables initialised */
|
|
||||||
init_pmd_tables();
|
|
||||||
|
|
||||||
/* Initialise platform-specific page mappings, and peripherals */
|
/* Initialise platform-specific page mappings, and peripherals */
|
||||||
platform_init();
|
platform_init();
|
||||||
|
|
||||||
@@ -382,10 +375,13 @@ void start_kernel(void)
|
|||||||
vectors_init();
|
vectors_init();
|
||||||
|
|
||||||
/* Remap 1MB kernel sections as 4Kb pages. */
|
/* Remap 1MB kernel sections as 4Kb pages. */
|
||||||
remap_as_pages(_start_kernel, _end_kernel);
|
// remap_as_pages((void *)page_align(_start_kernel), (void *)page_align_up(_end));
|
||||||
|
|
||||||
/* Move the initial pgd into a more convenient place, mapped as pages. */
|
/* Move the initial pgd into a more convenient place, mapped as pages. */
|
||||||
relocate_page_tables();
|
// relocate_page_tables();
|
||||||
|
|
||||||
|
/* Evaluate system resources and set up resource pools */
|
||||||
|
init_system_resources();
|
||||||
|
|
||||||
/* Initialise memory allocators */
|
/* Initialise memory allocators */
|
||||||
paging_init();
|
paging_init();
|
||||||
@@ -396,9 +392,6 @@ void start_kernel(void)
|
|||||||
/* Initialise system call page */
|
/* Initialise system call page */
|
||||||
syscall_init();
|
syscall_init();
|
||||||
|
|
||||||
/* Initialise everything else, e.g. locks, lists... */
|
|
||||||
init_locks();
|
|
||||||
|
|
||||||
/* Setup inittask's ktcb and push it to scheduler runqueue */
|
/* Setup inittask's ktcb and push it to scheduler runqueue */
|
||||||
init_tasks();
|
init_tasks();
|
||||||
|
|
||||||
|
|||||||
@@ -39,48 +39,6 @@ unsigned int space_flags_to_ptflags(unsigned int flags)
|
|||||||
BUG(); return 0;
|
BUG(); return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define NUM_PMD_TABLES 7
|
|
||||||
//#define NUM_PGD_TABLES 8
|
|
||||||
|
|
||||||
/* Initial first level page table to provide startup mappings */
|
|
||||||
SECTION(".kspace.pgd") pgd_table_t kspace;
|
|
||||||
SECTION(".kspace.pmd") pmd_table_t pmd_tables[NUM_PMD_TABLES];
|
|
||||||
|
|
||||||
/* A mini bitmap for boot pmd allocations */
|
|
||||||
static int pmd_cnt;
|
|
||||||
pmd_table_t *pmd_array;
|
|
||||||
|
|
||||||
pmd_table_t *alloc_boot_pmd(void)
|
|
||||||
{
|
|
||||||
pmd_table_t *pt;
|
|
||||||
|
|
||||||
if (pmd_cnt == NUM_PMD_TABLES)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
pt = &pmd_array[pmd_cnt++];
|
|
||||||
BUG_ON((unsigned long)pt & (sizeof(pmd_table_t) - 1));
|
|
||||||
|
|
||||||
return pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialises pmd allocation cache, this is called before page allocator
|
|
||||||
* initialises. After this call one can add page mappings via add_mapping().
|
|
||||||
* This also sets the alloc_pmd() global function to this boot-time version.
|
|
||||||
*/
|
|
||||||
void init_pmd_tables(void)
|
|
||||||
{
|
|
||||||
pmd_cnt = 0;
|
|
||||||
pmd_array = pmd_tables;
|
|
||||||
memset(pmd_array, 0, NUM_PMD_TABLES * sizeof(pmd_table_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clears out all entries in the initial page table */
|
|
||||||
void init_clear_ptab(void)
|
|
||||||
{
|
|
||||||
memset((void *)virt_to_phys(&kspace), 0, sizeof(pgd_table_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sets up struct page array and the physical memory descriptor. */
|
/* Sets up struct page array and the physical memory descriptor. */
|
||||||
void paging_init(void)
|
void paging_init(void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
* PB926 platform-specific initialisation and setup
|
* PB926 platform-specific initialisation and setup
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007 Bahadir Balban
|
* Copyright (C) 2007 Bahadir Balban
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <l4/generic/platform.h>
|
#include <l4/generic/platform.h>
|
||||||
@@ -22,7 +21,7 @@
|
|||||||
|
|
||||||
void init_platform_console(void)
|
void init_platform_console(void)
|
||||||
{
|
{
|
||||||
add_mapping(PB926_UART0_BASE, PL011_BASE, PAGE_SIZE,
|
add_boot_mapping(PB926_UART0_BASE, PL011_BASE, PAGE_SIZE,
|
||||||
MAP_IO_DEFAULT_FLAGS);
|
MAP_IO_DEFAULT_FLAGS);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -30,7 +29,7 @@ void init_platform_console(void)
|
|||||||
* userspace printf can work. Note, this raw mapping is to be
|
* userspace printf can work. Note, this raw mapping is to be
|
||||||
* removed in the future, when file-based io is implemented.
|
* removed in the future, when file-based io is implemented.
|
||||||
*/
|
*/
|
||||||
add_mapping(PB926_UART0_BASE, USERSPACE_UART_BASE, PAGE_SIZE,
|
add_boot_mapping(PB926_UART0_BASE, USERSPACE_UART_BASE, PAGE_SIZE,
|
||||||
MAP_USR_IO_FLAGS);
|
MAP_USR_IO_FLAGS);
|
||||||
|
|
||||||
uart_init();
|
uart_init();
|
||||||
@@ -38,18 +37,18 @@ void init_platform_console(void)
|
|||||||
|
|
||||||
void init_platform_timer(void)
|
void init_platform_timer(void)
|
||||||
{
|
{
|
||||||
add_mapping(PB926_TIMER01_BASE, PLATFORM_TIMER_BASE, PAGE_SIZE,
|
add_boot_mapping(PB926_TIMER01_BASE, PLATFORM_TIMER_BASE, PAGE_SIZE,
|
||||||
MAP_IO_DEFAULT_FLAGS);
|
MAP_IO_DEFAULT_FLAGS);
|
||||||
add_mapping(PB926_SYSCTRL_BASE, PB926_SYSCTRL_VBASE, PAGE_SIZE,
|
add_boot_mapping(PB926_SYSCTRL_BASE, PB926_SYSCTRL_VBASE, PAGE_SIZE,
|
||||||
MAP_IO_DEFAULT_FLAGS);
|
MAP_IO_DEFAULT_FLAGS);
|
||||||
timer_init();
|
timer_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_platform_irq_controller()
|
void init_platform_irq_controller()
|
||||||
{
|
{
|
||||||
add_mapping(PB926_VIC_BASE, PLATFORM_IRQCTRL_BASE, PAGE_SIZE,
|
add_boot_mapping(PB926_VIC_BASE, PLATFORM_IRQCTRL_BASE, PAGE_SIZE,
|
||||||
MAP_IO_DEFAULT_FLAGS);
|
MAP_IO_DEFAULT_FLAGS);
|
||||||
add_mapping(PB926_SIC_BASE, PLATFORM_SIRQCTRL_BASE, PAGE_SIZE,
|
add_boot_mapping(PB926_SIC_BASE, PLATFORM_SIRQCTRL_BASE, PAGE_SIZE,
|
||||||
MAP_IO_DEFAULT_FLAGS);
|
MAP_IO_DEFAULT_FLAGS);
|
||||||
irq_controllers_init();
|
irq_controllers_init();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ BEGIN_PROC(printhex4)
|
|||||||
BEGIN_PROC(printhex2)
|
BEGIN_PROC(printhex2)
|
||||||
mov r1, #2
|
mov r1, #2
|
||||||
printhex: adr r2, hexbuf
|
printhex: adr r2, hexbuf
|
||||||
|
@printhex: ldr r2, =hexbuf
|
||||||
add r3, r2, r1
|
add r3, r2, r1
|
||||||
mov r1, #0
|
mov r1, #0
|
||||||
strb r1, [r3]
|
strb r1, [r3]
|
||||||
@@ -77,8 +78,9 @@ printhex: adr r2, hexbuf
|
|||||||
.macro get_straddr rs, rm
|
.macro get_straddr rs, rm
|
||||||
mrc p15, 0, \rm, c1, c0 @ Get MMU bits.
|
mrc p15, 0, \rm, c1, c0 @ Get MMU bits.
|
||||||
tst \rm, #1 @ MMU enabled?
|
tst \rm, #1 @ MMU enabled?
|
||||||
|
@subeq \rs, \rs, #KERNEL_AREA_START
|
||||||
biceq \rs, \rs, #KERNEL_AREA_START @ Clear Virtual mem offset.
|
biceq \rs, \rs, #KERNEL_AREA_START @ Clear Virtual mem offset.
|
||||||
orreq \rs, \rs, #PHYS_ADDR_BASE @ Add Phy mem offset.
|
@orreq \rs, \rs, #PHYS_ADDR_BASE @ Add Phy mem offset.
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
BEGIN_PROC(printascii)
|
BEGIN_PROC(printascii)
|
||||||
|
|||||||
Reference in New Issue
Block a user