Updated LICENSE/README files, removed unused code from tasks.

This commit is contained in:
Bahadir Balban
2009-06-15 14:58:41 +03:00
parent 0dd8918ae5
commit ba1cc0c6bc
17 changed files with 44 additions and 810 deletions

View File

@@ -1,130 +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 = "blkdev0"
# The root directory of the repository where this file resides:
project_root = "../.."
tools_root = join(project_root, "tools")
prev_image = join(project_root, "tasks/mm0/mm0.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")
#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" + 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', \
'gcc', libc_name], # libgcc.a - This is required for division routines.
CPPFLAGS = "-D__USERSPACE__",
CPPPATH = ['#include', libl4_incpath, libc_incpath, kernel_incpath, libmem_incpath])
def extract_arch_subarch_plat(config_header):
'''
From the autogenerated kernel config.h, extracts platform, archictecture,
subarchitecture information. This is used to include the relevant headers
from the kernel directories.
'''
arch = None
subarch = None
plat = None
if not os.path.exists(config_header):
print "\n\nconfig.h does not exist. "\
"Please run: `scons configure' first\n\n"
sys.exit()
f = open(config_h, "r")
while True:
line = f.readline()
if line == "":
break
parts = split(line)
if len(parts) > 0:
if parts[0] == "#define":
if parts[1] == "__ARCH__":
arch = parts[2]
elif parts[1] == "__PLATFORM__":
plat = parts[2]
elif parts[1] == "__SUBARCH__":
subarch = parts[2]
f.close()
if arch == None:
print "Error: No config symbol found for architecture"
sys.exit()
if subarch == None:
print "Error: No config symbol found for subarchitecture"
sys.exit()
if plat == None:
print "Error: No config symbol found for platform"
sys.exit()
return arch, subarch, plat
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("fsbin/*.S"), 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)

View File

@@ -1,43 +0,0 @@
#
# Binary to elf build script
# Works by including a binary in an assembler file and linking it.
#
# Copyright (C) 2007 Bahadir Balban
#
import os
import sys
import shutil
from os.path import join
from glob import glob
elfimg_name = "romfs"
# The root directory of the repository where this file resides:
project_root = "../.."
tools_root = join(project_root, "tools")
prev_image = join(project_root, "tasks/test0/test0.axf")
ld_script = "include/linker.lds"
physical_base_ld_script = "include/physical_base.lds"
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],
ASFLAGS = ['-D__ASSEMBLY__'],
PROGSUFFIX = '.axf', # The suffix to use for final executable
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
CPPFLAGS = "-D__USERSPACE__",
CPPPATH = ['#include'])
src = [glob("*.S")]
objs = env.Object(src)
physical_base = env.Command(physical_base_ld_script, prev_image, get_physical_base)
task = env.Program(elfimg_name, objs)
env.Alias(elfimg_name, task)
env.Depends(task, physical_base)

View File

@@ -1,7 +0,0 @@
/* This is used to place a binary file into an elf section */
.section .data.fs
.incbin "fsbin/romfs.bin"
.align 4

Binary file not shown.

View File

@@ -1 +0,0 @@
arch-arm

View File

@@ -1,31 +0,0 @@
#ifndef __BLKDEV_H__
#define __BLKDEV_H__
#include <l4lib/types.h>
struct block_device;
struct block_device_ops {
int (*init)(struct block_device *bdev);
int (*open)(struct block_device *bdev);
int (*read)(struct block_device *bdev, unsigned long offset,
int size, void *buf);
int (*write)(struct block_device *bdev, unsigned long offset,
int size, void *buf);
int (*read_page)(struct block_device *bdev,
unsigned long pfn, void *buf);
int (*write_page)(struct block_device *bdev,
unsigned long pfn, void *buf);
};
struct block_device {
char *name;
void *private; /* Low-level device specific data */
u64 size;
struct block_device_ops ops;
};
void init_blkdev(void);
#endif /* __BLKDEV_H__ */

View File

