mirror of
https://github.com/drasko/codezero.git
synced 2026-01-12 02:43:15 +01:00
Changes in merged posix pager mm0 initialization.
- Moved rootfs from being embedded to mm0 image to being an independent image. - MM0 boots up to start_init_process with updated boot convention.
This commit is contained in:
@@ -56,6 +56,7 @@ def configure_kernel(cml_file):
|
||||
cml2_update_config_h(CONFIG_H, config)
|
||||
|
||||
configuration_save(config)
|
||||
#config.config_print()
|
||||
|
||||
# Generate bare container files if new ones defined
|
||||
bare_cont_gen = BareContGenerator()
|
||||
|
||||
@@ -70,13 +70,17 @@ mm0 = SConscript('mm0/SConscript', \
|
||||
exports = { 'config' : config, 'env' : mm0_env, 'contid' : contid }, duplicate = 0, \
|
||||
variant_dir = join(BUILDDIR, 'cont' + str(contid) + '/posix' + '/mm0'))
|
||||
|
||||
rootfs = SConscript('rootfs/SConscript', \
|
||||
exports = { 'config' : config, 'environment' : env, 'contid' : contid, 'previmage' : mm0 }, duplicate = 0, \
|
||||
variant_dir = join(BUILDDIR, 'cont' + str(contid) + '/posix' + '/rootfs'))
|
||||
|
||||
test0_env = env.Clone()
|
||||
test0_env.Replace(CPPPATH = ['include', KERNEL_INCLUDE, LIBL4_INCLUDE, LIBMEM_INCLUDE])
|
||||
test0 = SConscript('test0/SConscript', \
|
||||
exports = { 'config' : config, 'environment' : test0_env, 'contid' : contid, 'previmage' : mm0 }, duplicate = 0, \
|
||||
exports = { 'config' : config, 'environment' : test0_env, 'contid' : contid, 'previmage' : rootfs }, duplicate = 0, \
|
||||
variant_dir = join(BUILDDIR, 'cont' + str(contid) + '/posix' + '/test0'))
|
||||
|
||||
images = [mm0, test0]
|
||||
images = [mm0, rootfs, test0]
|
||||
bootdesc_env = env.Clone()
|
||||
bootdesc_env['bootdesc_dir'] = 'bootdesc'
|
||||
|
||||
@@ -87,11 +91,13 @@ bootdesc = SConscript('bootdesc/SConscript', \
|
||||
|
||||
Depends(mm0, libposix)
|
||||
Depends(test0, libposix)
|
||||
Depends(bootdesc, [test0, mm0])
|
||||
Depends(rootfs, mm0)
|
||||
Depends(test0, rootfs)
|
||||
Depends(bootdesc, [test0, mm0, rootfs])
|
||||
|
||||
Alias('libposix', libposix)
|
||||
Alias('mm0', mm0)
|
||||
Alias('test0', test0)
|
||||
Alias('bootdesc', bootdesc)
|
||||
|
||||
Alias('rootfs', rootfs)
|
||||
Default([mm0, libposix, test0, bootdesc])
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
#
|
||||
# User space application build script
|
||||
#
|
||||
# Copyright (C) 2007 Bahadir Balban
|
||||
#
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
from string import split
|
||||
from os.path import join
|
||||
from glob import glob
|
||||
|
||||
task_name = "mm0"
|
||||
|
||||
# The root directory of the repository where this file resides:
|
||||
project_root = "../.."
|
||||
tools_root = join(project_root, "tools")
|
||||
prev_image = join(project_root, "build/start.axf")
|
||||
libs_path = join(project_root, "libs")
|
||||
ld_script = "include/linker.lds"
|
||||
physical_base_ld_script = "include/physical_base.lds"
|
||||
|
||||
# libc paths:
|
||||
libc_variant = "userspace"
|
||||
libc_libpath = join(libs_path, "c/build/%s" % libc_variant)
|
||||
libc_incpath = join(libc_libpath, "include")
|
||||
libc_crt0 = join(libs_path, "c/build/crt/sys-userspace/arch-arm/crt0.o")
|
||||
libc_name = "c-%s" % libc_variant
|
||||
|
||||
# libl4 paths:
|
||||
libl4_path = "../libl4"
|
||||
libl4_incpath = join(libl4_path, "include")
|
||||
|
||||
# libposix paths:
|
||||
libposix_path = "../libposix"
|
||||
libposix_incpath = join(libposix_path, "include")
|
||||
|
||||
#libmem paths:
|
||||
libmem_path = "../libmem"
|
||||
libmem_incpath = "../libmem"
|
||||
|
||||
# kernel paths:
|
||||
kernel_incpath = join(project_root, "include")
|
||||
|
||||
# Kernel config header.
|
||||
config_h = join(project_root, "include/l4/config.h")
|
||||
|
||||
|
||||
# If crt0 is in its library path, it becomes hard to link with it.
|
||||
# For instance the linker script must use an absolute path for it.
|
||||
def copy_crt0(source, target, env):
|
||||
os.system("cp " + str(source[0]) + " " + str(target[0]))
|
||||
|
||||
def get_physical_base(source, target, env):
|
||||
os.system(join(tools_root, "pyelf/readelf.py --first-free-page " + \
|
||||
prev_image +" >> " + physical_base_ld_script))
|
||||
|
||||
# The kernel build environment:
|
||||
env = Environment(CC = 'arm-none-linux-gnueabi-gcc',
|
||||
# We don't use -nostdinc because sometimes we need standard headers,
|
||||
# such as stdarg.h e.g. for variable args, as in printk().
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror' ],
|
||||
LINKFLAGS = ['-nostdlib', '-T' + ld_script, "-L" + libc_libpath, "-L" + libl4_path, \
|
||||
"-L" + libposix_path, "-L" + libmem_path],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
PROGSUFFIX = '.axf', # The suffix to use for final executable
|
||||
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
|
||||
LIBS = [libc_name, 'libl4', 'libmm', 'libmc', 'libkm', 'libposix', \
|
||||
'gcc', libc_name], # libgcc.a - This is required for division routines.
|
||||
CPPFLAGS = "-D__USERSPACE__",
|
||||
CPPPATH = ['#include', libl4_incpath, libc_incpath, kernel_incpath, \
|
||||
libmem_incpath, libposix_incpath])
|
||||
|
||||
|
||||
def create_symlinks(arch):
|
||||
arch_path = "include/arch"
|
||||
arch_path2 ="src/arch"
|
||||
if os.path.exists(arch_path):
|
||||
os.system("rm %s" % (arch_path))
|
||||
os.system("ln -s %s %s" % ("arch-" + arch, arch_path))
|
||||
if os.path.exists(arch_path2):
|
||||
os.system("rm %s" % (arch_path2))
|
||||
os.system("ln -s %s %s" % ("arch-" + arch, arch_path2))
|
||||
|
||||
arch, subarch, plat = extract_arch_subarch_plat(config_h)
|
||||
|
||||
create_symlinks(arch) # Creates symlinks to architecture specific directories.
|
||||
|
||||
src = [glob("src/*.c"), glob("src/lib/*.c"), glob("src/lib/elf/*.c"), glob("*.c"), glob("src/arch/*.c")]
|
||||
objs = env.Object(src)
|
||||
physical_base = env.Command(physical_base_ld_script, prev_image, get_physical_base)
|
||||
crt0_copied = env.Command("crt0.o", libc_crt0, copy_crt0)
|
||||
|
||||
task = env.Program(task_name, objs + [crt0_copied])
|
||||
env.Alias(task_name, task)
|
||||
env.Depends(task, physical_base)
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
/*
|
||||
* This is just to allocate some memory as a block device.
|
||||
*/
|
||||
#include <init.h>
|
||||
#include <l4/macros.h>
|
||||
#include <bootdesc.h>
|
||||
#include <memfs/memfs.h>
|
||||
|
||||
extern char _start_bdev[];
|
||||
extern char _end_bdev[];
|
||||
|
||||
__attribute__((section(".data.memfs"))) char blockdevice[MEMFS_TOTAL_SIZE];
|
||||
#include <l4lib/arch/syslib.h>
|
||||
|
||||
void *vfs_rootdev_open(void)
|
||||
{
|
||||
return (void *)_start_bdev;
|
||||
struct svc_image *rootfs_img = bootdesc_get_image_byname("rootfs");
|
||||
unsigned long rootfs_size = rootfs_img->phys_end - rootfs_img->phys_start;
|
||||
|
||||
BUG_ON(rootfs_size < MEMFS_TOTAL_SIZE);
|
||||
|
||||
/* Map filesystem blocks to virtual memory */
|
||||
return l4_map_helper((void *)rootfs_img->phys_start, __pfn(rootfs_size));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FS0 Initialisation.
|
||||
* Filesystem initialisation.
|
||||
*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*/
|
||||
@@ -51,7 +51,7 @@ void vfs_register_filesystems(void)
|
||||
/*
|
||||
* Filesystem initialisation.
|
||||
*/
|
||||
int initialise(void)
|
||||
int vfs_init(void)
|
||||
{
|
||||
void *rootdev_blocks;
|
||||
struct superblock *root_sb;
|
||||
@@ -79,10 +79,6 @@ int initialise(void)
|
||||
|
||||
printf("%s: Mounted memfs root filesystem.\n", __TASKNAME__);
|
||||
|
||||
/*
|
||||
* Initialisation is done. From here on, we can start
|
||||
* serving filesystem requests.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@ struct bootdesc {
|
||||
struct svc_image images[];
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct initdata;
|
||||
void read_bootdesc(struct initdata *initdata);
|
||||
|
||||
void read_boot_params();
|
||||
struct svc_image *bootdesc_get_image_byname(char *);
|
||||
|
||||
#endif /* __BOOTDESC_H__ */
|
||||
|
||||
@@ -38,7 +38,7 @@ struct capability {
|
||||
extern struct cap_list capability_list;
|
||||
|
||||
struct initdata;
|
||||
int read_kernel_capabilities(struct initdata *);
|
||||
void copy_boot_capabilities(struct initdata *initdata);
|
||||
int read_pager_capabilities();
|
||||
void copy_boot_capabilities();
|
||||
|
||||
#endif /* __MM0_CAPABILITY_H__ */
|
||||
|
||||
@@ -29,7 +29,7 @@ struct initdata {
|
||||
|
||||
extern struct initdata initdata;
|
||||
|
||||
void init_pager(void);
|
||||
void init(void);
|
||||
|
||||
/* TODO: Remove this stuff from here. */
|
||||
int init_devzero(void);
|
||||
|
||||
@@ -31,13 +31,7 @@ SECTIONS
|
||||
/* rodata is needed else your strings will link at physical! */
|
||||
.rodata : AT (ADDR(.rodata) - pager_offset) { *(.rodata) }
|
||||
.rodata1 : AT (ADDR(.rodata1) - pager_offset) { *(.rodata1) }
|
||||
.data : AT (ADDR(.data) - pager_offset)
|
||||
{
|
||||
*(.data)
|
||||
_start_bdev = .;
|
||||
*(.data.memfs)
|
||||
_end_bdev = .;
|
||||
}
|
||||
.data : AT (ADDR(.data) - pager_offset) { *(.data) }
|
||||
.bss : AT (ADDR(.bss) - pager_offset) { *(.bss) }
|
||||
. = ALIGN(4K);
|
||||
. += 0x2000; /* BSS doesnt increment link counter??? */
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
void init_mm_descriptors(struct page_bitmap *page_map,
|
||||
struct bootdesc *bootdesc, struct membank *membank);
|
||||
void init_physmem(struct initdata *initdata, struct membank *membank);
|
||||
void init_physmem(void);
|
||||
|
||||
int pager_address_pool_init(void);
|
||||
void *pager_new_address(int npages);
|
||||
|
||||
@@ -31,15 +31,13 @@ struct membank {
|
||||
extern struct membank membank[];
|
||||
|
||||
/* Describes bitmap of used/unused state for all physical pages */
|
||||
extern struct page_bitmap page_map;
|
||||
extern struct memdesc physmem;
|
||||
|
||||
/* Sets the global page map as used/unused. Aligns input when needed. */
|
||||
int set_page_map(struct page_bitmap *pmap, unsigned long start,
|
||||
int numpages, int val);
|
||||
|
||||
struct initdata;
|
||||
void init_physmem_primary(struct initdata *initdata);
|
||||
void init_physmem_secondary(struct initdata *initdata, struct membank *membank);
|
||||
void init_physmem_primary();
|
||||
void init_physmem_secondary(struct membank *membank);
|
||||
|
||||
#endif /* __PAGER_PHYSMEM_H__ */
|
||||
|
||||
@@ -87,4 +87,6 @@ struct vnode *generic_vnode_lookup(struct vnode *thisnode, struct pathdata *p,
|
||||
struct vnode *vfs_lookup_bypath(struct pathdata *p);
|
||||
struct vnode *vfs_lookup_byvnum(struct superblock *sb, unsigned long vnum);
|
||||
|
||||
int vfs_init(void);
|
||||
|
||||
#endif /* __VFS_H__ */
|
||||
|
||||
@@ -153,10 +153,6 @@ void handle_requests(void)
|
||||
else
|
||||
return; /* else we're done */
|
||||
}
|
||||
case L4_IPC_TAG_BRK: {
|
||||
// ret = sys_brk(sender, (void *)mr[0]);
|
||||
// break;
|
||||
}
|
||||
|
||||
/* FIXME: Fix all these syscalls to read any buffer data from the caller task's utcb. */
|
||||
/* FS0 System calls */
|
||||
@@ -189,86 +185,11 @@ void handle_requests(void)
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Executes the given function in a new thread in the current
|
||||
* address space but on a brand new stack.
|
||||
*/
|
||||
int self_spawn(void)
|
||||
{
|
||||
struct task_ids ids;
|
||||
struct tcb *self, *self_child;
|
||||
unsigned long stack, stack_size;
|
||||
|
||||
BUG_ON(!(self = find_task(self_tid())));
|
||||
|
||||
ids.tid = TASK_ID_INVALID;
|
||||
ids.spid = self->spid;
|
||||
ids.tgid = self->tgid;
|
||||
|
||||
/* Create a new L4 thread in current thread's address space. */
|
||||
self_child = task_create(self, &ids, THREAD_SAME_SPACE,
|
||||
TCB_SHARED_VM | TCB_SHARED_FILES);
|
||||
|
||||
if (IS_ERR(self_child = tcb_alloc_init(TCB_SHARED_VM
|
||||
| TCB_SHARED_FILES)))
|
||||
BUG();
|
||||
|
||||
/*
|
||||
* Create a new utcb. Every pager thread will
|
||||
* need its own utcb to answer calls.
|
||||
*/
|
||||
self_child->utcb = utcb_vaddr_new();
|
||||
|
||||
/* Map utcb to child */
|
||||
task_map_prefault_utcb(self_child, self_child);
|
||||
|
||||
/*
|
||||
* Set up a child stack by mmapping an anonymous region.
|
||||
*/
|
||||
stack_size = self->stack_end - self->stack_start;
|
||||
if (IS_ERR(stack = do_mmap(0, 0, self, 0,
|
||||
VM_READ | VM_WRITE | VMA_ANONYMOUS
|
||||
| VMA_PRIVATE | VMA_GROWSDOWN,
|
||||
__pfn(stack_size)))) {
|
||||
printf("%s: Error spawning %s, Error code: %d\n",
|
||||
__FUNCTION__, __TASKNAME__, (int)stack);
|
||||
BUG();
|
||||
}
|
||||
|
||||
/* Modify stack marker of child tcb */
|
||||
self_child->stack_end = stack;
|
||||
self_child->stack_start = stack - stack_size;
|
||||
|
||||
/* Prefault child stack */
|
||||
for (int i = 0; i < __pfn(stack_size); i++)
|
||||
prefault_page(self_child,
|
||||
self_child->stack_start + __pfn_to_addr(i),
|
||||
VM_READ | VM_WRITE);
|
||||
|
||||
/* Copy current stack to child */
|
||||
memcpy((void *)self_child->stack_start,
|
||||
(void *)self->stack_start, stack_size);
|
||||
|
||||
/* TODO: Modify registers ???, it depends on what state is copied in C0 */
|
||||
|
||||
/* TODO: Notify vfs ??? */
|
||||
|
||||
task_add_global(self_child);
|
||||
|
||||
if (l4_thread_control(THREAD_CREATE | THREAD_CREATE_SAMESPC, ids)
|
||||
l4_thread_control(THREAD_RUN, &ids);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void main(void)
|
||||
{
|
||||
printf("\n%s: Started with thread id %d\n", __TASKNAME__, self_tid());
|
||||
|
||||
/* Initialise the memory, server tasks, mmap and start them. */
|
||||
init_pager();
|
||||
init();
|
||||
|
||||
printf("%s: Memory/Process manager initialized. Listening requests.\n", __TASKNAME__);
|
||||
while (1) {
|
||||
|
||||
@@ -12,7 +12,15 @@
|
||||
extern unsigned long _end[];
|
||||
extern unsigned long pager_offset;
|
||||
|
||||
void read_bootdesc(struct initdata *initdata)
|
||||
struct svc_image *bootdesc_get_image_byname(char *name)
|
||||
{
|
||||
for (int i = 0; i < initdata.bootdesc->total_images; i++)
|
||||
if (!strncmp(initdata.bootdesc->images[i].name, name, strlen(name)))
|
||||
return &initdata.bootdesc->images[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
void read_boot_params()
|
||||
{
|
||||
int npages;
|
||||
struct bootdesc *bootdesc;
|
||||
@@ -24,16 +32,15 @@ void read_bootdesc(struct initdata *initdata)
|
||||
|
||||
/* Check if bootdesc is on an unmapped page */
|
||||
if (is_page_aligned(bootdesc))
|
||||
l4_map_helper(bootdesc - pager_offset, PAGE_SIZE);
|
||||
l4_map_helper(bootdesc - pager_offset, 1);
|
||||
|
||||
/* Allocate bootdesc sized structure */
|
||||
initdata->bootdesc = alloc_bootmem(bootdesc->desc_size, 0);
|
||||
initdata.bootdesc = alloc_bootmem(bootdesc->desc_size, 0);
|
||||
|
||||
/* Copy bootdesc to initdata */
|
||||
memcpy(initdata->bootdesc, bootdesc,
|
||||
memcpy(initdata.bootdesc, bootdesc,
|
||||
bootdesc->desc_size);
|
||||
|
||||
if (npages > 0)
|
||||
l4_unmap_helper((void *)page_align_up(_end),
|
||||
PAGE_SIZE * npages);
|
||||
l4_unmap_helper((void *)page_align_up(_end), npages);
|
||||
}
|
||||
|
||||
@@ -12,74 +12,3 @@
|
||||
#include <l4/generic/cap-types.h> /* TODO: Move this to API */
|
||||
#include <lib/malloc.h>
|
||||
|
||||
struct cap_list capability_list;
|
||||
|
||||
__initdata static struct capability *caparray;
|
||||
__initdata static int total_caps = 0;
|
||||
|
||||
/* Copy all init-memory allocated capabilities */
|
||||
void copy_boot_capabilities(struct initdata *initdata)
|
||||
{
|
||||
struct capability *cap;
|
||||
|
||||
for (int i = 0; i < total_caps; i++) {
|
||||
cap = kzalloc(sizeof(struct capability));
|
||||
|
||||
/* This copies kernel-allocated unique cap id as well */
|
||||
memcpy(cap, &caparray[i], sizeof(struct capability));
|
||||
|
||||
/* Initialize capability list */
|
||||
link_init(&cap->list);
|
||||
|
||||
/* Add capability to global cap list */
|
||||
list_insert(&capability_list.caps, &cap->list);
|
||||
}
|
||||
}
|
||||
|
||||
int read_kernel_capabilities(struct initdata *initdata)
|
||||
{
|
||||
int ncaps;
|
||||
int err;
|
||||
|
||||
/* Read number of capabilities */
|
||||
if ((err = l4_capability_control(CAP_CONTROL_NCAPS, 0, &ncaps)) < 0) {
|
||||
printf("l4_capability_control() reading # of capabilities failed.\n"
|
||||
"Could not complete CAP_CONTROL_NCAPS request.\n");
|
||||
goto error;
|
||||
}
|
||||
total_caps = ncaps;
|
||||
|
||||
/* Allocate array of caps from boot memory */
|
||||
caparray = alloc_bootmem(sizeof(struct capability) * ncaps, 0);
|
||||
|
||||
/* Read all capabilities */
|
||||
if ((err = l4_capability_control(CAP_CONTROL_READ_CAPS, 0, caparray)) < 0) {
|
||||
printf("l4_capability_control() reading of capabilities failed.\n"
|
||||
"Could not complete CAP_CONTROL_READ_CAPS request.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Set up initdata pointer to important capabilities */
|
||||
initdata->bootcaps = caparray;
|
||||
for (int i = 0; i < ncaps; i++) {
|
||||
/*
|
||||
* TODO: There may be multiple physmem caps!
|
||||
* This really needs to be considered as multiple
|
||||
* membanks!!!
|
||||
*/
|
||||
if ((caparray[i].type & CAP_RTYPE_MASK)
|
||||
== CAP_RTYPE_PHYSMEM) {
|
||||
initdata->physmem = &caparray[i];
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
printf("%s: Error, pager has no physmem capability defined.\n",
|
||||
__TASKNAME__);
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
BUG();
|
||||
}
|
||||
|
||||
|
||||
@@ -589,8 +589,6 @@ int vfs_write(unsigned long vnum, unsigned long file_offset,
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Writes updated file stats back to vfs. (e.g. new file size) */
|
||||
int vfs_update_file_stats(struct vm_file *f)
|
||||
{
|
||||
|
||||
@@ -3,15 +3,20 @@
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Bahadir Balban
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <memory.h>
|
||||
#include <mm/alloc_page.h>
|
||||
#include <lib/malloc.h>
|
||||
#include <lib/bit.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/utcb.h>
|
||||
|
||||
#include <l4/lib/list.h>
|
||||
#include <l4/generic/cap-types.h> /* TODO: Move this to API */
|
||||
#include <l4/api/capability.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <mm/alloc_page.h>
|
||||
#include <lib/malloc.h>
|
||||
#include <lib/bit.h>
|
||||
|
||||
#include <task.h>
|
||||
#include <shm.h>
|
||||
#include <file.h>
|
||||
@@ -21,22 +26,30 @@
|
||||
#include <utcb.h>
|
||||
#include <bootm.h>
|
||||
#include <vfs.h>
|
||||
#include <init.h>
|
||||
#include <memory.h>
|
||||
#include <capability.h>
|
||||
|
||||
/* A separate list than the generic file list that keeps just the boot files */
|
||||
LINK_DECLARE(boot_file_list);
|
||||
|
||||
extern unsigned long _start_init[];
|
||||
extern unsigned long _end_init[];
|
||||
|
||||
/* Kernel data acquired during initialisation */
|
||||
__initdata struct initdata initdata;
|
||||
|
||||
void print_bootdesc(struct bootdesc *bd)
|
||||
{
|
||||
for (int i = 0; i < bd->total_images; i++) {
|
||||
printf("Task Image: %d\n", i);
|
||||
printf("Name: %s\n", bd->images[i].name);
|
||||
printf("Start: 0x%x\n", bd->images[i].phys_start);
|
||||
printf("End: 0x%x\n", bd->images[i].phys_end);
|
||||
}
|
||||
}
|
||||
|
||||
/* Physical memory descriptors */
|
||||
struct memdesc physmem; /* Initial, primitive memory descriptor */
|
||||
struct membank membank[1]; /* The memory bank */
|
||||
struct page *page_array; /* The physical page array based on mem bank */
|
||||
|
||||
|
||||
/* Capability descriptor list */
|
||||
struct cap_list capability_list;
|
||||
|
||||
__initdata static struct capability *caparray;
|
||||
__initdata static int total_caps = 0;
|
||||
|
||||
|
||||
void print_pfn_range(int pfn, int size)
|
||||
{
|
||||
@@ -45,36 +58,6 @@ void print_pfn_range(int pfn, int size)
|
||||
printf("Used: 0x%x - 0x%x\n", addr, end);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void print_page_map(struct page_bitmap *map)
|
||||
{
|
||||
unsigned int start_pfn = 0;
|
||||
unsigned int total_used = 0;
|
||||
int numpages = 0;
|
||||
|
||||
// printf("Page map: 0x%x-0x%x\n", map->pfn_start << PAGE_BITS, map->pfn_end << PAGE_BITS);
|
||||
for (int i = 0; i < (PHYSMEM_TOTAL_PAGES >> 5); i++) {
|
||||
for (int x = 0; x < WORD_BITS; x++) {
|
||||
if (map->map[i] & (1 << x)) { /* A used page found? */
|
||||
if (!start_pfn) /* First such page found? */
|
||||
start_pfn = (WORD_BITS * i) + x;
|
||||
total_used++;
|
||||
numpages++; /* Increase number of pages */
|
||||
} else { /* Either used pages ended or were never found */
|
||||
if (start_pfn) { /* We had a used page */
|
||||
/* Finished end of used range.
|
||||
* Print and reset. */
|
||||
//print_pfn_range(start_pfn, numpages);
|
||||
start_pfn = 0;
|
||||
numpages = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("%s: Pagemap: Total of %d used physical pages. %d Kbytes used.\n", __TASKNAME__, total_used, total_used << 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* A specialised function for setting up the task environment of mm0.
|
||||
* Essentially all the memory regions are set up but a new task isn't
|
||||
@@ -133,115 +116,83 @@ int mm0_task_init(struct vm_file *f, unsigned long task_start,
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct vm_file *initdata_next_bootfile(struct initdata *initdata)
|
||||
/* Copy all init-memory allocated capabilities */
|
||||
void copy_boot_capabilities()
|
||||
{
|
||||
struct vm_file *file, *n;
|
||||
list_foreach_removable_struct(file, n,
|
||||
&initdata->boot_file_list,
|
||||
list) {
|
||||
list_remove_init(&file->list);
|
||||
return file;
|
||||
struct capability *cap;
|
||||
|
||||
for (int i = 0; i < total_caps; i++) {
|
||||
cap = kzalloc(sizeof(struct capability));
|
||||
|
||||
/* This copies kernel-allocated unique cap id as well */
|
||||
memcpy(cap, &caparray[i], sizeof(struct capability));
|
||||
|
||||
/* Initialize capability list */
|
||||
link_init(&cap->list);
|
||||
|
||||
/* Add capability to global cap list */
|
||||
list_insert(&capability_list.caps, &cap->list);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reads boot files from init data, determines their task ids if they
|
||||
* match with particular servers, and starts the tasks.
|
||||
*/
|
||||
int start_boot_tasks(struct initdata *initdata)
|
||||
int read_pager_capabilities()
|
||||
{
|
||||
struct vm_file *file = 0, *fs0_file = 0, *mm0_file = 0, *n;
|
||||
struct tcb *fs0_task;
|
||||
struct svc_image *img;
|
||||
struct task_ids ids;
|
||||
struct link other_files;
|
||||
int total = 0;
|
||||
int ncaps;
|
||||
int err;
|
||||
|
||||
link_init(&other_files);
|
||||
/* Read number of capabilities */
|
||||
if ((err = l4_capability_control(CAP_CONTROL_NCAPS, 0, &ncaps)) < 0) {
|
||||
printf("l4_capability_control() reading # of capabilities failed.\n"
|
||||
"Could not complete CAP_CONTROL_NCAPS request.\n");
|
||||
goto error;
|
||||
}
|
||||
total_caps = ncaps;
|
||||
|
||||
/* Separate out special server tasks and regular files */
|
||||
do {
|
||||
file = initdata_next_bootfile(initdata);
|
||||
/* Allocate array of caps from boot memory */
|
||||
caparray = alloc_bootmem(sizeof(struct capability) * ncaps, 0);
|
||||
|
||||
if (file) {
|
||||
BUG_ON(file->type != VM_FILE_BOOTFILE);
|
||||
img = file->priv_data;
|
||||
if (img->name[0] == 'm' &&
|
||||
img->name[1] == 'm' &&
|
||||
img->name[2] == '0')
|
||||
mm0_file = file;
|
||||
else if (img->name[0] == 'f' &&
|
||||
img->name[1] == 's' &&
|
||||
img->name[2] == '0')
|
||||
fs0_file = file;
|
||||
else
|
||||
list_insert(&file->list, &other_files);
|
||||
} else
|
||||
break;
|
||||
} while (1);
|
||||
|
||||
if (!mm0_file || !fs0_file) {
|
||||
printf("%s: FATAL: Could not find images for %s, and/or %s\n",
|
||||
__PAGERNAME__, __PAGERNAME__, __VFSNAME__);
|
||||
BUG();
|
||||
/* Read all capabilities */
|
||||
if ((err = l4_capability_control(CAP_CONTROL_READ_CAPS, 0, caparray)) < 0) {
|
||||
printf("l4_capability_control() reading of capabilities failed.\n"
|
||||
"Could not complete CAP_CONTROL_READ_CAPS request.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* MM0 needs partial initialisation since it's already running. */
|
||||
// printf("%s: Initialising mm0 tcb.\n", __TASKNAME__);
|
||||
ids.tid = PAGER_TID;
|
||||
ids.spid = PAGER_TID;
|
||||
ids.tgid = PAGER_TID;
|
||||
|
||||
if (mm0_task_init(mm0_file, INITTASK_AREA_START,
|
||||
INITTASK_AREA_END, &ids) < 0)
|
||||
BUG();
|
||||
total++;
|
||||
|
||||
/* Initialise vfs with its predefined id */
|
||||
ids.tid = VFS_TID;
|
||||
ids.spid = VFS_TID;
|
||||
ids.tgid = VFS_TID;
|
||||
|
||||
// printf("%s: Initialising fs0\n",__TASKNAME__);
|
||||
BUG_ON((IS_ERR(fs0_task = boottask_exec(fs0_file, USER_AREA_START,
|
||||
USER_AREA_END, &ids))));
|
||||
total++;
|
||||
|
||||
/* Initialise other tasks */
|
||||
list_foreach_removable_struct(file, n, &other_files, list) {
|
||||
ids.tid = TASK_ID_INVALID;
|
||||
ids.spid = TASK_ID_INVALID;
|
||||
ids.tgid = TASK_ID_INVALID;
|
||||
list_remove_init(&file->list);
|
||||
BUG_ON(IS_ERR(boottask_exec(file, USER_AREA_START,
|
||||
USER_AREA_END, &ids)));
|
||||
total++;
|
||||
}
|
||||
|
||||
if (!total) {
|
||||
printf("%s: Could not start any tasks.\n",
|
||||
__TASKNAME__);
|
||||
BUG();
|
||||
/* Set up initdata pointer to important capabilities */
|
||||
initdata.bootcaps = caparray;
|
||||
for (int i = 0; i < ncaps; i++) {
|
||||
/*
|
||||
* TODO: There may be multiple physmem caps!
|
||||
* This really needs to be considered as multiple
|
||||
* membanks!!!
|
||||
*/
|
||||
if ((caparray[i].type & CAP_RTYPE_MASK)
|
||||
== CAP_RTYPE_PHYSMEM) {
|
||||
initdata.physmem = &caparray[i];
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
printf("%s: Error, pager has no physmem capability defined.\n",
|
||||
__TASKNAME__);
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern unsigned long _start_init[];
|
||||
extern unsigned long _end_init[];
|
||||
error:
|
||||
BUG();
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy all necessary data from initmem to real memory,
|
||||
* release initdata and any init memory used
|
||||
*/
|
||||
void copy_release_initdata(struct initdata *initdata)
|
||||
void release_initdata()
|
||||
{
|
||||
/*
|
||||
* Copy boot capabilities to a list of
|
||||
* real capabilities
|
||||
*/
|
||||
copy_boot_capabilities(initdata);
|
||||
copy_boot_capabilities();
|
||||
|
||||
/* Free and unmap init memory:
|
||||
*
|
||||
@@ -255,48 +206,215 @@ void copy_release_initdata(struct initdata *initdata)
|
||||
self_tid());
|
||||
}
|
||||
|
||||
|
||||
void init_mm(struct initdata *initdata)
|
||||
static void init_page_map(struct page_bitmap *pmap, unsigned long pfn_start, unsigned long pfn_end)
|
||||
{
|
||||
/* Initialise the page and bank descriptors */
|
||||
init_physmem_primary(initdata);
|
||||
pmap->pfn_start = pfn_start;
|
||||
pmap->pfn_end = pfn_end;
|
||||
set_page_map(pmap, pfn_start, pfn_end - pfn_start, 0);
|
||||
}
|
||||
|
||||
init_physmem_secondary(initdata, membank);
|
||||
/*
|
||||
* Marks pages in the global page_map as used or unused.
|
||||
*
|
||||
* @start = start page address to set, inclusive.
|
||||
* @numpages = number of pages to set.
|
||||
*/
|
||||
int set_page_map(struct page_bitmap *page_map, unsigned long pfn_start,
|
||||
int numpages, int val)
|
||||
{
|
||||
unsigned long pfn_end = pfn_start + numpages;
|
||||
unsigned long pfn_err = 0;
|
||||
|
||||
/* Initialise the page allocator on first bank. */
|
||||
init_page_allocator(membank[0].free, membank[0].end);
|
||||
|
||||
/* Initialise the zero page */
|
||||
init_devzero();
|
||||
|
||||
/* Initialise in-memory boot files */
|
||||
init_boot_files(initdata);
|
||||
|
||||
if (shm_pool_init() < 0) {
|
||||
printf("SHM initialisation failed.\n");
|
||||
BUG();
|
||||
if (page_map->pfn_start > pfn_start || page_map->pfn_end < pfn_start) {
|
||||
pfn_err = pfn_start;
|
||||
goto error;
|
||||
}
|
||||
if (page_map->pfn_end < pfn_end || page_map->pfn_start > pfn_end) {
|
||||
pfn_err = pfn_end;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (utcb_pool_init() < 0) {
|
||||
printf("SHM initialisation failed.\n");
|
||||
BUG();
|
||||
if (val)
|
||||
for (int i = pfn_start; i < pfn_end; i++)
|
||||
page_map->map[BITWISE_GETWORD(i)] |= BITWISE_GETBIT(i);
|
||||
else
|
||||
for (int i = pfn_start; i < pfn_end; i++)
|
||||
page_map->map[BITWISE_GETWORD(i)] &= ~BITWISE_GETBIT(i);
|
||||
return 0;
|
||||
error:
|
||||
BUG_MSG("Given page area is out of system page_map range: 0x%lx\n",
|
||||
pfn_err << PAGE_BITS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Allocates page descriptors and initialises them using page_map information */
|
||||
void init_physmem_secondary(struct membank *membank)
|
||||
{
|
||||
struct page_bitmap *pmap = initdata.page_map;
|
||||
int npages = pmap->pfn_end - pmap->pfn_start;
|
||||
|
||||
/* Allocation marks for the struct page array; npages, start, end */
|
||||
int pg_npages, pg_spfn, pg_epfn;
|
||||
unsigned long ffree_addr;
|
||||
|
||||
/*
|
||||
* Means the page array won't map one to one to pfns. That's ok,
|
||||
* but we dont allow it for now.
|
||||
*/
|
||||
// BUG_ON(pmap->pfn_start);
|
||||
|
||||
membank[0].start = __pfn_to_addr(pmap->pfn_start);
|
||||
membank[0].end = __pfn_to_addr(pmap->pfn_end);
|
||||
|
||||
/* First find the first free page after last used page */
|
||||
for (int i = 0; i < npages; i++)
|
||||
if ((pmap->map[BITWISE_GETWORD(i)] & BITWISE_GETBIT(i)))
|
||||
membank[0].free = (i + 1) * PAGE_SIZE;
|
||||
BUG_ON(membank[0].free >= membank[0].end);
|
||||
|
||||
/*
|
||||
* One struct page for every physical page. Calculate how many pages
|
||||
* needed for page structs, start and end pfn marks.
|
||||
*/
|
||||
pg_npages = __pfn(page_align_up((sizeof(struct page) * npages)));
|
||||
|
||||
/* These are relative pfn offsets to the start of the memory bank */
|
||||
|
||||
/* FIXME:
|
||||
* 1.) These values were only right when membank started from pfn 0.
|
||||
* 2.) Use set_page_map to set page map below instead of manually.
|
||||
*/
|
||||
pg_spfn = __pfn(membank[0].free);
|
||||
pg_epfn = pg_spfn + pg_npages;
|
||||
|
||||
/* Use free pages from the bank as the space for struct page array */
|
||||
membank[0].page_array = l4_map_helper((void *)membank[0].free,
|
||||
pg_npages);
|
||||
/* Update free memory left */
|
||||
membank[0].free += pg_npages * PAGE_SIZE;
|
||||
|
||||
/* Update page bitmap for the pages used for the page array */
|
||||
for (int i = pg_spfn; i < pg_epfn; i++)
|
||||
pmap->map[BITWISE_GETWORD(i)] |= BITWISE_GETBIT(i);
|
||||
|
||||
/* Initialise the page array */
|
||||
for (int i = 0; i < npages; i++) {
|
||||
link_init(&membank[0].page_array[i].list);
|
||||
|
||||
/* Set use counts for pages the kernel has already used up */
|
||||
if (!(pmap->map[BITWISE_GETWORD(i)] & BITWISE_GETBIT(i)))
|
||||
membank[0].page_array[i].refcnt = -1;
|
||||
else /* Last page used +1 is free */
|
||||
ffree_addr = (i + 1) * PAGE_SIZE;
|
||||
}
|
||||
|
||||
/* First free address must come up the same for both */
|
||||
BUG_ON(ffree_addr != membank[0].free);
|
||||
|
||||
/* Set global page array to this bank's array */
|
||||
page_array = membank[0].page_array;
|
||||
|
||||
/* Test that page/phys macros work */
|
||||
BUG_ON(phys_to_page(page_to_phys(&page_array[5])) != &page_array[5])
|
||||
}
|
||||
|
||||
|
||||
void init_pager(void)
|
||||
/* Fills in the physmem structure with free physical memory information */
|
||||
void init_physmem_primary()
|
||||
{
|
||||
unsigned long pfn_start, pfn_end, pfn_images_end = 0;
|
||||
struct bootdesc *bootdesc = initdata.bootdesc;
|
||||
|
||||
/* Allocate page map structure */
|
||||
initdata.page_map = alloc_bootmem(sizeof(struct page_bitmap) +
|
||||
((initdata.physmem->end -
|
||||
initdata.physmem->start)
|
||||
>> 5) + 1, 0);
|
||||
|
||||
/* Initialise page map from physmem capability */
|
||||
init_page_map(initdata.page_map,
|
||||
initdata.physmem->start,
|
||||
initdata.physmem->end);
|
||||
|
||||
/* Mark pager and other boot task areas as used */
|
||||
for (int i = 0; i < bootdesc->total_images; i++) {
|
||||
pfn_start =
|
||||
__pfn(page_align_up(bootdesc->images[i].phys_start));
|
||||
pfn_end = __pfn(page_align_up(bootdesc->images[i].phys_end));
|
||||
if (pfn_end > pfn_images_end)
|
||||
pfn_images_end = pfn_end;
|
||||
set_page_map(initdata.page_map, pfn_start,
|
||||
pfn_end - pfn_start, 1);
|
||||
}
|
||||
|
||||
physmem.start = initdata.physmem->start;
|
||||
physmem.end = initdata.physmem->end;
|
||||
|
||||
physmem.free_cur = pfn_images_end;
|
||||
physmem.free_end = physmem.end;
|
||||
physmem.numpages = __pfn(physmem.end - physmem.start);
|
||||
}
|
||||
|
||||
void init_physmem(void)
|
||||
{
|
||||
init_physmem_primary();
|
||||
|
||||
init_physmem_secondary(membank);
|
||||
|
||||
init_page_allocator(membank[0].free, membank[0].end);
|
||||
}
|
||||
|
||||
void init_execve(char *path)
|
||||
{
|
||||
/*
|
||||
* Find executable, and execute it by creating a new process
|
||||
* rather than replacing the current image (which is the pager!)
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* To be removed later: This file copies in-memory elf image to the
|
||||
* initialized and formatted in-memory memfs filesystem.
|
||||
*/
|
||||
void copy_init_process(void)
|
||||
{
|
||||
//int fd = sys_open(find_task(self_tid()), "/test0", O_WRITE, 0)
|
||||
|
||||
//sys_write(find_task(self_tid()), fd, __test0_start, __test0_end - __test0_start);
|
||||
|
||||
//sys_close(find_task(self_tid()), fd);
|
||||
|
||||
}
|
||||
|
||||
void start_init_process(void)
|
||||
{
|
||||
/* Copy raw test0 elf image from memory to memfs first */
|
||||
copy_init_process();
|
||||
|
||||
init_execve("/test0");
|
||||
}
|
||||
|
||||
void init(void)
|
||||
{
|
||||
read_pager_capabilities();
|
||||
|
||||
pager_address_pool_init();
|
||||
|
||||
read_kernel_capabilities(&initdata);
|
||||
read_boot_params();
|
||||
|
||||
read_bootdesc(&initdata);
|
||||
init_physmem();
|
||||
|
||||
init_mm(&initdata);
|
||||
init_devzero();
|
||||
|
||||
start_boot_tasks(&initdata);
|
||||
shm_pool_init();
|
||||
|
||||
copy_release_initdata(&initdata);
|
||||
utcb_pool_init();
|
||||
|
||||
vfs_init();
|
||||
|
||||
start_init_process();
|
||||
|
||||
release_initdata();
|
||||
|
||||
mm0_test_global_vm_integrity();
|
||||
}
|
||||
|
||||
@@ -19,157 +19,4 @@
|
||||
#include <physmem.h>
|
||||
#include <bootm.h>
|
||||
|
||||
struct memdesc physmem; /* Initial, primitive memory descriptor */
|
||||
struct membank membank[1]; /* The memory bank */
|
||||
struct page *page_array; /* The physical page array based on mem bank */
|
||||
|
||||
|
||||
static void init_page_map(struct page_bitmap *pmap, unsigned long pfn_start, unsigned long pfn_end)
|
||||
{
|
||||
pmap->pfn_start = pfn_start;
|
||||
pmap->pfn_end = pfn_end;
|
||||
set_page_map(pmap, pfn_start, pfn_end - pfn_start, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Marks pages in the global page_map as used or unused.
|
||||
*
|
||||
* @start = start page address to set, inclusive.
|
||||
* @numpages = number of pages to set.
|
||||
*/
|
||||
int set_page_map(struct page_bitmap *page_map, unsigned long pfn_start,
|
||||
int numpages, int val)
|
||||
{
|
||||
unsigned long pfn_end = pfn_start + numpages;
|
||||
unsigned long pfn_err = 0;
|
||||
|
||||
if (page_map->pfn_start > pfn_start || page_map->pfn_end < pfn_start) {
|
||||
pfn_err = pfn_start;
|
||||
goto error;
|
||||
}
|
||||
if (page_map->pfn_end < pfn_end || page_map->pfn_start > pfn_end) {
|
||||
pfn_err = pfn_end;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (val)
|
||||
for (int i = pfn_start; i < pfn_end; i++)
|
||||
page_map->map[BITWISE_GETWORD(i)] |= BITWISE_GETBIT(i);
|
||||
else
|
||||
for (int i = pfn_start; i < pfn_end; i++)
|
||||
page_map->map[BITWISE_GETWORD(i)] &= ~BITWISE_GETBIT(i);
|
||||
return 0;
|
||||
error:
|
||||
BUG_MSG("Given page area is out of system page_map range: 0x%lx\n",
|
||||
pfn_err << PAGE_BITS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Allocates page descriptors and initialises them using page_map information */
|
||||
void init_physmem_secondary(struct initdata *initdata, struct membank *membank)
|
||||
{
|
||||
struct page_bitmap *pmap = initdata->page_map;
|
||||
int npages = pmap->pfn_end - pmap->pfn_start;
|
||||
|
||||
/* Allocation marks for the struct page array; npages, start, end */
|
||||
int pg_npages, pg_spfn, pg_epfn;
|
||||
unsigned long ffree_addr;
|
||||
|
||||
/*
|
||||
* Means the page array won't map one to one to pfns. That's ok,
|
||||
* but we dont allow it for now.
|
||||
*/
|
||||
// BUG_ON(pmap->pfn_start);
|
||||
|
||||
membank[0].start = __pfn_to_addr(pmap->pfn_start);
|
||||
membank[0].end = __pfn_to_addr(pmap->pfn_end);
|
||||
|
||||
/* First find the first free page after last used page */
|
||||
for (int i = 0; i < npages; i++)
|
||||
if ((pmap->map[BITWISE_GETWORD(i)] & BITWISE_GETBIT(i)))
|
||||
membank[0].free = (i + 1) * PAGE_SIZE;
|
||||
BUG_ON(membank[0].free >= membank[0].end);
|
||||
|
||||
/*
|
||||
* One struct page for every physical page. Calculate how many pages
|
||||
* needed for page structs, start and end pfn marks.
|
||||
*/
|
||||
pg_npages = __pfn(page_align_up((sizeof(struct page) * npages)));
|
||||
|
||||
/* These are relative pfn offsets to the start of the memory bank */
|
||||
|
||||
/* FIXME:
|
||||
* 1.) These values were only right when membank started from pfn 0.
|
||||
* 2.) Use set_page_map to set page map below instead of manually.
|
||||
*/
|
||||
pg_spfn = __pfn(membank[0].free);
|
||||
pg_epfn = pg_spfn + pg_npages;
|
||||
|
||||
/* Use free pages from the bank as the space for struct page array */
|
||||
membank[0].page_array = l4_map_helper((void *)membank[0].free,
|
||||
pg_npages);
|
||||
/* Update free memory left */
|
||||
membank[0].free += pg_npages * PAGE_SIZE;
|
||||
|
||||
/* Update page bitmap for the pages used for the page array */
|
||||
for (int i = pg_spfn; i < pg_epfn; i++)
|
||||
pmap->map[BITWISE_GETWORD(i)] |= BITWISE_GETBIT(i);
|
||||
|
||||
/* Initialise the page array */
|
||||
for (int i = 0; i < npages; i++) {
|
||||
link_init(&membank[0].page_array[i].list);
|
||||
|
||||
/* Set use counts for pages the kernel has already used up */
|
||||
if (!(pmap->map[BITWISE_GETWORD(i)] & BITWISE_GETBIT(i)))
|
||||
membank[0].page_array[i].refcnt = -1;
|
||||
else /* Last page used +1 is free */
|
||||
ffree_addr = (i + 1) * PAGE_SIZE;
|
||||
}
|
||||
|
||||
/* First free address must come up the same for both */
|
||||
BUG_ON(ffree_addr != membank[0].free);
|
||||
|
||||
/* Set global page array to this bank's array */
|
||||
page_array = membank[0].page_array;
|
||||
|
||||
/* Test that page/phys macros work */
|
||||
BUG_ON(phys_to_page(page_to_phys(&page_array[5])) != &page_array[5])
|
||||
}
|
||||
|
||||
|
||||
/* Fills in the physmem structure with free physical memory information */
|
||||
void init_physmem_primary(struct initdata *initdata)
|
||||
{
|
||||
unsigned long pfn_start, pfn_end, pfn_images_end = 0;
|
||||
struct bootdesc *bootdesc = initdata->bootdesc;
|
||||
|
||||
/* Allocate page map structure */
|
||||
initdata->page_map = alloc_bootmem(sizeof(struct page_bitmap) +
|
||||
((initdata->physmem->end -
|
||||
initdata->physmem->start)
|
||||
>> 5) + 1, 0);
|
||||
|
||||
/* Initialise page map from physmem capability */
|
||||
init_page_map(initdata->page_map,
|
||||
initdata->physmem->start,
|
||||
initdata->physmem->end);
|
||||
|
||||
/* Mark pager and other boot task areas as used */
|
||||
for (int i = 0; i < bootdesc->total_images; i++) {
|
||||
pfn_start =
|
||||
__pfn(page_align_up(bootdesc->images[i].phys_start));
|
||||
pfn_end = __pfn(page_align_up(bootdesc->images[i].phys_end));
|
||||
if (pfn_end > pfn_images_end)
|
||||
pfn_images_end = pfn_end;
|
||||
set_page_map(initdata->page_map, pfn_start,
|
||||
pfn_end - pfn_start, 1);
|
||||
}
|
||||
|
||||
physmem.start = initdata->physmem->start;
|
||||
physmem.end = initdata->physmem->end;
|
||||
|
||||
physmem.free_cur = pfn_images_end;
|
||||
physmem.free_end = physmem.end;
|
||||
physmem.numpages = __pfn(physmem.end - physmem.start);
|
||||
}
|
||||
|
||||
|
||||
46
conts/posix/rootfs/SConscript
Normal file
46
conts/posix/rootfs/SConscript
Normal file
@@ -0,0 +1,46 @@
|
||||
# -*- mode: python; coding: utf-8; -*-
|
||||
|
||||
# Codezero -- a microkernel for embedded systems.
|
||||
#
|
||||
# Copyright © 2009 B Labs Ltd
|
||||
|
||||
import os.path
|
||||
import sys, subprocess, shutil
|
||||
from os.path import *
|
||||
|
||||
Import('config', 'environment', 'previmage')
|
||||
|
||||
e = environment.Clone()
|
||||
|
||||
sys.path.append('../../../')
|
||||
|
||||
from config.projpaths import *
|
||||
from config.configuration import *
|
||||
from tools.pyelf.lmanext import *
|
||||
|
||||
rootfs_lds_in = \
|
||||
'''
|
||||
/*
|
||||
* Linker script that embeds an empty root filesystem.
|
||||
* This is to be replaced by a real rootfs image later.
|
||||
*/
|
||||
SECTIONS
|
||||
{
|
||||
. = %s;
|
||||
.bss : { *(.bss) }
|
||||
}
|
||||
'''
|
||||
|
||||
def generate_rootfs_lds(target, source, env):
|
||||
with open(source[1].path, 'r') as lds_in:
|
||||
with open(target[0].path, 'w+') as lds_out:
|
||||
linker_script = lds_in.read()
|
||||
lds_out.write(linker_script % next_available_lma(source[0].path))
|
||||
|
||||
rootfs_lds = e.Command('rootfs.lds', [previmage, 'rootfs.lds.in'], generate_rootfs_lds)
|
||||
|
||||
e.Append(LINKFLAGS = '-T' + rootfs_lds[0].path)
|
||||
rootfs_img = e.Program('rootfs.elf', 'rootfs.c')
|
||||
Depends(rootfs_img, rootfs_lds)
|
||||
|
||||
Return('rootfs_img')
|
||||
2
conts/posix/rootfs/rootfs.c
Normal file
2
conts/posix/rootfs/rootfs.c
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
SECTION(".bss") char empty_image[SZ_4MB];
|
||||
9
conts/posix/rootfs/rootfs.lds.in
Normal file
9
conts/posix/rootfs/rootfs.lds.in
Normal file
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* Linker script that embeds an empty root filesystem.
|
||||
* This is to be replaced by a real rootfs image later.
|
||||
*/
|
||||
SECTIONS
|
||||
{
|
||||
. = %s;
|
||||
.bss : { *(.bss) }
|
||||
}
|
||||
@@ -118,7 +118,7 @@ int main(void)
|
||||
load_container_images((unsigned long)_start_containers,
|
||||
(unsigned long)_end_containers);
|
||||
|
||||
printf("elf-loader:\tkernel entry point is %lx\n", *kernel_entry);
|
||||
printf("elf-loader:\tkernel entry point is 0x%lx\n", *kernel_entry);
|
||||
arch_start_kernel(kernel_entry);
|
||||
|
||||
printf("elf-loader:\tKernel start failed! Looping endless.\n");
|
||||
|
||||
Reference in New Issue
Block a user