mirror of
https://github.com/drasko/codezero.git
synced 2026-01-13 11:23:16 +01:00
Initial commit
This commit is contained in:
130
tasks/blkdev0/SConstruct
Normal file
130
tasks/blkdev0/SConstruct
Normal 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)
|
||||
|
||||
43
tasks/blkdev0/fsbin/SConstruct
Normal file
43
tasks/blkdev0/fsbin/SConstruct
Normal 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)
|
||||
7
tasks/blkdev0/fsbin/incbin.S
Normal file
7
tasks/blkdev0/fsbin/incbin.S
Normal 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
1
tasks/blkdev0/include/arch
Symbolic link
@@ -0,0 +1 @@
|
||||
arch-arm
|
||||
23
tasks/blkdev0/include/blkdev.h
Normal file
23
tasks/blkdev0/include/blkdev.h
Normal 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__ */
|
||||
43
tasks/blkdev0/include/linker.lds
Normal file
43
tasks/blkdev0/include/linker.lds
Normal 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 = .;
|
||||
}
|
||||
17
tasks/blkdev0/include/physical_base.lds
Normal file
17
tasks/blkdev0/include/physical_base.lds
Normal 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;
|
||||
6
tasks/blkdev0/include/ramdisk.h
Normal file
6
tasks/blkdev0/include/ramdisk.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef __RAMDISK_H__
|
||||
#define __RAMDISK_H__
|
||||
|
||||
extern struct block_device ramdisk;
|
||||
|
||||
#endif
|
||||
10
tasks/blkdev0/main.c
Normal file
10
tasks/blkdev0/main.c
Normal 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
1
tasks/blkdev0/src/arch
Symbolic link
@@ -0,0 +1 @@
|
||||
arch-arm
|
||||
10
tasks/blkdev0/src/init.c
Normal file
10
tasks/blkdev0/src/init.c
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
|
||||
#include <blkdev.h>
|
||||
#include <ramdisk.h>
|
||||
|
||||
|
||||
void init_blkdev(void)
|
||||
{
|
||||
ramdisk.ops.open(&ramdisk);
|
||||
}
|
||||
65
tasks/blkdev0/src/ramdisk.c
Normal file
65
tasks/blkdev0/src/ramdisk.c
Normal 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,
|
||||
},
|
||||
};
|
||||
|
||||
28
tasks/blkdev0/tools/generate_bootdesc.py
Executable file
28
tasks/blkdev0/tools/generate_bootdesc.py
Executable 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()
|
||||
|
||||
Reference in New Issue
Block a user