@@ -1,47 +0,0 @@
/*
* Simple linker script for userspace or svc tasks.
*
* Copyright (C) 2007 Bahadir Balban
*/
/*
* The only catch with this linker script is that everything
* is linked starting at virtual_base, and loaded starting
* at physical_base. virtual_base is the predefined region
* of virtual memory for userland applications. physical_base
* is determined at build-time, it is one of the subsequent pages
* that come after the kernel image's load area.
*/
/* USER_AREA_START, see memlayout.h */
virtual_base = 0x10000000;
__stack = 0x20000000;
INCLUDE "include/physical_base.lds"
/* physical_base = 0x228000; */
offset = virtual_base - physical_base;
ENTRY(_start)
SECTIONS
{
. = virtual_base;
_start_text = .;
.text : AT (ADDR(.text) - offset) { crt0.o(.text) *(.text) }
/* rodata is needed else your strings will link at physical! */
.rodata : AT (ADDR(.rodata) - offset) { *(.rodata) }
.rodata1 : AT (ADDR(.rodata1) - offset) { *(.rodata1) }
.data : AT (ADDR(.data) - offset)
{
. = ALIGN(4K);
_start_ramdisk0 = .;
*(.data.romfs)
_end_ramdisk0 = .;
. = ALIGN(4K);
_start_ramdisk1 = .;
*(.data.sfs)
_end_ramdisk1 = .;
*(.data)
}
.bss : AT (ADDR(.bss) - offset) { *(.bss) }
_end = .;
}

View File

@@ -1,7 +0,0 @@
#ifndef __RAMDISK_H__
#define __RAMDISK_H__
extern struct block_device ramdisk[];
extern struct block_device ramdisk[];
#endif

View File

@@ -1,59 +0,0 @@
/*
* High-level block device handling.
*
* Copyright (C) 2007, 2008 Bahadir Balban
*/
#include <stdio.h>
#include <blkdev.h>
/*
* Handles block device requests from fs0 using a combination of
* server-specific and posix shm semantics
*/
void handle_block_device_request()
{
u32 mr[MR_UNUSED_TOTAL];
l4id_t sender;
int err;
u32 tag;
printf("%s: Listening requests.\n", __TASKNAME__);
if ((err = l4_receive(L4_ANYTHREAD)) < 0) {
printf("%s: %s: IPC Error: %d. Quitting...\n", __TASKNAME__,
__FUNCTION__, err);
BUG();
}
/* Read conventional ipc data */
tag = l4_get_tag();
sender = l4_get_sender();
/* Read mrs not used by syslib */
for (int i = 0; i < MR_UNUSED_TOTAL; i++)
mr[i] = read_mr(i);
switch(tag) {
case L4_IPC_TAG_WAIT:
printf("%s: Synced with waiting thread.\n", __TASKNAME__);
break;
case L4_IPC_TAG_BLOCK_OPEN:
sys_open(sender, (void *)mr[0], (int)mr[1], (u32)mr[2]);
break;
default:
printf("%s: Unrecognised ipc tag (%d)"
"received. Ignoring.\n", __TASKNAME__, mr[MR_TAG]);
}
}
int main(void)
{
/* Initialise the block devices */
init_blkdev();
while (1) {
handle_block_device_request();
}
return 0;
}

View File

@@ -1,11 +0,0 @@
#include <blkdev.h>
#include <ramdisk.h>
void init_blkdev(void)
{
ramdisk[0].ops.init(&ramdisk[0]);
ramdisk[1].ops.init(&ramdisk[1]);
}

View File

