Initial commit

This commit is contained in:
Bahadir Balban
2008-01-13 13:53:52 +00:00
commit e2b791a3d8
789 changed files with 95825 additions and 0 deletions

130
tasks/blkdev0/SConstruct Normal file
View File

@@ -0,0 +1,130 @@
#
# 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

@@ -0,0 +1,43 @@
#
# 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

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

1
tasks/blkdev0/include/arch Symbolic link
View File

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

View File

@@ -0,0 +1,23 @@
#ifndef __BLKDEV_H__
#define __BLKDEV_H__
struct block_device;
struct block_device_ops {
void (*open)(struct block_device *bdev);
void (*read)(unsigned long offset, int size, void *buf);
void (*write)(unsigned long offset, int size, void *buf);
void (*read_page)(unsigned long pfn, void *buf);
void (*write_page)(unsigned long pfn, void *buf);
};
struct block_device {
char *name;
unsigned long size;
struct block_device_ops ops;
};
void init_blkdev(void);
#endif /* __BLKDEV_H__ */

View File

@@ -0,0 +1,43 @@
/*
* 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_ramdisk = .;
*(.data.fs)
_end_ramdisk = .;
*(.data)
}
.bss : AT (ADDR(.bss) - offset) { *(.bss) }
_end = .;
}

View File

@@ -0,0 +1,17 @@
/*
* The next free p_align'ed LMA base address
*
* p_align = 0x8000
*
* Recap from ELF spec: p_align: Loadable process segments must have
* congruent values for p_vaddr and p_offset, modulo the page size.
* This member gives the value to which the segments are aligned in
* memory and in the file. Values 0 and 1 mean that no alignment is
* required. Otherwise, p_align should be a positive, integral power
* of 2, and p_addr should equal p_offset, modulo p_align.
* This essentially means next available address must be aligned at
* p_align, rather than the page_size, which one (well, I) would
* normally expect.
*/
physical_base = 0x3000;

View File

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

10
tasks/blkdev0/main.c Normal file
View File

@@ -0,0 +1,10 @@
#include <stdio.h>
#include <blkdev.h>
int main(void)
{
init_blkdev();
return 0;
}

1
tasks/blkdev0/src/arch Symbolic link
View File

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

10
tasks/blkdev0/src/init.c Normal file
View File

@@ -0,0 +1,10 @@
#include <blkdev.h>
#include <ramdisk.h>
void init_blkdev(void)
{
ramdisk.ops.open(&ramdisk);
}

View File

@@ -0,0 +1,65 @@
/*
* A basic ramdisk implementation.
*
* Copyright (C) 2007 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_ramdisk[];
extern char _end_ramdisk[];
static unsigned long ramdisk_base;
void ramdisk_open(struct block_device *ramdisk)
{
ramdisk_base = (unsigned long)_start_ramdisk;
ramdisk->size = (unsigned long)_end_ramdisk -
(unsigned long)_start_ramdisk;
}
void ramdisk_read(unsigned long offset, int size, void *buf)
{
void *src = (void *)(ramdisk_base + offset);
memcpy(buf, src, size);
}
void ramdisk_write(unsigned long offset, int size, void *buf)
{
void *dst = (void *)(ramdisk_base + offset);
memcpy(dst, buf, size);
}
void ramdisk_readpage(unsigned long pfn, void *buf)
{
ramdisk_read(__pfn_to_addr(pfn), PAGE_SIZE, buf);
}
void ramdisk_writepage(unsigned long pfn, void *buf)
{
ramdisk_write(__pfn_to_addr(pfn), PAGE_SIZE, buf);
}
struct block_device ramdisk = {
.name = "ramdisk",
.ops = {
.open = ramdisk_open,
.read = ramdisk_read,
.write = ramdisk_write,
.read_page = ramdisk_readpage,
.write_page = ramdisk_writepage,
},
};

View File

@@ -0,0 +1,28 @@
#!/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()