@@ -1,116 +0,0 @@
/*
* A basic ramdisk implementation.
*
* Copyright (C) 2007, 2008 Bahadir Balban
*
* The ramdisk binary is embedded in the data section of the ramdisk device
* executable. Read/writes simply occur to this area. The disk area could
* have any filesystem layout e.g. romfs, which is irrelevant for this code.
*/
#include <blkdev.h>
#include <ramdisk.h>
#include <l4/macros.h>
#include <l4/config.h>
#include <l4/types.h>
#include <string.h>
#include INC_SUBARCH(mm.h)
#include INC_GLUE(memory.h)
/* Ramdisk section markers for ramdisk inside this executable image */
extern char _start_ramdisk0[];
extern char _end_ramdisk0[];
extern char _start_ramdisk1[];
extern char _end_ramdisk1[];
struct ramdisk_data {
u64 base;
u64 end;
};
struct ramdisk_data rddata[2];
__attribute__((section(".data.sfs"))) char sfsdisk[SZ_16MB];
int ramdisk_init(struct block_device *ramdisk)
{
struct ramdisk_data *rddata = ramdisk->private;
if (!strcmp("ramdisk0", ramdisk->name)) {
rddata->base = (u64)(unsigned long)_start_ramdisk0;
rddata->end = (u64)(unsigned long)_end_ramdisk0;
ramdisk->size = (u64)((unsigned long)_end_ramdisk0 -
(unsigned long)_start_ramdisk0);
} else if (!strcmp("ramdisk1", ramdisk->name)) {
rddata->base = (u64)(unsigned long)_start_ramdisk1;
rddata->end = (u64)(unsigned long)_end_ramdisk1;
ramdisk->size = (u64)((unsigned long)_end_ramdisk1 -
(unsigned long)_start_ramdisk1);
} else
return -1;
return 0;
}
int ramdisk_open(struct block_device *ramdisk)
{
return 0;
}
int ramdisk_read(struct block_device *b, unsigned long offset, int size, void *buf)
{
struct ramdisk_data *data = b->private;
void *src = (void *)(unsigned long)(data->base + offset);
memcpy(buf, src, size);
return 0;
}
int ramdisk_write(struct block_device *b, unsigned long offset,
int size, void *buf)
{
struct ramdisk_data *data = b->private;
void *dst = (void *)(unsigned long)(data->base + offset);
memcpy(dst, buf, size);
return 0;
}
int ramdisk_readpage(struct block_device *b, unsigned long pfn, void *buf)
{
ramdisk_read(b, __pfn_to_addr(pfn), PAGE_SIZE, buf);
return 0;
}
int ramdisk_writepage(struct block_device *b, unsigned long pfn, void *buf)
{
ramdisk_write(b, __pfn_to_addr(pfn), PAGE_SIZE, buf);
return 0;
}
struct block_device ramdisk[2] = {
[0] = {
.name = "ramdisk0",
.private = &rddata[0],
.ops = {
.init = ramdisk_init,
.open = ramdisk_open,
.read = ramdisk_read,
.write = ramdisk_write,
.read_page = ramdisk_readpage,
.write_page = ramdisk_writepage,
},
},
[1] = {
.name = "ramdisk1",
.private = &rddata[1],
.ops = {
.init = ramdisk_init,
.open = ramdisk_open,
.read = ramdisk_read,
.write = ramdisk_write,
.read_page = ramdisk_readpage,
.write_page = ramdisk_writepage,
},
}
};

View File

@@ -1,28 +0,0 @@
#!/usr/bin/python
import os
import sys
compiler_prefix = "arm-none-linux-gnueabi-"
objdump = "objdump"
command = "-t"
image_name = "inittask.axf"
linkoutput_file_suffix = "-linkinfo.txt"
linkoutput_file = image_name + linkoutput_file_suffix
def generate_bootdesc():
command = compiler_prefix + objdump + " -t " + image_name + " > " + linkoutput_file
print command
os.system(command)
f = open(linkoutput_file, "r")
while True:
line = f.readline()
if len(line) is 0:
break
if "_start" in line or "_end" in line:
print line
f.close()
if __name__ == "__main__":
generate_bootdesc()

View File

@@ -1,18 +0,0 @@
struct channel {
int dir; /* Direction */
char *name; /* Name */
int cd; /* Channel descriptor */
};
struct interface {
struct channel chan[];
};
int main(int argc, char *argv[])
{
void *buf = malloc(sizeof(struct channel)*10);
struct interface *intf = buf;
}

View File

@@ -1,154 +0,0 @@
/*
* Lightweight and simple RPC primitives.
*
* Copyright (c) 2007 Bahadir Balban
*
* Some methodology is needed for efficient and functional message passing
* among processes, particulary when shared memory or same address space
* messaging is available. The rpc primitives here attempt to fill this gap.
*
* The idea is to generate as little bloat as possible. To that end we don't
* need encryption, marshalling, type tracking and discovery. Also Very minor
* boilerplated code is produced from C macros rather than a notorious rpc tool.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* What default value arg0 is given for rpc calls */
#define ARG0 8
#define PAGE_SIZE 0x1000
char pagebuf[PAGE_SIZE];
struct ipc_shmem {
unsigned long vaddr;
};
struct tlmsg {
struct ipc_shmem shmem;
unsigned long arg[3];
unsigned long ret;
unsigned long method_num;
};
typedef int (*remote_call_t)(struct tlmsg *m);
int square(int i)
{
printf("%s: Entering...\n", __FUNCTION__);
return i*i;
}
/* Hand coded wrapper for non-complex argument types. */
int rpc_square(struct tlmsg *m)
{
printf("%s: Entering...\n", __FUNCTION__);
return square(m->arg[0]);
}
struct complex_struct {
int item;
int item2;
};
/* Use this to declare an RPC wrapper for your function. Your function
* must return a primitive type (e.g, int, float, long etc.) and can
* have a ref to a single argument of complex type (e.g. a struct). Apart
* from these limitations it is essentially a regular C function. Note
* that one can pass a lot of data back and forth using a single struct.
* The wrappers are very lightweight, and thanks to many possibilities of
* shared memory (e.g. same address-space, shared pages) data need not be
* copied when passed back and forth. */
#define DECLARE_RPC_BYREF(ret, func, type0) \
static inline ret rpc_byref_##func(struct tlmsg *m) \
{ /* Find struct address */ \
unsigned long multiword_struct = m->arg[0] + \
m->shmem.vaddr; /* Data passed by a shared entity */ \
return func((type0 *)multiword_struct); /* Call real function */\
}
/* Same as above, but passing a structure by value instead of reference.
* This is much slower due to lots of copying involved. It is not
* recommended but included for completion. */
#define DECLARE_RPC_BYVAL(ret, func, type0) \
static inline ret rpc_byval_##func(struct tlmsg *m) \
{ /* Find struct address */ \
unsigned long multiword_struct = m->arg[0] + \
m->shmem.vaddr; /* Data passed by a shared entity */ \
/* Call real function, by value */ \
return func((type0)(*(type0 *)multiword_struct)); \
}
/* Use these directly to declare the function, *and* its RPC wrapper. */
#define RPC_FUNC_BYREF(ret, func, type0) \
ret func(type0 *); \
DECLARE_RPC_BYREF(ret, func, type0) \
ret func(type0 *arg0)
#define RPC_FUNC_BYVAL(ret, func, type0) \
ret func(type0); \
DECLARE_RPC_BYVAL(ret, func, type0) \
ret func(type0 arg0)
RPC_FUNC_BYVAL(int, complex_byval, struct complex_struct)
{
printf("%s: Entering...\n", __FUNCTION__);
arg0.item++;
return 0;
}
RPC_FUNC_BYREF(int, complex_byref, struct complex_struct)
{
printf("%s: Entering...\n", __FUNCTION__);
arg0->item++;
return 0;
}
#define RPC_NAME(func, by) rpc_##by##_##func
remote_call_t remote_call_array[] = {
rpc_square,
RPC_NAME(complex_byval, byval),
RPC_NAME(complex_byref, byref),
};
struct tlmsg *getmsg(int x)
{
struct tlmsg *m = (struct tlmsg *)malloc(sizeof(struct tlmsg));
m->method_num = x;
m->arg[0] = ARG0;
m->shmem.vaddr = (unsigned long)&pagebuf;
return m;
}
void putmsg(struct tlmsg *m)
{
free((void *)m);
}
void check_rpc_success()
{
struct complex_struct *cs = (struct complex_struct *)(pagebuf + ARG0);
printf("complex struct at offset 0x%x. cs->item: %d, expected: 1.\n", ARG0, cs->item);
}
int main(void)
{
struct tlmsg *m[3];
unsigned int ret;
remote_call_t call[3];
memset((void *)pagebuf, 0, PAGE_SIZE);
for (int i = 0; i < 3; i++) {
m[i] = getmsg(i);
printf("Calling remote function %d according to incoming msg.\n", i);
call[i] = remote_call_array[m[i]->method_num];
ret = call[i](m[i]); /* i.e. call rpc function number i, with
* message number i as argument */
printf("Call returned %d\n", ret);
m[i]->ret = ret;
putmsg(m[i]);
}
check_rpc_success();
}

Binary file not shown.