mirror of
https://github.com/drasko/codezero.git
synced 2026-03-03 11:03:16 +01:00
Kernel updates since December 2009
This commit is contained in:
@@ -18,6 +18,7 @@ from config.lib import *
|
||||
|
||||
config = configuration_retrieve()
|
||||
arch = config.arch
|
||||
gcc_arch_flag = config.gcc_arch_flag
|
||||
|
||||
LIBL4_RELDIR = 'conts/libl4'
|
||||
KERNEL_INCLUDE = join(PROJROOT, 'include')
|
||||
@@ -48,25 +49,27 @@ LIBPOSIX_INCLUDE_SERVER = join(LIBPOSIX_DIR, 'include')
|
||||
LIBPOSIX_INCLUDE_USERSPACE = join(LIBPOSIX_DIR, 'include/posix')
|
||||
LIBPOSIX_LIBPATH = join(BUILDDIR, LIBPOSIX_RELDIR)
|
||||
|
||||
env = Environment(CC = config.user_toolchain + 'gcc',
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', \
|
||||
'-std=gnu99', '-Wall', '-Werror'],
|
||||
LINKFLAGS = ['-nostdlib'],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
PROGSUFFIX = '.elf',
|
||||
ENV = {'PATH' : os.environ['PATH']},
|
||||
LIBS = ['gcc', 'libl4', 'c-userspace','libdev-userspace', \
|
||||
'libmm', 'libmc', 'libmalloc', 'gcc'],
|
||||
CPPPATH = ['include', LIBDEV_INCLUDE, LIBC_INCLUDE, KERNEL_INCLUDE,
|
||||
LIBL4_INCLUDE, LIBMEM_INCLUDE],
|
||||
LIBPATH = [LIBDEV_LIBPATH, LIBC_LIBPATH, LIBL4_LIBPATH,
|
||||
LIBMEM_LIBPATH, LIBPOSIX_LIBPATH],
|
||||
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h')
|
||||
env = Environment(CC = config.toolchain + 'gcc',
|
||||
AR = config.toolchain + 'ar',
|
||||
RANLIB = config.toolchain + 'ranlib',
|
||||
CCFLAGS = ['-g','-nostdinc', '-nostdlib', '-ffreestanding',
|
||||
'-march=' + gcc_arch_flag, '-std=gnu99', '-Wall', '-Werror'],
|
||||
LINKFLAGS = ['-nostdlib'],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
PROGSUFFIX = '.elf',
|
||||
ENV = {'PATH' : os.environ['PATH']},
|
||||
LIBS = ['libl4', 'libdev-userspace', 'gcc', 'c-userspace', \
|
||||
'gcc', 'libmm', 'libmc', 'libmalloc'],
|
||||
CPPPATH = ['include', LIBDEV_INCLUDE, LIBC_INCLUDE, KERNEL_INCLUDE,
|
||||
LIBL4_INCLUDE, LIBMEM_INCLUDE, LIBPOSIX_INCLUDE_USERSPACE],
|
||||
LIBPATH = [LIBDEV_LIBPATH, LIBC_LIBPATH, LIBL4_LIBPATH,
|
||||
LIBMEM_LIBPATH, LIBPOSIX_LIBPATH],
|
||||
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h')
|
||||
|
||||
contid = ARGUMENTS.get('cont', '0')
|
||||
|
||||
libposix_env = env.Clone()
|
||||
libposix_env.Replace(CPPPATH = [LIBPOSIX_INCLUDE_USERSPACE, 'include', KERNEL_INCLUDE, LIBL4_INCLUDE, LIBMEM_INCLUDE])
|
||||
libposix_env.Replace(CPPPATH = [LIBPOSIX_INCLUDE_USERSPACE, 'include', KERNEL_INCLUDE, LIBL4_INCLUDE, LIBMEM_INCLUDE, LIBC_INCLUDE])
|
||||
libposix = SConscript('libposix/SConscript', \
|
||||
exports = { 'config' : config, 'env' : libposix_env, 'contid' : contid}, duplicate = 0, \
|
||||
variant_dir = join(BUILDDIR, 'conts' + '/posix' + '/libposix'))
|
||||
@@ -83,7 +86,7 @@ rootfs = SConscript('rootfs/SConscript', \
|
||||
|
||||
# No libposix reference because it conflicts with the compiler C library + the cluncky libc we have.
|
||||
test0_env = env.Clone()
|
||||
test0_env.Replace(CPPPATH = ['include', KERNEL_INCLUDE, LIBL4_INCLUDE, LIBMEM_INCLUDE])
|
||||
test0_env.Replace(CPPPATH = ['include', KERNEL_INCLUDE, LIBL4_INCLUDE, LIBMEM_INCLUDE, LIBC_INCLUDE, LIBPOSIX_INCLUDE_USERSPACE])
|
||||
test0 = SConscript('test0/SConscript', \
|
||||
exports = { 'config' : config, 'environment' : test0_env, 'contid' : contid, 'previmage' : rootfs }, duplicate = 0, \
|
||||
variant_dir = join(BUILDDIR, 'cont' + str(contid) + '/posix' + '/test0'))
|
||||
|
||||
@@ -97,8 +97,8 @@ def relocate_bootdesc(target, source, env):
|
||||
images = source[1:]
|
||||
mm0 = images[0]
|
||||
start, end = image_lma_start_end(mm0.path)
|
||||
print config.user_toolchain + "objcopy --adjust-section-vma .data=" + conv_hex(end) + " " + bootdesc_raw.path
|
||||
os.system(config.user_toolchain + "objcopy --adjust-section-vma .data=" + conv_hex(end) + " " + bootdesc_raw.path)
|
||||
print config.toolchain + "objcopy --adjust-section-vma .data=" + conv_hex(end) + " " + bootdesc_raw.path
|
||||
os.system(config.toolchain + "objcopy --adjust-section-vma .data=" + conv_hex(end) + " " + bootdesc_raw.path)
|
||||
shutil.copyfile(bootdesc_raw.path, target[0].path)
|
||||
|
||||
bootdesc_c = e.Command('bootdesc.c', images, generate_bootdesc)
|
||||
|
||||
@@ -12,7 +12,7 @@ from configure import *
|
||||
config = configuration_retrieve()
|
||||
builddir = ARGUMENTS.get('builddir', 'build/conts/posix')
|
||||
|
||||
env = Environment(CC = config.user_toolchain + 'gcc',
|
||||
env = Environment(CC = config.toolchain + 'gcc',
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror'],
|
||||
LINKFLAGS = ['-nostdlib','-Tlinker.lds'],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
|
||||
@@ -8,7 +8,8 @@ Import('env')
|
||||
|
||||
e = env.Clone()
|
||||
e.Append(CPPPATH = ['include', 'include/posix'])
|
||||
e.Replace(CCFLAGS = ['-g', '-nostdlib', '-Wall', '-Werror', '-ffreestanding', '-std=gnu99'])
|
||||
e.Replace(CCFLAGS = ['-g','-nostdinc', '-nostdlib', '-Wall', '-Werror', '-ffreestanding', '-std=gnu99'],
|
||||
CPPFLAGS = ' -include l4lib/macros.h ')
|
||||
|
||||
objects = e.StaticObject(Glob('*.c'))
|
||||
libposix = e.StaticLibrary('posix', objects)
|
||||
|
||||
@@ -16,7 +16,7 @@ kernel_headers = join(project_root, "include")
|
||||
l4lib_headers = join(project_root, "tasks/libl4/include")
|
||||
config_h = join(project_root, "include/l4/config.h")
|
||||
|
||||
env = Environment(CC = config.user_toolchain + 'gcc',
|
||||
env = Environment(CC = config.toolchain + 'gcc',
|
||||
CCFLAGS = ['-g', '-std=gnu99', '-nostdlib', '-ffreestanding'],
|
||||
LINKFLAGS = ['-nostdlib'],
|
||||
CPPPATH = ['#include'],
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <libposix.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <l4lib/utcb.h>
|
||||
#include <l4/macros.h>
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <l4lib/utcb.h>
|
||||
#include <l4/macros.h>
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
#include <sys/shm.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <l4lib/utcb.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <unistd.h>
|
||||
#include <l4/macros.h>
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <l4lib/utcb.h>
|
||||
#include <l4/macros.h>
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <libposix.h>
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
#ifndef __LIBPOSIX_H__
|
||||
#define __LIBPOSIX_H__
|
||||
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
|
||||
#include <l4lib/types.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
|
||||
/* Abort debugging conditions */
|
||||
// #define LIBPOSIX_ERROR_MESSAGES
|
||||
#if defined (LIBPOSIX_ERROR_MESSAGES)
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#endif
|
||||
|
||||
/* The kernel sources contain a file with all the needed information. */
|
||||
#include <linux/limits.h>
|
||||
//#include <linux/limits.h>
|
||||
|
||||
/* Have to remove NR_OPEN? */
|
||||
#ifdef __undef_NR_OPEN
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
#ifndef _UCLIBC_PTHREAD_H
|
||||
#define _UCLIBC_PTHREAD_H
|
||||
|
||||
#ifndef _PTHREAD_H
|
||||
# error "Always include <pthread.h> rather than <bits/uClibc_pthread.h>"
|
||||
#endif
|
||||
//#ifndef _PTHREAD_H
|
||||
//# error "Always include <pthread.h> rather than <bits/uClibc_pthread.h>"
|
||||
//#endif
|
||||
|
||||
#if defined _LIBC && (defined IS_IN_libc || defined NOT_IN_libc)
|
||||
/* Threading functions internal to uClibc. Make these thread functions
|
||||
|
||||
0
conts/posix/libposix/include/posix/pthread.h
Normal file
0
conts/posix/libposix/include/posix/pthread.h
Normal file
@@ -8,11 +8,11 @@
|
||||
#define __LIBPOSIX_SHPAGE_H__
|
||||
|
||||
#include <l4/macros.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <l4lib/utcb.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
|
||||
extern void *shared_page;
|
||||
|
||||
|
||||
@@ -328,16 +328,16 @@ extern int sprintf (char *__restrict __s,
|
||||
|
||||
This function is a possible cancellation point and therefore not
|
||||
marked with __THROW. */
|
||||
extern int vfprintf (FILE *__restrict __s, __const char *__restrict __format,
|
||||
__gnuc_va_list __arg);
|
||||
//extern int vfprintf (FILE *__restrict __s, __const char *__restrict __format,
|
||||
// __gnuc_va_list __arg);
|
||||
/* Write formatted output to stdout from argument list ARG.
|
||||
|
||||
This function is a possible cancellation point and therefore not
|
||||
marked with __THROW. */
|
||||
extern int vprintf (__const char *__restrict __format, __gnuc_va_list __arg);
|
||||
//extern int vprintf (__const char *__restrict __format, __gnuc_va_list __arg);
|
||||
/* Write formatted output to S from argument list ARG. */
|
||||
extern int vsprintf (char *__restrict __s, __const char *__restrict __format,
|
||||
__gnuc_va_list __arg) __THROW;
|
||||
//extern int vsprintf (char *__restrict __s, __const char *__restrict __format,
|
||||
// __gnuc_va_list __arg) __THROW;
|
||||
__END_NAMESPACE_STD
|
||||
|
||||
#if defined __USE_BSD || defined __USE_ISOC99 || defined __USE_UNIX98
|
||||
@@ -347,18 +347,18 @@ extern int snprintf (char *__restrict __s, size_t __maxlen,
|
||||
__const char *__restrict __format, ...)
|
||||
__THROW __attribute__ ((__format__ (__printf__, 3, 4)));
|
||||
|
||||
extern int vsnprintf (char *__restrict __s, size_t __maxlen,
|
||||
__const char *__restrict __format, __gnuc_va_list __arg)
|
||||
__THROW __attribute__ ((__format__ (__printf__, 3, 0)));
|
||||
//extern int vsnprintf (char *__restrict __s, size_t __maxlen,
|
||||
// __const char *__restrict __format, __gnuc_va_list __arg)
|
||||
// __THROW __attribute__ ((__format__ (__printf__, 3, 0)));
|
||||
__END_NAMESPACE_C99
|
||||
#endif
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* Write formatted output to a string dynamically allocated with `malloc'.
|
||||
Store the address of the string in *PTR. */
|
||||
extern int vasprintf (char **__restrict __ptr, __const char *__restrict __f,
|
||||
__gnuc_va_list __arg)
|
||||
__THROW __attribute__ ((__format__ (__printf__, 2, 0)));
|
||||
//extern int vasprintf (char **__restrict __ptr, __const char *__restrict __f,
|
||||
// __gnuc_va_list __arg)
|
||||
// __THROW __attribute__ ((__format__ (__printf__, 2, 0)));
|
||||
#if 0 /* uClibc: disabled */
|
||||
extern int __asprintf (char **__restrict __ptr,
|
||||
__const char *__restrict __fmt, ...)
|
||||
@@ -374,8 +374,8 @@ extern int asprintf (char **__restrict __ptr,
|
||||
cancellation point. But due to similarity with an POSIX interface
|
||||
or due to the implementation they are cancellation points and
|
||||
therefore not marked with __THROW. */
|
||||
extern int vdprintf (int __fd, __const char *__restrict __fmt,
|
||||
__gnuc_va_list __arg)
|
||||
//extern int vdprintf (int __fd, __const char *__restrict __fmt,
|
||||
// __gnuc_va_list __arg)
|
||||
__attribute__ ((__format__ (__printf__, 2, 0)));
|
||||
extern int dprintf (int __fd, __const char *__restrict __fmt, ...)
|
||||
__attribute__ ((__format__ (__printf__, 2, 3)));
|
||||
@@ -405,21 +405,21 @@ __BEGIN_NAMESPACE_C99
|
||||
|
||||
This function is a possible cancellation point and therefore not
|
||||
marked with __THROW. */
|
||||
extern int vfscanf (FILE *__restrict __s, __const char *__restrict __format,
|
||||
__gnuc_va_list __arg)
|
||||
__attribute__ ((__format__ (__scanf__, 2, 0)));
|
||||
//extern int vfscanf (FILE *__restrict __s, __const char *__restrict __format,
|
||||
// __gnuc_va_list __arg)
|
||||
// __attribute__ ((__format__ (__scanf__, 2, 0)));
|
||||
|
||||
/* Read formatted input from stdin into argument list ARG.
|
||||
|
||||
This function is a possible cancellation point and therefore not
|
||||
marked with __THROW. */
|
||||
extern int vscanf (__const char *__restrict __format, __gnuc_va_list __arg)
|
||||
__attribute__ ((__format__ (__scanf__, 1, 0)));
|
||||
//extern int vscanf (__const char *__restrict __format, __gnuc_va_list __arg)
|
||||
// __attribute__ ((__format__ (__scanf__, 1, 0)));
|
||||
|
||||
/* Read formatted input from S into argument list ARG. */
|
||||
extern int vsscanf (__const char *__restrict __s,
|
||||
__const char *__restrict __format, __gnuc_va_list __arg)
|
||||
__THROW __attribute__ ((__format__ (__scanf__, 2, 0)));
|
||||
//extern int vsscanf (__const char *__restrict __s,
|
||||
// __const char *__restrict __format, __gnuc_va_list __arg)
|
||||
// __THROW __attribute__ ((__format__ (__scanf__, 2, 0)));
|
||||
__END_NAMESPACE_C99
|
||||
#endif /* Use ISO C9x. */
|
||||
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <libposix.h>
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
#include <sys/shm.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <l4lib/utcb.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <libposix.h>
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
#include <sys/shm.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <l4lib/utcb.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <l4lib/os/posix/readdir.h>
|
||||
#include <l4/macros.h>
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/types.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <l4/macros.h>
|
||||
#include <libposix.h>
|
||||
|
||||
@@ -4,17 +4,15 @@
|
||||
* Copyright (C) 2007-2009 Bahadir Balban
|
||||
*/
|
||||
#include <l4lib/kip.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/arch/utcb.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <l4/macros.h>
|
||||
#include INC_GLUE(memlayout.h)
|
||||
#include <stdio.h>
|
||||
#include <shpage.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/shm.h>
|
||||
#include <shpage.h>
|
||||
#include <libposix.h>
|
||||
#include INC_GLUE(memlayout.h)
|
||||
|
||||
#if 0
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <l4lib/os/posix/kstat.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <l4lib/utcb.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#include <libposix.h>
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <libposix.h>
|
||||
|
||||
|
||||
@@ -4,22 +4,13 @@ Import('config', 'env', 'contid')
|
||||
import os, sys
|
||||
|
||||
arch = config.arch
|
||||
subarch = config.subarch
|
||||
|
||||
sys.path.append('../../../../')
|
||||
from config.lib import *
|
||||
|
||||
container = next((c for c in config.containers if int(c.id) == int(contid)), None)
|
||||
|
||||
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))
|
||||
|
||||
def generate_container_h(target, source, env):
|
||||
base_value_dict = {}
|
||||
with open(source[0].path, 'r') as ch_in:
|
||||
@@ -52,13 +43,15 @@ def generate_vma_lma_lds(target, source, env):
|
||||
lma_lds = Command('include/linker.lds', 'include/linker.lds.in', generate_vma_lma_lds)
|
||||
|
||||
container_h = Command('include/container.h', 'include/container.h.in', generate_container_h)
|
||||
src = [Glob('*.c') + Glob('mm/*.c') + Glob('lib/*.c') + Glob('fs/*.c') + Glob('fs/memfs/*.c') + Glob('lib/elf/*.c') + Glob('mm/arch/*.[Sc]')]
|
||||
src = [Glob('*.c') + Glob('mm/*.c') + Glob('lib/*.c') + Glob('fs/*.c') + \
|
||||
Glob('fs/memfs/*.c') + Glob('lib/elf/*.c') + Glob('mm/arch/' + arch + '/*.[Sc]') +
|
||||
Glob('mm/arch/' + arch + '/' + subarch + '/*.[Sc]')]
|
||||
|
||||
e = env.Clone()
|
||||
|
||||
e.Append(LINKFLAGS = ['-T' + lma_lds[0].path, '-u_start'])
|
||||
e.Append(LIBS = 'posix')
|
||||
e.Append(CPPFLAGS = ' -include ' + container_h[0].path)
|
||||
e.Append(CPPFLAGS = ' -include ' + container_h[0].path + ' -include macros.h -include l4lib/macros.h ')
|
||||
objs = e.Object(src)
|
||||
mm0 = e.Program('mm0.elf', objs)
|
||||
Depends(objs, container_h)
|
||||
|
||||
@@ -30,7 +30,7 @@ LIBC_LIBPATH = join(BUILDDIR, LIBC_RELDIR)
|
||||
LIBC_INCLUDE = [join(LIBC_DIR, 'include'), \
|
||||
join(LIBC_DIR, 'include/arch' + '/' + arch)]
|
||||
|
||||
env = Environment(CC = config.user_toolchain + 'gcc',
|
||||
env = Environment(CC = config.toolchain + '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', \
|
||||
@@ -41,7 +41,7 @@ env = Environment(CC = config.user_toolchain + 'gcc',
|
||||
PROGSUFFIX = '.elf', # The suffix to use for final executable
|
||||
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
|
||||
LIBS = ['gcc', 'libl4', 'libc', 'libmm', 'libmc'],
|
||||
CPPPATH = ["#include", LIBC_INCLUDE, KERNEL_INCLUDE, LIBL4_INCLUDE, LIBMEM_INCLUDE],
|
||||
CPPPATH = ["#include", LIBC_INCLUDE, KERNEL_INCLUDE, LIBL4_INCLUDE],
|
||||
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h -D__KERNEL__')
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <l4/macros.h>
|
||||
#include <bootdesc.h>
|
||||
#include <memfs/memfs.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
|
||||
void *vfs_rootdev_open(void)
|
||||
{
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
arch-arm
|
||||
44
conts/posix/mm0/include/arch/arm/debug.h
Normal file
44
conts/posix/mm0/include/arch/arm/debug.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Debug/performance measurements for mm0
|
||||
*
|
||||
* Copyright (C) 2010 B Labs Ltd.
|
||||
*/
|
||||
#ifndef __ARCH_DEBUG_H__
|
||||
#define __ARCH_DEBUG_H__
|
||||
|
||||
#if !defined(CONFIG_DEBUG_PERFMON_USER)
|
||||
|
||||
#include <l4lib/types.h>
|
||||
|
||||
/* Common empty definitions for all arches */
|
||||
static inline u32 perfmon_read_cyccnt() { return 0; }
|
||||
|
||||
static inline void perfmon_reset_start_cyccnt() { }
|
||||
static inline u32 perfmon_read_reset_start_cyccnt() { return 0; }
|
||||
|
||||
#define debug_record_cycles(str)
|
||||
|
||||
#else /* End of CONFIG_DEBUG_PERFMON_USER */
|
||||
|
||||
/* Architecture specific perfmon cycle counting */
|
||||
#include L4LIB_INC_SUBARCH(perfmon.h)
|
||||
|
||||
extern u64 perfmon_total_cycles;
|
||||
extern u64 current_cycles;
|
||||
|
||||
/*
|
||||
* This is for Cortex-A9 running at 400Mhz. 25 / 100000 is
|
||||
* a rewriting of 2.5 nanosec / 1,000,000
|
||||
*/
|
||||
#define debug_record_cycles(str) \
|
||||
{ \
|
||||
current_cycles = perfmon_read_cyccnt(); \
|
||||
perfmon_total_cycles += current_cycles; \
|
||||
printf("%s: took %llu milliseconds\n", str, \
|
||||
current_cycles * 64 * 25 / 100000); \
|
||||
perfmon_reset_start_cyccnt(); \
|
||||
}
|
||||
|
||||
#endif /* End of !CONFIG_DEBUG_PERFMON_USER */
|
||||
|
||||
#endif /* __ARCH_DEBUG_H__ */
|
||||
15
conts/posix/mm0/include/arch/arm/mm.h
Normal file
15
conts/posix/mm0/include/arch/arm/mm.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef __INITTASK_ARCH_MM_H__
|
||||
#define __INITTASK_ARCH_MM_H__
|
||||
|
||||
#include <l4/macros.h>
|
||||
#include <l4/types.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
#include INC_ARCH(exception.h)
|
||||
#include <vm_area.h>
|
||||
|
||||
struct fault_data;
|
||||
void set_generic_fault_params(struct fault_data *fault);
|
||||
void arch_print_fault_params(struct fault_data *fault);
|
||||
void fault_handle_error(struct fault_data *fault);
|
||||
|
||||
#endif /* __INITTASK_ARCH_MM_H__ */
|
||||
@@ -6,7 +6,7 @@
|
||||
#ifndef __MM0_CAPABILITY_H__
|
||||
#define __MM0_CAPABILITY_H__
|
||||
|
||||
#include <l4lib/capability.h>
|
||||
#include <l4lib/lib/cap.h>
|
||||
#include <task.h>
|
||||
|
||||
extern struct cap_list capability_list;
|
||||
|
||||
9
conts/posix/mm0/include/macros.h
Normal file
9
conts/posix/mm0/include/macros.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef __MM0_MACROS_H__
|
||||
#define __MM0_MACROS_H__
|
||||
|
||||
#define __INC_ARCH(x) <arch/__ARCH__/x>
|
||||
#define __INC_SUBARCH(x) <arch/__ARCH__/__SUBARCH__/x>
|
||||
#define __INC_PLAT(x) <platform/__PLATFORM__/x>
|
||||
#define __INC_GLUE(x) <glue/__ARCH__/x>
|
||||
|
||||
#endif /* __MM0_MACROS_H__ */
|
||||
@@ -21,15 +21,11 @@ struct container_memory_regions {
|
||||
};
|
||||
extern struct container_memory_regions cont_mem_regions;
|
||||
|
||||
#define PAGER_MMAP_SEGMENT SZ_4MB
|
||||
#define PAGER_MMAP_START (page_align_up(__stack))
|
||||
#define PAGER_MMAP_END (PAGER_MMAP_START + PAGER_MMAP_SEGMENT)
|
||||
|
||||
void init_mm_descriptors(struct page_bitmap *page_map,
|
||||
struct bootdesc *bootdesc, struct membank *membank);
|
||||
void init_physmem(void);
|
||||
|
||||
int pager_address_pool_init(void);
|
||||
int pager_address_pool_init();
|
||||
void *pager_new_address(int npages);
|
||||
int pager_delete_address(void *virt_addr, int npages);
|
||||
void *pager_map_pages(struct vm_file *f, unsigned long page_offset, unsigned long npages);
|
||||
@@ -38,6 +34,7 @@ void *pager_map_page(struct vm_file *f, unsigned long page_offset);
|
||||
void pager_unmap_page(void *addr);
|
||||
void *pager_map_file_range(struct vm_file *f, unsigned long byte_offset,
|
||||
unsigned long size);
|
||||
|
||||
void *pager_validate_map_user_range2(struct tcb *user, void *userptr,
|
||||
unsigned long size, unsigned int vm_flags);
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
#include <l4/types.h>
|
||||
#include INC_GLUE(memlayout.h)
|
||||
#include <l4/lib/list.h>
|
||||
#include <l4lib/arch/types.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include L4LIB_INC_ARCH(types.h)
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
#include <l4lib/utcb.h>
|
||||
#include <lib/addr.h>
|
||||
#include <l4/api/kip.h>
|
||||
|
||||
@@ -5,10 +5,8 @@
|
||||
|
||||
int pager_validate_user_range(struct tcb *user, void *userptr, unsigned long size,
|
||||
unsigned int vm_flags);
|
||||
void *pager_validate_map_user_range(struct tcb *user, void *userptr,
|
||||
unsigned long size, unsigned int vm_flags);
|
||||
void pager_unmap_user_range(void *mapped_ptr, unsigned long size);
|
||||
|
||||
void *pager_get_user_page(struct tcb *user, void *userptr,
|
||||
unsigned long size, unsigned int vm_flags);
|
||||
int copy_user_args(struct tcb *task, struct args_struct *args,
|
||||
void *argv_user, int args_max);
|
||||
int copy_user_buf(struct tcb *task, void *buf, char *user, int maxlength,
|
||||
|
||||
@@ -11,9 +11,10 @@
|
||||
#include <l4/config.h>
|
||||
#include <l4/types.h>
|
||||
#include <task.h>
|
||||
#include <arch/mm.h>
|
||||
#include <lib/spinlock.h>
|
||||
#include <physmem.h>
|
||||
#include <linker.h>
|
||||
#include __INC_ARCH(mm.h)
|
||||
|
||||
// #define DEBUG_FAULT_HANDLING
|
||||
#ifdef DEBUG_FAULT_HANDLING
|
||||
@@ -22,6 +23,14 @@
|
||||
#define dprintf(...)
|
||||
#endif
|
||||
|
||||
/* Some task segment marks for mm0 */
|
||||
#define PAGER_MMAP_SEGMENT SZ_1MB
|
||||
#define PAGER_MMAP_START (page_align_up(__stack))
|
||||
#define PAGER_MMAP_END (PAGER_MMAP_START + PAGER_MMAP_SEGMENT)
|
||||
#define PAGER_EXT_VIRTUAL_START PAGER_MMAP_END
|
||||
#define PAGER_EXT_VIRTUAL_END (unsigned long)(PAGER_MMAP_END + SZ_2MB)
|
||||
#define PAGER_VIRTUAL_START PAGER_EXT_VIRTUAL_END
|
||||
|
||||
/* Protection flags */
|
||||
#define VM_NONE (1 << 0)
|
||||
#define VM_READ (1 << 1)
|
||||
@@ -75,6 +84,10 @@ extern struct page *page_array;
|
||||
sizeof(struct page)) + \
|
||||
membank[0].start)
|
||||
|
||||
/* Multiple conversions together */
|
||||
#define virt_to_page(x) (phys_to_page(virt_to_phys(x)))
|
||||
#define page_to_virt(x) (phys_to_virt((void *)page_to_phys(x)))
|
||||
|
||||
/* Fault data specific to this task + ptr to kernel's data */
|
||||
struct fault_data {
|
||||
fault_kdata_t *kdata; /* Generic data forged by the kernel */
|
||||
@@ -226,9 +239,12 @@ void vm_object_print(struct vm_object *vmo);
|
||||
void vm_print_objects(struct link *vmo_list);
|
||||
void vm_print_files(struct link *file_list);
|
||||
|
||||
/* Used for pre-faulting a page from mm0 */
|
||||
/* Buggy version. Used for pre-faulting a page from mm0 */
|
||||
struct page *task_prefault_page(struct tcb *task, unsigned long address,
|
||||
unsigned int vmflags);
|
||||
/* New version */
|
||||
struct page *task_prefault_smart(struct tcb *task, unsigned long address,
|
||||
unsigned int vmflags);
|
||||
struct page *page_init(struct page *page);
|
||||
struct page *find_page(struct vm_object *vmo, unsigned long page_offset);
|
||||
void *pager_map_page(struct vm_file *f, unsigned long page_offset);
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <init.h>
|
||||
#include <l4lib/arch/utcb.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include L4LIB_INC_ARCH(utcb.h)
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include <l4lib/kip.h>
|
||||
#include <l4lib/utcb.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
arch-arm
|
||||
94
conts/posix/mm0/mm/arch/arm/crt0.S
Normal file
94
conts/posix/mm0/mm/arch/arm/crt0.S
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Australian Public Licence B (OZPLB)
|
||||
*
|
||||
* Version 1-0
|
||||
*
|
||||
* Copyright (c) 2004 National ICT Australia
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Developed by: Embedded, Real-time and Operating Systems Program (ERTOS)
|
||||
* National ICT Australia
|
||||
* http://www.ertos.nicta.com.au
|
||||
*
|
||||
* Permission is granted by National ICT Australia, free of charge, to
|
||||
* any person obtaining a copy of this software and any associated
|
||||
* documentation files (the "Software") to deal with the Software without
|
||||
* restriction, including (without limitation) the rights to use, copy,
|
||||
* modify, adapt, merge, publish, distribute, communicate to the public,
|
||||
* sublicense, and/or sell, lend or rent out copies of the Software, and
|
||||
* to permit persons to whom the Software is furnished to do so, subject
|
||||
* to the following conditions:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimers.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimers in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* * Neither the name of National ICT Australia, nor the names of its
|
||||
* contributors, may be used to endorse or promote products derived
|
||||
* from this Software without specific prior written permission.
|
||||
*
|
||||
* EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
|
||||
* PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
|
||||
* NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||
* BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
|
||||
* REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
|
||||
* THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
|
||||
* ERRORS, WHETHER OR NOT DISCOVERABLE.
|
||||
*
|
||||
* TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
|
||||
* NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
|
||||
* THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
|
||||
* LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
|
||||
* OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
|
||||
* OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
|
||||
* OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
|
||||
* CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
|
||||
* DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
|
||||
* CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
|
||||
* DAMAGES OR OTHER LIABILITY.
|
||||
*
|
||||
* If applicable legislation implies representations, warranties, or
|
||||
* conditions, or imposes obligations or liability on National ICT
|
||||
* Australia or one of its contributors in respect of the Software that
|
||||
* cannot be wholly or partly excluded, restricted or modified, the
|
||||
* liability of National ICT Australia or the contributor is limited, to
|
||||
* the full extent permitted by the applicable legislation, at its
|
||||
* option, to:
|
||||
* a. in the case of goods, any one or more of the following:
|
||||
* i. the replacement of the goods or the supply of equivalent goods;
|
||||
* ii. the repair of the goods;
|
||||
* iii. the payment of the cost of replacing the goods or of acquiring
|
||||
* equivalent goods;
|
||||
* iv. the payment of the cost of having the goods repaired; or
|
||||
* b. in the case of services:
|
||||
* i. the supplying of the services again; or
|
||||
* ii. the payment of the cost of having the services supplied again.
|
||||
*
|
||||
* The construction, validity and performance of this licence is governed
|
||||
* by the laws in force in New South Wales, Australia.
|
||||
*/
|
||||
|
||||
#ifdef __thumb__
|
||||
#define bl blx
|
||||
#endif
|
||||
|
||||
.section .text.head
|
||||
.code 32
|
||||
.global _start;
|
||||
.align;
|
||||
_start:
|
||||
ldr sp, =__stack
|
||||
bl platform_init
|
||||
bl __container_init
|
||||
1:
|
||||
b 1b
|
||||
|
||||
11
conts/posix/mm0/mm/arch/arm/debug.c
Normal file
11
conts/posix/mm0/mm/arch/arm/debug.c
Normal file
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Perfmon globals
|
||||
*/
|
||||
|
||||
|
||||
#if defined(CONFIG_DEBUG_PERFMON_USER)
|
||||
|
||||
u64 perfmon_total_cycles;
|
||||
u64 current_cycles;
|
||||
|
||||
#endif
|
||||
33
conts/posix/mm0/mm/arch/arm/mm.c
Normal file
33
conts/posix/mm0/mm/arch/arm/mm.c
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*/
|
||||
#include <task.h>
|
||||
#include <vm_area.h>
|
||||
#include <l4lib/exregs.h>
|
||||
#include __INC_ARCH(mm.h)
|
||||
|
||||
#if defined(DEBUG_FAULT_HANDLING)
|
||||
void arch_print_fault_params(struct fault_data *fault)
|
||||
{
|
||||
printf("%s: Handling %s fault (%s abort) from %d. fault @ 0x%x, generic pte flags: 0x%x\n",
|
||||
__TASKNAME__, (fault->reason & VM_READ) ? "read" :
|
||||
(fault->reason & VM_WRITE) ? "write" : "exec",
|
||||
is_prefetch_abort(fault->kdata->fsr) ? "prefetch" : "data",
|
||||
fault->task->tid, fault->address, fault->pte_flags);
|
||||
}
|
||||
#else
|
||||
void arch_print_fault_params(struct fault_data *fault) { }
|
||||
#endif
|
||||
|
||||
|
||||
void fault_handle_error(struct fault_data *fault)
|
||||
{
|
||||
struct task_ids ids;
|
||||
|
||||
/* Suspend the task */
|
||||
ids.tid = fault->task->tid;
|
||||
BUG_ON(l4_thread_control(THREAD_SUSPEND, &ids) < 0);
|
||||
|
||||
BUG();
|
||||
}
|
||||
|
||||
65
conts/posix/mm0/mm/arch/arm/v5/mm.c
Normal file
65
conts/posix/mm0/mm/arch/arm/v5/mm.c
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* ARMv5 specific functions
|
||||
*
|
||||
* Copyright (C) 2008 - 2010 B Labs Ltd.
|
||||
*/
|
||||
#include <task.h>
|
||||
#include <vm_area.h>
|
||||
#include <l4lib/exregs.h>
|
||||
#include __INC_ARCH(mm.h)
|
||||
|
||||
/* Extracts generic protection flags from architecture-specific pte */
|
||||
unsigned int vm_prot_flags(pte_t pte)
|
||||
{
|
||||
unsigned int vm_prot_flags = 0;
|
||||
unsigned int rw_flags = __MAP_USR_RW & PTE_PROT_MASK;
|
||||
unsigned int ro_flags = __MAP_USR_RO & PTE_PROT_MASK;
|
||||
|
||||
/* Clear non-protection flags */
|
||||
pte &= PTE_PROT_MASK;
|
||||
|
||||
if (pte == ro_flags)
|
||||
vm_prot_flags = VM_READ | VM_EXEC;
|
||||
else if (pte == rw_flags)
|
||||
vm_prot_flags = VM_READ | VM_WRITE | VM_EXEC;
|
||||
else
|
||||
vm_prot_flags = VM_NONE;
|
||||
|
||||
return vm_prot_flags;
|
||||
}
|
||||
|
||||
/*
|
||||
* PTE STATES:
|
||||
* PTE type field: 00 (Translation fault)
|
||||
* PTE type field correct, AP bits: None (Read or Write access fault)
|
||||
* PTE type field correct, AP bits: RO (Write access fault)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Extracts arch-specific fault parameters
|
||||
* and puts them into generic format
|
||||
*/
|
||||
void set_generic_fault_params(struct fault_data *fault)
|
||||
{
|
||||
unsigned int prot_flags = vm_prot_flags(fault->kdata->pte);
|
||||
|
||||
fault->reason = 0;
|
||||
fault->pte_flags = prot_flags;
|
||||
|
||||
if (is_prefetch_abort(fault->kdata->fsr)) {
|
||||
fault->reason |= VM_READ;
|
||||
fault->address = fault->kdata->faulty_pc;
|
||||
} else {
|
||||
fault->address = fault->kdata->far;
|
||||
|
||||
/* Always assume read fault first */
|
||||
if (prot_flags & VM_NONE)
|
||||
fault->reason |= VM_READ;
|
||||
else if (prot_flags & VM_READ)
|
||||
fault->reason |= VM_WRITE;
|
||||
else
|
||||
BUG();
|
||||
}
|
||||
arch_print_fault_params(fault);
|
||||
}
|
||||
|
||||
65
conts/posix/mm0/mm/arch/arm/v6/mm.c
Normal file
65
conts/posix/mm0/mm/arch/arm/v6/mm.c
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* ARMv5 specific functions
|
||||
*
|
||||
* Copyright (C) 2008 - 2010 B Labs Ltd.
|
||||
*/
|
||||
#include <task.h>
|
||||
#include <vm_area.h>
|
||||
#include <l4lib/exregs.h>
|
||||
#include __INC_ARCH(mm.h)
|
||||
|
||||
/* Extracts generic protection flags from architecture-specific pte */
|
||||
unsigned int vm_prot_flags(pte_t pte)
|
||||
{
|
||||
unsigned int vm_prot_flags = 0;
|
||||
unsigned int rw_flags = __MAP_USR_RW & PTE_PROT_MASK;
|
||||
unsigned int ro_flags = __MAP_USR_RO & PTE_PROT_MASK;
|
||||
|
||||
/* Clear non-protection flags */
|
||||
pte &= PTE_PROT_MASK;
|
||||
|
||||
if (pte == ro_flags)
|
||||
vm_prot_flags = VM_READ | VM_EXEC;
|
||||
else if (pte == rw_flags)
|
||||
vm_prot_flags = VM_READ | VM_WRITE | VM_EXEC;
|
||||
else
|
||||
vm_prot_flags = VM_NONE;
|
||||
|
||||
return vm_prot_flags;
|
||||
}
|
||||
|
||||
/*
|
||||
* PTE STATES:
|
||||
* PTE type field: 00 (Translation fault)
|
||||
* PTE type field correct, AP bits: None (Read or Write access fault)
|
||||
* PTE type field correct, AP bits: RO (Write access fault)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Extracts arch-specific fault parameters
|
||||
* and puts them into generic format
|
||||
*/
|
||||
void set_generic_fault_params(struct fault_data *fault)
|
||||
{
|
||||
unsigned int prot_flags = vm_prot_flags(fault->kdata->pte);
|
||||
|
||||
fault->reason = 0;
|
||||
fault->pte_flags = prot_flags;
|
||||
|
||||
if (is_prefetch_abort(fault->kdata->fsr)) {
|
||||
fault->reason |= VM_READ;
|
||||
fault->address = fault->kdata->faulty_pc;
|
||||
} else {
|
||||
fault->address = fault->kdata->far;
|
||||
|
||||
/* Always assume read fault first */
|
||||
if (prot_flags & VM_NONE)
|
||||
fault->reason |= VM_READ;
|
||||
else if (prot_flags & VM_READ)
|
||||
fault->reason |= VM_WRITE;
|
||||
else
|
||||
BUG();
|
||||
}
|
||||
arch_print_fault_params(fault);
|
||||
}
|
||||
|
||||
77
conts/posix/mm0/mm/arch/arm/v7/mm.c
Normal file
77
conts/posix/mm0/mm/arch/arm/v7/mm.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* ARMv7 specific functions
|
||||
*
|
||||
* Copyright (C) 2008 - 2010 B Labs Ltd.
|
||||
*/
|
||||
#include <task.h>
|
||||
#include <vm_area.h>
|
||||
#include <l4lib/exregs.h>
|
||||
#include __INC_ARCH(mm.h)
|
||||
#include INC_SUBARCH(mm.h)
|
||||
#include INC_SUBARCH(exception.h)
|
||||
|
||||
/* Get simplified access permissions */
|
||||
int pte_get_access_simple(pte_t pte)
|
||||
{
|
||||
/* Place AP[2] and AP[1] in [1:0] positions and return */
|
||||
return (((pte >> PTE_AP2_BIT) & 1) << 1)
|
||||
| ((pte >> PTE_AP1_BIT) & 1);
|
||||
}
|
||||
|
||||
int is_translation_fault(u32 fsr)
|
||||
{
|
||||
return (fsr & FSR_FS_MASK) == ABORT_TRANSLATION_PAGE;
|
||||
}
|
||||
|
||||
unsigned int vm_prot_flags(pte_t pte, u32 fsr)
|
||||
{
|
||||
unsigned int pte_prot_flags = 0;
|
||||
|
||||
/* Translation fault means no permissions */
|
||||
if (is_translation_fault(fsr))
|
||||
return VM_NONE;
|
||||
|
||||
/* Check simplified permission bits */
|
||||
switch (pte_get_access_simple(pte)) {
|
||||
case AP_SIMPLE_USER_RW_KERN_RW:
|
||||
pte_prot_flags |= VM_WRITE;
|
||||
case AP_SIMPLE_USER_RO_KERN_RO:
|
||||
pte_prot_flags |= VM_READ;
|
||||
|
||||
/* Also, check exec never bit */
|
||||
if (!(pte & (1 << PTE_XN_BIT)))
|
||||
pte_prot_flags |= VM_EXEC;
|
||||
break;
|
||||
case AP_SIMPLE_USER_NONE_KERN_RW:
|
||||
case AP_SIMPLE_USER_NONE_KERN_RO:
|
||||
default:
|
||||
pte_prot_flags = VM_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
return pte_prot_flags;
|
||||
}
|
||||
|
||||
void set_generic_fault_params(struct fault_data *fault)
|
||||
{
|
||||
fault->pte_flags = vm_prot_flags(fault->kdata->pte, fault->kdata->fsr);
|
||||
fault->reason = 0;
|
||||
|
||||
/*
|
||||
* Prefetch fault denotes exec fault.
|
||||
*/
|
||||
if (is_prefetch_abort(fault->kdata->fsr)) {
|
||||
fault->reason |= VM_EXEC;
|
||||
fault->address = fault->kdata->faulty_pc;
|
||||
} else {
|
||||
fault->address = fault->kdata->far;
|
||||
|
||||
/* Write-not-read bit determines fault */
|
||||
if (fault->kdata->fsr & (1 << DFSR_WNR_BIT))
|
||||
fault->reason |= VM_WRITE;
|
||||
else
|
||||
fault->reason |= VM_READ;
|
||||
}
|
||||
arch_print_fault_params(fault);
|
||||
}
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
#include <bootm.h>
|
||||
#include <init.h>
|
||||
#include <linker.h>
|
||||
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
|
||||
extern unsigned long pager_offset;
|
||||
|
||||
|
||||
@@ -7,12 +7,11 @@
|
||||
#include <init.h>
|
||||
#include <memory.h>
|
||||
#include <capability.h>
|
||||
#include <l4lib/capability/cap_print.h>
|
||||
#include <l4/api/errno.h>
|
||||
#include <l4/lib/list.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
#include <l4/generic/cap-types.h> /* TODO: Move this to API */
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include <malloc/malloc.h>
|
||||
#include <user.h>
|
||||
|
||||
@@ -504,15 +503,14 @@ int sys_request_cap(struct tcb *task, struct capability *__cap_userptr)
|
||||
struct capability *cap;
|
||||
int ret;
|
||||
|
||||
if (!(cap = pager_validate_map_user_range(task, __cap_userptr,
|
||||
sizeof(*__cap_userptr),
|
||||
VM_READ | VM_WRITE)))
|
||||
if (!(cap = pager_get_user_page(task, __cap_userptr,
|
||||
sizeof(*__cap_userptr),
|
||||
VM_READ | VM_WRITE)))
|
||||
return -EFAULT;
|
||||
|
||||
/* Only support IPC requests for now */
|
||||
if (cap_type(cap) != CAP_TYPE_IPC) {
|
||||
ret = -EPERM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Validate rest of the fields */
|
||||
@@ -560,7 +558,6 @@ int sys_request_cap(struct tcb *task, struct capability *__cap_userptr)
|
||||
}
|
||||
|
||||
out:
|
||||
pager_unmap_user_range(cap, sizeof(*cap));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2008 Bahadir Balban
|
||||
*/
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <l4lib/exregs.h>
|
||||
#include <l4/api/errno.h>
|
||||
@@ -111,6 +111,7 @@ int sys_clone(struct tcb *parent,
|
||||
|
||||
if (!child_stack)
|
||||
return -EINVAL;
|
||||
BUG_ON((unsigned long)child_stack < 0x10000);
|
||||
|
||||
if (clone_flags & CLONE_VM) {
|
||||
flags |= TCB_SHARED_VM;
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2008 Bahadir Balban
|
||||
*/
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <l4lib/types.h>
|
||||
#include <l4/macros.h>
|
||||
|
||||
@@ -11,12 +11,12 @@
|
||||
#include <utcb.h>
|
||||
#include <vm_area.h>
|
||||
#include <syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/exregs.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <malloc/malloc.h>
|
||||
#include <l4/api/space.h>
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
|
||||
|
||||
/* Closes all file descriptors of a task */
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
/*
|
||||
* Page fault handling.
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Bahadir Balban
|
||||
* Copyright (C) 2007, 2008-2010 Bahadir Bilgehan Balban
|
||||
*/
|
||||
#include <vm_area.h>
|
||||
#include <task.h>
|
||||
#include <mm/alloc_page.h>
|
||||
#include <malloc/malloc.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
#include INC_SUBARCH(mm.h)
|
||||
#include <arch/mm.h>
|
||||
#include <l4/generic/space.h>
|
||||
#include <l4/api/errno.h>
|
||||
#include <string.h>
|
||||
@@ -20,6 +15,12 @@
|
||||
#include <file.h>
|
||||
#include <test.h>
|
||||
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include INC_GLUE(memory.h)
|
||||
#include INC_SUBARCH(mm.h)
|
||||
#include __INC_ARCH(mm.h)
|
||||
#include __INC_ARCH(debug.h)
|
||||
|
||||
/* Given a page and the vma it is in, returns that page's virtual address */
|
||||
unsigned long vma_page_to_virtual(struct vm_area *vma, struct page *page)
|
||||
@@ -245,28 +246,16 @@ struct vm_obj_link *vma_create_shadow(void)
|
||||
/* Allocates a new page, copies the original onto it and returns. */
|
||||
struct page *copy_to_new_page(struct page *orig)
|
||||
{
|
||||
void *new_vaddr, *vaddr, *paddr;
|
||||
struct page *new;
|
||||
void *paddr = alloc_page(1);
|
||||
|
||||
BUG_ON(!(paddr = alloc_page(1)));
|
||||
|
||||
new = phys_to_page(paddr);
|
||||
|
||||
/* Map the new and orig page to self */
|
||||
new_vaddr = l4_map_helper(paddr, 1);
|
||||
vaddr = l4_map_helper((void *)page_to_phys(orig), 1);
|
||||
BUG_ON(!paddr);
|
||||
|
||||
/* Copy the page into new page */
|
||||
memcpy(new_vaddr, vaddr, PAGE_SIZE);
|
||||
memcpy(phys_to_virt(paddr), page_to_virt(orig), PAGE_SIZE);
|
||||
|
||||
/* Unmap both pages from current task. */
|
||||
l4_unmap_helper(vaddr, 1);
|
||||
l4_unmap_helper(new_vaddr, 1);
|
||||
|
||||
return new;
|
||||
return phys_to_page(paddr);
|
||||
}
|
||||
|
||||
|
||||
/* Copy all mapped object link stack from vma to new vma */
|
||||
int vma_copy_links(struct vm_area *new_vma, struct vm_area *vma)
|
||||
{
|
||||
@@ -649,96 +638,140 @@ struct page *copy_on_write(struct fault_data *fault)
|
||||
* FIXME: Add VM_DIRTY bit for every page that has write-faulted.
|
||||
*/
|
||||
|
||||
struct page *__do_page_fault(struct fault_data *fault)
|
||||
/* Handle read faults */
|
||||
struct page *page_read_fault(struct fault_data *fault)
|
||||
{
|
||||
unsigned int reason = fault->reason;
|
||||
unsigned int vma_flags = fault->vma->flags;
|
||||
unsigned int pte_flags = fault->pte_flags;
|
||||
struct vm_area *vma = fault->vma;
|
||||
struct vm_obj_link *vmo_link;
|
||||
unsigned long file_offset;
|
||||
struct page *page;
|
||||
struct page *page = 0;
|
||||
|
||||
/* Handle read */
|
||||
if ((reason & VM_READ) && (pte_flags & VM_NONE)) {
|
||||
file_offset = fault_to_file_offset(fault);
|
||||
file_offset = fault_to_file_offset(fault);
|
||||
|
||||
/* Get the first object, either original file or a shadow */
|
||||
if (!(vmo_link = vma_next_link(&vma->vm_obj_list, &vma->vm_obj_list))) {
|
||||
printf("%s:%s: No vm object in vma!\n",
|
||||
__TASKNAME__, __FUNCTION__);
|
||||
/* Get the first object, either original file or a shadow */
|
||||
if (!(vmo_link = vma_next_link(&vma->vm_obj_list, &vma->vm_obj_list))) {
|
||||
printf("%s:%s: No vm object in vma!\n",
|
||||
__TASKNAME__, __FUNCTION__);
|
||||
BUG();
|
||||
}
|
||||
|
||||
/* Traverse the list of read-only vm objects and search for the page */
|
||||
while (IS_ERR(page = vmo_link->obj->pager->ops.page_in(vmo_link->obj,
|
||||
file_offset))) {
|
||||
if (!(vmo_link = vma_next_link(&vmo_link->list,
|
||||
&vma->vm_obj_list))) {
|
||||
printf("%s:%s: Traversed all shadows and the original "
|
||||
"file's vm_object, but could not find the "
|
||||
"faulty page in this vma.\n",__TASKNAME__,
|
||||
__FUNCTION__);
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
BUG_ON(!page);
|
||||
|
||||
/* Traverse the list of read-only vm objects and search for the page */
|
||||
while (IS_ERR(page = vmo_link->obj->pager->ops.page_in(vmo_link->obj,
|
||||
file_offset))) {
|
||||
if (!(vmo_link = vma_next_link(&vmo_link->list,
|
||||
&vma->vm_obj_list))) {
|
||||
printf("%s:%s: Traversed all shadows and the original "
|
||||
"file's vm_object, but could not find the "
|
||||
"faulty page in this vma.\n",__TASKNAME__,
|
||||
__FUNCTION__);
|
||||
return page;
|
||||
}
|
||||
|
||||
struct page *page_write_fault(struct fault_data *fault)
|
||||
{
|
||||
unsigned int vma_flags = fault->vma->flags;
|
||||
struct vm_area *vma = fault->vma;
|
||||
struct vm_obj_link *vmo_link;
|
||||
unsigned long file_offset;
|
||||
struct page *page = 0;
|
||||
|
||||
/* Copy-on-write. All private vmas are always COW */
|
||||
if (vma_flags & VMA_PRIVATE) {
|
||||
BUG_ON(IS_ERR(page = copy_on_write(fault)));
|
||||
|
||||
/*
|
||||
* This handles shared pages that are both anon and non-anon.
|
||||
*/
|
||||
} else if ((vma_flags & VMA_SHARED)) {
|
||||
file_offset = fault_to_file_offset(fault);
|
||||
|
||||
/* Don't traverse, just take the first object */
|
||||
BUG_ON(!(vmo_link = vma_next_link(&vma->vm_obj_list,
|
||||
&vma->vm_obj_list)));
|
||||
|
||||
/* Get the page from its pager */
|
||||
if (IS_ERR(page = vmo_link->obj->pager->ops.page_in(vmo_link->obj,
|
||||
file_offset))) {
|
||||
/*
|
||||
* Writable page does not exist,
|
||||
* if it is anonymous, it needs to be COW'ed,
|
||||
* otherwise the file must have paged-in this
|
||||
* page, so its a bug.
|
||||
*/
|
||||
if (vma_flags & VMA_ANONYMOUS) {
|
||||
BUG_ON(IS_ERR(page = copy_on_write(fault)));
|
||||
return page;
|
||||
} else {
|
||||
printf("%s: Could not obtain faulty "
|
||||
"page from regular file.\n",
|
||||
__TASKNAME__);
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
BUG_ON(!page);
|
||||
}
|
||||
|
||||
/* Handle write */
|
||||
if ((reason & VM_WRITE) && (pte_flags & VM_READ)) {
|
||||
/* Copy-on-write. All private vmas are always COW */
|
||||
if (vma_flags & VMA_PRIVATE) {
|
||||
BUG_ON(IS_ERR(page = copy_on_write(fault)));
|
||||
|
||||
/*
|
||||
* This handles shared pages that are both anon and non-anon.
|
||||
* Page and object are now dirty. Currently it's
|
||||
* only relevant for file-backed shared objects.
|
||||
*/
|
||||
} else if ((vma_flags & VMA_SHARED)) {
|
||||
file_offset = fault_to_file_offset(fault);
|
||||
page->flags |= VM_DIRTY;
|
||||
page->owner->flags |= VM_DIRTY;
|
||||
} else
|
||||
BUG();
|
||||
|
||||
/* Don't traverse, just take the first object */
|
||||
BUG_ON(!(vmo_link = vma_next_link(&vma->vm_obj_list,
|
||||
&vma->vm_obj_list)));
|
||||
return page;
|
||||
}
|
||||
|
||||
/* Get the page from its pager */
|
||||
if (IS_ERR(page = vmo_link->obj->pager->ops.page_in(vmo_link->obj,
|
||||
file_offset))) {
|
||||
/*
|
||||
* Writable page does not exist,
|
||||
* if it is anonymous, it needs to be COW'ed,
|
||||
* otherwise the file must have paged-in this
|
||||
* page, so its a bug.
|
||||
*/
|
||||
if (vma_flags & VMA_ANONYMOUS) {
|
||||
BUG_ON(IS_ERR(page = copy_on_write(fault)));
|
||||
goto out_success;
|
||||
} else {
|
||||
printf("%s: Could not obtain faulty "
|
||||
"page from regular file.\n",
|
||||
__TASKNAME__);
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
struct page *__do_page_fault(struct fault_data *fault)
|
||||
{
|
||||
unsigned int reason = fault->reason;
|
||||
unsigned int pte_flags = fault->pte_flags;
|
||||
unsigned int map_flags = 0;
|
||||
struct page *page = 0;
|
||||
|
||||
/*
|
||||
* Page and object are now dirty. Currently it's
|
||||
* only relevant for file-backed shared objects.
|
||||
*/
|
||||
page->flags |= VM_DIRTY;
|
||||
page->owner->flags |= VM_DIRTY;
|
||||
} else
|
||||
BUG();
|
||||
if ((reason & VM_READ) && (pte_flags & VM_NONE)) {
|
||||
page = page_read_fault(fault);
|
||||
map_flags = MAP_USR_RO;
|
||||
|
||||
} else if ((reason & VM_WRITE) && (pte_flags & VM_NONE)) {
|
||||
page = page_read_fault(fault);
|
||||
page = page_write_fault(fault);
|
||||
map_flags = MAP_USR_RW;
|
||||
|
||||
} else if ((reason & VM_EXEC) && (pte_flags & VM_NONE)) {
|
||||
page = page_read_fault(fault);
|
||||
map_flags = MAP_USR_RX;
|
||||
|
||||
} else if ((reason & VM_EXEC) && (pte_flags & VM_READ)) {
|
||||
/* Retrieve already paged in file */
|
||||
page = page_read_fault(fault);
|
||||
if (pte_flags & VM_WRITE)
|
||||
map_flags = MAP_USR_RWX;
|
||||
else
|
||||
map_flags = MAP_USR_RX;
|
||||
|
||||
} else if ((reason & VM_WRITE) && (pte_flags & VM_READ)) {
|
||||
page = page_write_fault(fault);
|
||||
if (pte_flags & VM_EXEC)
|
||||
map_flags = MAP_USR_RWX;
|
||||
else
|
||||
map_flags = MAP_USR_RW;
|
||||
|
||||
} else {
|
||||
printf("mm0: Unhandled page fault.\n");
|
||||
BUG();
|
||||
}
|
||||
|
||||
out_success:
|
||||
BUG_ON(!page);
|
||||
|
||||
/* Map the new page to faulty task */
|
||||
l4_map((void *)page_to_phys(page),
|
||||
(void *)page_align(fault->address), 1,
|
||||
(reason & VM_READ) ? MAP_USR_RO_FLAGS : MAP_USR_RW_FLAGS,
|
||||
fault->task->tid);
|
||||
dprintf("%s: Mapped 0x%x as writable to tid %d.\n", __TASKNAME__,
|
||||
page_align(fault->address), fault->task->tid);
|
||||
map_flags, fault->task->tid);
|
||||
// vm_object_print(page->owner);
|
||||
|
||||
return page;
|
||||
@@ -796,7 +829,7 @@ int vm_freeze_shadows(struct tcb *task)
|
||||
/* Map the page as read-only */
|
||||
l4_map((void *)page_to_phys(p),
|
||||
(void *)virtual, 1,
|
||||
MAP_USR_RO_FLAGS, task->tid);
|
||||
MAP_USR_RO, task->tid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -860,11 +893,6 @@ struct page *do_page_fault(struct fault_data *fault)
|
||||
fault_handle_error(fault);
|
||||
}
|
||||
|
||||
if ((reason & VM_EXEC) && (vma_flags & VM_EXEC)) {
|
||||
printf("Exec faults unsupported yet.\n");
|
||||
fault_handle_error(fault);
|
||||
}
|
||||
|
||||
/* Handle legitimate faults */
|
||||
return __do_page_fault(fault);
|
||||
}
|
||||
@@ -890,20 +918,145 @@ struct page *page_fault_handler(struct tcb *sender, fault_kdata_t *fkdata)
|
||||
return do_page_fault(&fault);
|
||||
}
|
||||
|
||||
int vm_compare_prot_flags(unsigned int current, unsigned int needed)
|
||||
static inline unsigned int pte_to_map_flags(unsigned int pte_flags)
|
||||
{
|
||||
current &= VM_PROT_MASK;
|
||||
needed &= VM_PROT_MASK;
|
||||
unsigned int map_flags;
|
||||
|
||||
if (needed & VM_READ)
|
||||
if (current & (VM_READ | VM_WRITE))
|
||||
return 1;
|
||||
switch(pte_flags) {
|
||||
case VM_READ:
|
||||
map_flags = MAP_USR_RO;
|
||||
break;
|
||||
case (VM_READ | VM_WRITE):
|
||||
map_flags = MAP_USR_RW;
|
||||
break;
|
||||
case (VM_READ | VM_WRITE | VM_EXEC):
|
||||
map_flags = MAP_USR_RWX;
|
||||
break;
|
||||
case (VM_READ | VM_EXEC):
|
||||
map_flags = MAP_USR_RX;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
||||
if (needed & VM_WRITE &&
|
||||
(current & VM_WRITE))
|
||||
return 1;
|
||||
return map_flags;
|
||||
}
|
||||
|
||||
return 0;
|
||||
/*
|
||||
* Prefaults a page of a task. The catch is that the page may already
|
||||
* have been faulted with even more progress than the desired
|
||||
* flags would progress in the fault (e.g. read-faulting a
|
||||
* copy-on-write'd page).
|
||||
*
|
||||
* This function detects whether progress is necessary or not by
|
||||
* inspecting the vma's vm_object chain state.
|
||||
*
|
||||
* Generally both read-fault and write-fault paths are repeatable, in
|
||||
* the sense that an already faulted page may be safely re-faulted again
|
||||
* and again, be it a read-only or copy-on-write'd page.
|
||||
*
|
||||
* The retrieval of the same page in a repetitive fashion is safe,
|
||||
* but while it also seems to appear safe, it is unnecessary to downgrade
|
||||
* or change mapping permissions of a page. E.g. make a copy-on-write'd
|
||||
* page read-only by doing a blind read-fault on it.
|
||||
*
|
||||
* Hence this function checks whether a fault is necessary and simply
|
||||
* returns if it isn't.
|
||||
*
|
||||
* FIXME: Escalate any page fault errors like a civilized function!
|
||||
*/
|
||||
struct page *task_prefault_smart(struct tcb *task, unsigned long address,
|
||||
unsigned int wanted_flags)
|
||||
{
|
||||
struct vm_obj_link *vmo_link;
|
||||
unsigned long file_offset;
|
||||
unsigned int vma_flags, pte_flags;
|
||||
struct vm_area *vma;
|
||||
struct page *page;
|
||||
int err;
|
||||
|
||||
struct fault_data fault = {
|
||||
.task = task,
|
||||
.address = address,
|
||||
};
|
||||
|
||||
/* Find the vma */
|
||||
if (!(fault.vma = find_vma(fault.address,
|
||||
&fault.task->vm_area_head->list))) {
|
||||
dprintf("%s: Invalid: No vma for given address. %d\n",
|
||||
__FUNCTION__, -EINVAL);
|
||||
return PTR_ERR(-EINVAL);
|
||||
}
|
||||
|
||||
/* Read fault, repetitive safe */
|
||||
if (wanted_flags & VM_READ)
|
||||
if (IS_ERR(page = page_read_fault(&fault)))
|
||||
return page;
|
||||
|
||||
/* Write fault, repetitive safe */
|
||||
if (wanted_flags & VM_WRITE)
|
||||
if (IS_ERR(page = page_write_fault(&fault)))
|
||||
return page;
|
||||
|
||||
/*
|
||||
* If we came this far, it means we have more
|
||||
* permissions than VM_NONE.
|
||||
*
|
||||
* Now we _must_ find out what those page
|
||||
* protection flags were, and do this without
|
||||
* needing to inspect any ptes.
|
||||
*
|
||||
* We don't want to downgrade a RW page to RO again.
|
||||
*/
|
||||
file_offset = fault_to_file_offset(&fault);
|
||||
vma_flags = fault.vma->flags;
|
||||
vma = fault.vma;
|
||||
|
||||
/* Get the topmost vm_object */
|
||||
if (!(vmo_link = vma_next_link(&vma->vm_obj_list,
|
||||
&vma->vm_obj_list))) {
|
||||
printf("%s:%s: No vm object in vma!\n",
|
||||
__TASKNAME__, __FUNCTION__);
|
||||
BUG();
|
||||
}
|
||||
|
||||
/* Traverse the list of vm objects and search for the page */
|
||||
while (IS_ERR(page = vmo_link->obj->pager->ops.page_in(vmo_link->obj,
|
||||
file_offset))) {
|
||||
if (!(vmo_link = vma_next_link(&vmo_link->list,
|
||||
&vma->vm_obj_list))) {
|
||||
printf("%s:%s: Traversed all shadows and the original "
|
||||
"file's vm_object, but could not find the "
|
||||
"faulty page in this vma.\n",__TASKNAME__,
|
||||
__FUNCTION__);
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
/* Use flags for the vm_object containing the page */
|
||||
if (vmo_link->obj->flags & VM_WRITE)
|
||||
pte_flags = VM_WRITE | VM_READ;
|
||||
else
|
||||
pte_flags = VM_READ;
|
||||
|
||||
/*
|
||||
* Now check vma flags for adding the VM_EXEC
|
||||
* The real pte may not have this flag yet, but
|
||||
* it is allowed to have it and it doesn't harm.
|
||||
*/
|
||||
if (vma_flags & VM_EXEC)
|
||||
pte_flags |= VM_EXEC;
|
||||
|
||||
/* Map the page to task using these flags */
|
||||
if ((err = l4_map((void *)page_to_phys(page),
|
||||
(void *)page_align(fault.address), 1,
|
||||
pte_to_map_flags(pte_flags),
|
||||
fault.task->tid)) < 0) {
|
||||
printf("l4_map() failed. err=%d\n", err);
|
||||
BUG();
|
||||
}
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -914,6 +1067,16 @@ int vm_compare_prot_flags(unsigned int current, unsigned int needed)
|
||||
struct page *task_prefault_page(struct tcb *task, unsigned long address,
|
||||
unsigned int vmflags)
|
||||
{
|
||||
struct page *ret;
|
||||
|
||||
perfmon_reset_start_cyccnt();
|
||||
ret = task_prefault_smart(task, address, vmflags);
|
||||
|
||||
debug_record_cycles("task_prefault_smart");
|
||||
|
||||
return ret;
|
||||
|
||||
#if 0
|
||||
struct page *p;
|
||||
struct fault_data fault = {
|
||||
.task = task,
|
||||
@@ -949,6 +1112,23 @@ struct page *task_prefault_page(struct tcb *task, unsigned long address,
|
||||
BUG_ON(vmflags & ~(VM_READ | VM_WRITE));
|
||||
|
||||
return p;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int vm_compare_prot_flags(unsigned int current, unsigned int needed)
|
||||
{
|
||||
current &= VM_PROT_MASK;
|
||||
needed &= VM_PROT_MASK;
|
||||
|
||||
if (needed & VM_READ)
|
||||
if (current & (VM_READ | VM_WRITE))
|
||||
return 1;
|
||||
|
||||
if (needed & VM_WRITE &&
|
||||
(current & VM_WRITE))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
#include <l4/macros.h>
|
||||
#include <l4/api/errno.h>
|
||||
#include <l4lib/types.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <l4/api/kip.h>
|
||||
#include <posix/sys/types.h>
|
||||
@@ -43,8 +43,8 @@ int page_copy(struct page *dst, struct page *src,
|
||||
BUG_ON(dst_offset + size > PAGE_SIZE);
|
||||
BUG_ON(src_offset + size > PAGE_SIZE);
|
||||
|
||||
dstvaddr = l4_map_helper((void *)page_to_phys(dst), 1);
|
||||
srcvaddr = l4_map_helper((void *)page_to_phys(src), 1);
|
||||
dstvaddr = page_to_virt(dst);
|
||||
srcvaddr = page_to_virt(src);
|
||||
/*
|
||||
printf("%s: Copying from page with offset %lx to page with offset %lx\n"
|
||||
"src copy offset: 0x%lx, dst copy offset: 0x%lx, copy size: %lx\n",
|
||||
@@ -56,9 +56,6 @@ int page_copy(struct page *dst, struct page *src,
|
||||
|
||||
memcpy(dstvaddr + dst_offset, srcvaddr + src_offset, size);
|
||||
|
||||
l4_unmap_helper(dstvaddr, 1);
|
||||
l4_unmap_helper(srcvaddr, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -552,16 +549,16 @@ int copy_cache_pages(struct vm_file *vmfile, struct tcb *task, void *buf,
|
||||
copysize = min(copysize, PAGE_SIZE - page_offset(task_offset));
|
||||
|
||||
if (read)
|
||||
page_copy(task_prefault_page(task, task_offset,
|
||||
VM_READ | VM_WRITE),
|
||||
page_copy(task_prefault_smart(task, task_offset,
|
||||
VM_READ | VM_WRITE),
|
||||
file_page,
|
||||
page_offset(task_offset),
|
||||
page_offset(file_offset),
|
||||
copysize);
|
||||
else
|
||||
page_copy(file_page,
|
||||
task_prefault_page(task, task_offset,
|
||||
VM_READ),
|
||||
task_prefault_smart(task, task_offset,
|
||||
VM_READ),
|
||||
page_offset(file_offset),
|
||||
page_offset(task_offset),
|
||||
copysize);
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
*
|
||||
* Copyright (C) 2007 - 2009 Bahadir Balban
|
||||
*/
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include __INC_ARCH(debug.h)
|
||||
#include <l4lib/utcb.h>
|
||||
#include <l4lib/exregs.h>
|
||||
#include <l4/lib/list.h>
|
||||
@@ -229,6 +230,8 @@ void init_physmem_secondary(struct membank *membank)
|
||||
{
|
||||
struct page_bitmap *pmap = initdata.page_map;
|
||||
int npages = pmap->pfn_end - pmap->pfn_start;
|
||||
void *virtual_start;
|
||||
int err;
|
||||
|
||||
/*
|
||||
* Allocation marks for the struct
|
||||
@@ -253,17 +256,6 @@ void init_physmem_secondary(struct membank *membank)
|
||||
*/
|
||||
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;
|
||||
|
||||
@@ -311,7 +303,34 @@ void init_physmem_secondary(struct membank *membank)
|
||||
|
||||
/* Test that page/phys macros work */
|
||||
BUG_ON(phys_to_page(page_to_phys(&page_array[5]))
|
||||
!= &page_array[5])
|
||||
!= &page_array[5]);
|
||||
|
||||
/* Now map all physical pages to virtual correspondents */
|
||||
virtual_start = (void *)PAGER_VIRTUAL_START;
|
||||
if ((err = l4_map((void *)membank[0].start,
|
||||
virtual_start,
|
||||
__pfn(membank[0].end - membank[0].start),
|
||||
MAP_USR_RW, self_tid())) < 0) {
|
||||
printk("FATAL: Could not map all physical pages to "
|
||||
"virtual. err=%d\n", err);
|
||||
BUG();
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf("Virtual offset: %p\n", virtual_start);
|
||||
printf("Physical page offset: 0x%lx\n", membank[0].start);
|
||||
printf("page address: 0x%lx\n", (unsigned long)&page_array[5]);
|
||||
printf("page_to_virt: %p\n", page_to_virt(&page_array[5]));
|
||||
printf("virt_to_phys, virtual_start: %p\n", virt_to_phys(virtual_start));
|
||||
printf("page_to_virt_to_phys: %p\n", virt_to_phys(page_to_virt(&page_array[5])));
|
||||
printf("page_to_phys: 0x%lx\n", page_to_phys(&page_array[5]));
|
||||
#endif
|
||||
|
||||
/* Now test that virt/phys macros work */
|
||||
BUG_ON(virt_to_phys(page_to_virt(&page_array[5]))
|
||||
!= (void *)page_to_phys(&page_array[5]));
|
||||
BUG_ON(virt_to_page(page_to_virt(&page_array[5]))
|
||||
!= &page_array[5]);
|
||||
}
|
||||
|
||||
|
||||
@@ -354,6 +373,7 @@ void init_physmem_primary()
|
||||
physmem.numpages = physmem.end - physmem.start;
|
||||
}
|
||||
|
||||
|
||||
void init_physmem(void)
|
||||
{
|
||||
init_physmem_primary();
|
||||
@@ -377,6 +397,9 @@ void copy_init_process(void)
|
||||
void *mapped;
|
||||
int err;
|
||||
|
||||
/* Measure performance, if enabled */
|
||||
perfmon_reset_start_cyccnt();
|
||||
|
||||
if ((fd = sys_open(self, "/test0", O_TRUNC |
|
||||
O_RDWR | O_CREAT, 0)) < 0) {
|
||||
printf("FATAL: Could not open file "
|
||||
@@ -384,6 +407,8 @@ void copy_init_process(void)
|
||||
BUG();
|
||||
}
|
||||
|
||||
debug_record_cycles("sys_open");
|
||||
|
||||
init_img = bootdesc_get_image_byname("test0");
|
||||
img_size = page_align_up(init_img->phys_end) -
|
||||
page_align(init_img->phys_start);
|
||||
@@ -407,6 +432,8 @@ void copy_init_process(void)
|
||||
BUG();
|
||||
}
|
||||
|
||||
debug_record_cycles("Until after do_mmap");
|
||||
|
||||
/* Prefault it */
|
||||
if ((err = task_prefault_range(self, (unsigned long)mapped,
|
||||
img_size, VM_READ | VM_WRITE))
|
||||
@@ -415,26 +442,38 @@ void copy_init_process(void)
|
||||
BUG();
|
||||
}
|
||||
|
||||
|
||||
/* Copy the raw image to anon region */
|
||||
memcpy(mapped, init_img_start, img_size);
|
||||
|
||||
|
||||
debug_record_cycles("memcpy image");
|
||||
|
||||
|
||||
/* Write it to real file from anon region */
|
||||
sys_write(find_task(self_tid()), fd, mapped, img_size);
|
||||
|
||||
debug_record_cycles("sys_write");
|
||||
|
||||
/* Close file */
|
||||
sys_close(find_task(self_tid()), fd);
|
||||
|
||||
|
||||
debug_record_cycles("sys_close");
|
||||
|
||||
/* Unmap anon region */
|
||||
do_munmap(self, (unsigned long)mapped, __pfn(img_size));
|
||||
|
||||
/* Unmap raw virtual range for image memory */
|
||||
l4_unmap_helper(init_img_start,__pfn(img_size));
|
||||
|
||||
debug_record_cycles("Final do_munmap/l4_unmap");
|
||||
|
||||
}
|
||||
|
||||
void start_init_process(void)
|
||||
{
|
||||
/* Copy raw test0 elf image from memory to memfs first */
|
||||
|
||||
copy_init_process();
|
||||
|
||||
init_execve("/test0");
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <l4/types.h>
|
||||
#include <l4/api/errno.h>
|
||||
#include <l4/generic/space.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include INC_GLUE(memory.h)
|
||||
#include INC_SUBARCH(mm.h)
|
||||
#include <memory.h>
|
||||
@@ -30,6 +30,8 @@ struct address_pool pager_vaddr_pool;
|
||||
/* Bitmap size to represent an address pool of 256 MB. */
|
||||
#define ADDRESS_POOL_256MB 2048
|
||||
|
||||
unsigned long free_virtual_address_start;
|
||||
|
||||
/* Same as a regular id pool except that its bitmap size is fixed */
|
||||
static struct pager_virtual_address_id_pool {
|
||||
int nwords;
|
||||
@@ -60,8 +62,8 @@ int pager_address_pool_init(void)
|
||||
address_pool_init_with_idpool(&pager_vaddr_pool,
|
||||
(struct id_pool *)
|
||||
&pager_virtual_address_id_pool,
|
||||
PAGER_MMAP_END,
|
||||
__pfn_to_addr(cont_mem_regions.pager->end));
|
||||
PAGER_EXT_VIRTUAL_START,
|
||||
PAGER_EXT_VIRTUAL_END);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -126,7 +128,7 @@ void *pager_map_pages(struct vm_file *f, unsigned long page_offset, unsigned lon
|
||||
/* Map pages contiguously one by one */
|
||||
for (unsigned long pfn = page_offset; pfn < page_offset + npages; pfn++) {
|
||||
BUG_ON(!(p = find_page(&f->vm_obj, pfn)))
|
||||
l4_map((void *)page_to_phys(p), addr, 1, MAP_USR_RW_FLAGS, self_tid());
|
||||
l4_map((void *)page_to_phys(p), addr, 1, MAP_USR_RW, self_tid());
|
||||
addr += PAGE_SIZE;
|
||||
}
|
||||
|
||||
@@ -192,7 +194,7 @@ void *pager_validate_map_user_range2(struct tcb *user, void *userptr,
|
||||
}
|
||||
|
||||
l4_map((void *)page_to_phys(p),
|
||||
virt, 1, MAP_USR_RW_FLAGS, self_tid());
|
||||
virt, 1, MAP_USR_RW, self_tid());
|
||||
virt += PAGE_SIZE;
|
||||
}
|
||||
|
||||
@@ -207,3 +209,25 @@ void *pager_validate_map_user_range2(struct tcb *user, void *userptr,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find the page's offset from membank physical start,
|
||||
* simply add the same offset to virtual start
|
||||
*/
|
||||
void *phys_to_virt(void *p)
|
||||
{
|
||||
unsigned long paddr = (unsigned long)p;
|
||||
|
||||
return (void *)(paddr - membank[0].start + PAGER_VIRTUAL_START);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the page's offset from virtual start, add it to membank
|
||||
* physical start offset
|
||||
*/
|
||||
void *virt_to_phys(void *v)
|
||||
{
|
||||
unsigned long vaddr = (unsigned long)v;
|
||||
|
||||
return (void *)(vaddr - PAGER_VIRTUAL_START + membank[0].start);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
#include <malloc/malloc.h>
|
||||
#include INC_API(errno.h)
|
||||
#include <posix/sys/types.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include <memory.h>
|
||||
#include <task.h>
|
||||
#include <mmap.h>
|
||||
@@ -401,17 +401,15 @@ void *sys_mmap(struct tcb *task, struct sys_mmap_args *args)
|
||||
struct sys_mmap_args *mapped_args;
|
||||
void *ret;
|
||||
|
||||
if (!(mapped_args = pager_validate_map_user_range(task, args,
|
||||
sizeof(*args),
|
||||
VM_READ | VM_WRITE)))
|
||||
if (!(mapped_args = pager_get_user_page(task, args,
|
||||
sizeof(*args),
|
||||
VM_READ | VM_WRITE)))
|
||||
return PTR_ERR(-EINVAL);
|
||||
|
||||
ret = __sys_mmap(task, mapped_args->start, mapped_args->length,
|
||||
mapped_args->prot, mapped_args->flags, mapped_args->fd,
|
||||
mapped_args->offset);
|
||||
|
||||
pager_unmap_user_range(mapped_args, sizeof(*args));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <file.h>
|
||||
#include <l4/api/errno.h>
|
||||
#include <l4/lib/math.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include <vm_area.h>
|
||||
#include <malloc/malloc.h>
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*/
|
||||
#include <l4/macros.h>
|
||||
#include <l4/lib/list.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include <malloc/malloc.h>
|
||||
#include <mm/alloc_page.h>
|
||||
#include <vm_area.h>
|
||||
@@ -66,7 +66,7 @@ int file_page_out(struct vm_object *vm_obj, unsigned long page_offset)
|
||||
{
|
||||
struct vm_file *f = vm_object_to_file(vm_obj);
|
||||
struct page *page;
|
||||
void *vaddr, *paddr;
|
||||
void *paddr;
|
||||
int err;
|
||||
|
||||
/* Check first if the file has such a page at all */
|
||||
@@ -86,46 +86,26 @@ int file_page_out(struct vm_object *vm_obj, unsigned long page_offset)
|
||||
return 0;
|
||||
|
||||
paddr = (void *)page_to_phys(page);
|
||||
vaddr = l4_new_virtual(1);
|
||||
|
||||
/* FIXME:
|
||||
* Are we sure that pages need
|
||||
* to be mapped to self one-by-one?
|
||||
*
|
||||
* This needs fixing.
|
||||
*/
|
||||
|
||||
/* Map the page to self */
|
||||
l4_map(paddr, vaddr, 1, MAP_USR_RW_FLAGS, self_tid());
|
||||
|
||||
//printf("%s/%s: Writing to vnode %lu, at pgoff 0x%lu, %d pages, buf at %p\n",
|
||||
// __TASKNAME__, __FUNCTION__, f->vnode->vnum, page_offset, 1, vaddr);
|
||||
|
||||
/* Syscall to vfs to write page back to file. */
|
||||
if ((err = vfs_write(f->vnode, page_offset, 1, vaddr)) < 0)
|
||||
goto out_err;
|
||||
|
||||
/* Unmap it from self */
|
||||
l4_unmap(vaddr, 1, self_tid());
|
||||
l4_del_virtual(vaddr, 1);
|
||||
if ((err = vfs_write(f->vnode, page_offset, 1,
|
||||
phys_to_virt(paddr))) < 0)
|
||||
return err;
|
||||
|
||||
/* Clear dirty flag */
|
||||
page->flags &= ~VM_DIRTY;
|
||||
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
l4_unmap(vaddr, 1, self_tid());
|
||||
l4_del_virtual(vaddr, 1);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
struct page *file_page_in(struct vm_object *vm_obj, unsigned long page_offset)
|
||||
{
|
||||
struct vm_file *f = vm_object_to_file(vm_obj);
|
||||
struct page *page;
|
||||
void *vaddr, *paddr;
|
||||
void *paddr;
|
||||
int err;
|
||||
|
||||
/* Check first if the file has such a page at all */
|
||||
@@ -140,24 +120,19 @@ struct page *file_page_in(struct vm_object *vm_obj, unsigned long page_offset)
|
||||
if (!(page = find_page(vm_obj, page_offset))) {
|
||||
/* Allocate a new page */
|
||||
paddr = alloc_page(1);
|
||||
vaddr = l4_new_virtual(1);
|
||||
page = phys_to_page(paddr);
|
||||
|
||||
/* Map the page to vfs task */
|
||||
l4_map(paddr, vaddr, 1, MAP_USR_RW_FLAGS, self_tid());
|
||||
|
||||
/* Syscall to vfs to read into the page. */
|
||||
/* Call to vfs to read into the page. */
|
||||
if ((err = vfs_read(f->vnode, page_offset,
|
||||
1, vaddr)) < 0)
|
||||
goto out_err;
|
||||
1, phys_to_virt(paddr))) < 0) {
|
||||
|
||||
free_page(paddr);
|
||||
return PTR_ERR(err);
|
||||
}
|
||||
|
||||
// printf("%s/%s: Reading into vnode %lu, at pgoff 0x%lu, %d pages, buf at %p\n",
|
||||
// __TASKNAME__, __FUNCTION__, f->vnode->vnum, page_offset, 1, vaddr);
|
||||
|
||||
/* Unmap it from vfs */
|
||||
l4_unmap(vaddr, 1, self_tid());
|
||||
l4_del_virtual(vaddr, 1);
|
||||
|
||||
/* Update vm object details */
|
||||
vm_obj->npages++;
|
||||
|
||||
@@ -174,12 +149,6 @@ struct page *file_page_in(struct vm_object *vm_obj, unsigned long page_offset)
|
||||
}
|
||||
|
||||
return page;
|
||||
|
||||
out_err:
|
||||
l4_unmap(vaddr, 1, self_tid());
|
||||
l4_del_virtual(vaddr, 1);
|
||||
free_page(paddr);
|
||||
return PTR_ERR(err);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -392,9 +361,13 @@ int init_devzero(void)
|
||||
/* Allocate and initialise the zero page */
|
||||
zphys = alloc_page(1);
|
||||
zpage = phys_to_page(zphys);
|
||||
zvirt = l4_map_helper(zphys, 1);
|
||||
zvirt = (void *)phys_to_virt(zphys);
|
||||
memset(zvirt, 0, PAGE_SIZE);
|
||||
l4_unmap_helper(zvirt, 1);
|
||||
|
||||
/*
|
||||
* FIXME:
|
||||
* Flush the dcache if virtual data cache
|
||||
*/
|
||||
|
||||
/* Allocate and initialise devzero file */
|
||||
devzero = vm_file_create();
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <l4/api/errno.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include <stdio.h>
|
||||
#include <init.h>
|
||||
#include <physmem.h>
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
#include <vm_area.h>
|
||||
#include <globals.h>
|
||||
#include <malloc/malloc.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include <lib/idpool.h>
|
||||
#include <lib/addr.h>
|
||||
#include <lib/spinlock.h>
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
#include <l4/api/kip.h>
|
||||
#include <l4/api/errno.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include L4LIB_INC_ARCH(utcb.h)
|
||||
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/arch/utcb.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <l4lib/exregs.h>
|
||||
|
||||
@@ -358,9 +358,7 @@ struct tcb *task_create(struct tcb *parent, struct task_ids *ids,
|
||||
}
|
||||
|
||||
/* Create the thread structures and address space as the pager */
|
||||
if ((err = l4_thread_control(THREAD_CREATE |
|
||||
TC_AS_PAGER |
|
||||
ctrl_flags, ids)) < 0) {
|
||||
if ((err = l4_thread_control(THREAD_CREATE | ctrl_flags, ids)) < 0) {
|
||||
printf("l4_thread_control failed with %d.\n", err);
|
||||
return PTR_ERR(err);
|
||||
}
|
||||
@@ -464,6 +462,7 @@ int task_copy_args_to_user(char *user_stack,
|
||||
|
||||
/* Set beginning of envp */
|
||||
envp_start = (char **)user_stack;
|
||||
|
||||
/* Forward by number of envp ptrs */
|
||||
user_stack += sizeof(int) * env->argc;
|
||||
|
||||
@@ -509,6 +508,7 @@ int task_prefault_range(struct tcb *task, unsigned long start,
|
||||
{
|
||||
struct page *p;
|
||||
|
||||
|
||||
for (unsigned long i = start; i < start + size; i += PAGE_SIZE)
|
||||
if (IS_ERR(p = task_prefault_page(task, i, vm_flags)))
|
||||
return (int)p;
|
||||
|
||||
@@ -53,6 +53,7 @@ int vm_object_test_shadow_count(struct vm_object *vmo)
|
||||
* Add checking that total open file descriptors are
|
||||
* equal to total opener count of all files
|
||||
*/
|
||||
#if defined (DEBUG_FAULT_HANDLING)
|
||||
int mm0_test_global_vm_integrity(void)
|
||||
{
|
||||
struct tcb *task;
|
||||
@@ -123,6 +124,8 @@ int mm0_test_global_vm_integrity(void)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else /* End of DEBUG_FAULT_HANDLING */
|
||||
|
||||
int mm0_test_global_vm_integrity(void) { return 0; }
|
||||
|
||||
|
||||
#endif /* End of !DEBUG_FAULT_HANDLING */
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2008 Bahadir Balban
|
||||
*/
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include <vm_area.h>
|
||||
#include <task.h>
|
||||
#include <user.h>
|
||||
@@ -46,8 +46,8 @@ int pager_validate_user_range(struct tcb *user, void *userptr, unsigned long siz
|
||||
* FIXME: There's no logic here to make non-contiguous physical pages
|
||||
* to get mapped virtually contiguous.
|
||||
*/
|
||||
void *pager_validate_map_user_range(struct tcb *user, void *userptr,
|
||||
unsigned long size, unsigned int vm_flags)
|
||||
void *pager_get_user_page(struct tcb *user, void *userptr,
|
||||
unsigned long size, unsigned int vm_flags)
|
||||
{
|
||||
unsigned long start = page_align(userptr);
|
||||
unsigned long end = page_align_up(userptr + size);
|
||||
@@ -58,26 +58,17 @@ void *pager_validate_map_user_range(struct tcb *user, void *userptr,
|
||||
return 0;
|
||||
|
||||
/* Map first page and calculate the mapped address of pointer */
|
||||
mapped = l4_map_helper((void *)page_to_phys(task_prefault_page(user, start,
|
||||
vm_flags)), 1);
|
||||
mapped = page_to_virt(task_prefault_page(user, start, vm_flags));
|
||||
mapped = (void *)(((unsigned long)mapped) |
|
||||
((unsigned long)(PAGE_MASK & (unsigned long)userptr)));
|
||||
|
||||
/* Map the rest of the pages, if any */
|
||||
for (unsigned long i = start + PAGE_SIZE; i < end; i += PAGE_SIZE)
|
||||
l4_map_helper((void *)
|
||||
page_to_phys(task_prefault_page(user, start + i,
|
||||
vm_flags)), 1);
|
||||
BUG();
|
||||
|
||||
return mapped;
|
||||
}
|
||||
|
||||
void pager_unmap_user_range(void *mapped_ptr, unsigned long size)
|
||||
{
|
||||
l4_unmap_helper((void *)page_align(mapped_ptr),
|
||||
__pfn(page_align_up(size)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy from one buffer to another. Stop if maxlength or
|
||||
* a page boundary is hit.
|
||||
@@ -164,28 +155,23 @@ int copy_from_user(struct tcb *task, void *buf, char *user, int size)
|
||||
int count = size;
|
||||
void *mapped = 0;
|
||||
|
||||
if (!(mapped = pager_validate_map_user_range(task, user,
|
||||
TILL_PAGE_ENDS(user),
|
||||
VM_READ)))
|
||||
if (!(mapped = pager_get_user_page(task, user, TILL_PAGE_ENDS(user),
|
||||
VM_READ)))
|
||||
return -EINVAL;
|
||||
|
||||
while ((ret = memcpy_page(buf + copied, mapped, count, 0)) < 0) {
|
||||
pager_unmap_user_range(mapped, TILL_PAGE_ENDS(mapped));
|
||||
copied += TILL_PAGE_ENDS(mapped);
|
||||
count -= TILL_PAGE_ENDS(mapped);
|
||||
if (!(mapped =
|
||||
pager_validate_map_user_range(task, user + copied,
|
||||
TILL_PAGE_ENDS(user + copied),
|
||||
VM_READ)))
|
||||
pager_get_user_page(task, user + copied,
|
||||
TILL_PAGE_ENDS(user + copied),
|
||||
VM_READ)))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Note copied is always in bytes */
|
||||
total = copied + ret;
|
||||
|
||||
/* Unmap the final page */
|
||||
pager_unmap_user_range(mapped, TILL_PAGE_ENDS(mapped));
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
@@ -196,28 +182,23 @@ int copy_to_user(struct tcb *task, char *user, void *buf, int size)
|
||||
void *mapped = 0;
|
||||
|
||||
/* Map the user page */
|
||||
if (!(mapped = pager_validate_map_user_range(task, user,
|
||||
TILL_PAGE_ENDS(user),
|
||||
VM_READ)))
|
||||
if (!(mapped = pager_get_user_page(task, user,
|
||||
TILL_PAGE_ENDS(user),
|
||||
VM_READ | VM_WRITE)))
|
||||
return -EINVAL;
|
||||
|
||||
while ((ret = memcpy_page(mapped, buf + copied, count, 1)) < 0) {
|
||||
pager_unmap_user_range(mapped, TILL_PAGE_ENDS(mapped));
|
||||
copied += TILL_PAGE_ENDS(mapped);
|
||||
count -= TILL_PAGE_ENDS(mapped);
|
||||
if (!(mapped =
|
||||
pager_validate_map_user_range(task, user + copied,
|
||||
TILL_PAGE_ENDS(user + copied),
|
||||
VM_READ)))
|
||||
if (!(mapped = pager_get_user_page(task, user + copied,
|
||||
TILL_PAGE_ENDS(user + copied),
|
||||
VM_READ | VM_WRITE)))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Note copied is always in bytes */
|
||||
total = copied + ret;
|
||||
|
||||
/* Unmap the final page */
|
||||
pager_unmap_user_range(mapped, TILL_PAGE_ENDS(mapped));
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
@@ -243,9 +224,8 @@ int copy_user_buf(struct tcb *task, void *buf, char *user, int maxlength,
|
||||
return -EINVAL;
|
||||
|
||||
/* Map the first page the user buffer is in */
|
||||
if (!(mapped = pager_validate_map_user_range(task, user,
|
||||
TILL_PAGE_ENDS(user),
|
||||
VM_READ)))
|
||||
if (!(mapped = pager_get_user_page(task, user, TILL_PAGE_ENDS(user),
|
||||
VM_READ)))
|
||||
return -EINVAL;
|
||||
|
||||
while ((ret = copy_func(buf + copied, mapped, count)) < 0) {
|
||||
@@ -257,13 +237,12 @@ int copy_user_buf(struct tcb *task, void *buf, char *user, int maxlength,
|
||||
* because we know we hit a page boundary and we increase
|
||||
* by the page boundary bytes
|
||||
*/
|
||||
pager_unmap_user_range(mapped, TILL_PAGE_ENDS(mapped));
|
||||
copied += TILL_PAGE_ENDS(mapped);
|
||||
count -= TILL_PAGE_ENDS(mapped);
|
||||
if (!(mapped =
|
||||
pager_validate_map_user_range(task, user + copied,
|
||||
TILL_PAGE_ENDS(user + copied),
|
||||
VM_READ)))
|
||||
pager_get_user_page(task, user + copied,
|
||||
TILL_PAGE_ENDS(user + copied),
|
||||
VM_READ)))
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
@@ -271,9 +250,6 @@ int copy_user_buf(struct tcb *task, void *buf, char *user, int maxlength,
|
||||
/* Note copied is always in bytes */
|
||||
total = (copied / elem_size) + ret;
|
||||
|
||||
/* Unmap the final page */
|
||||
pager_unmap_user_range(mapped, TILL_PAGE_ENDS(mapped));
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
*
|
||||
* Copyright (C) 2007-2009 Bahadir Bilgehan Balban
|
||||
*/
|
||||
#include <l4lib/arch/utcb.h>
|
||||
|
||||
#include <l4/macros.h>
|
||||
#include INC_GLUE(memlayout.h)
|
||||
#include L4LIB_INC_ARCH(utcb.h)
|
||||
#include <mmap.h>
|
||||
#include <utcb.h>
|
||||
#include <malloc/malloc.h>
|
||||
|
||||
@@ -12,7 +12,7 @@ linkoutput_file_suffix = "-linkinfo.txt"
|
||||
linkoutput_file = image_name + linkoutput_file_suffix
|
||||
|
||||
def generate_bootdesc():
|
||||
command = config.user_toolchain + objdump + " -t " + image_name + " > " + linkoutput_file
|
||||
command = config.toolchain + objdump + " -t " + image_name + " > " + linkoutput_file
|
||||
print command
|
||||
os.system(command)
|
||||
f = open(linkoutput_file, "r")
|
||||
|
||||
@@ -69,7 +69,7 @@ test_exec_env = environment.Clone()
|
||||
|
||||
test_exec_env.Append(LIBS = ['posix', 'c-userspace'])
|
||||
test_exec_env.Append(LINKFLAGS = '-T' + test_exec_lds[0].path)
|
||||
test_exec_env.Append(CPPFLAGS = ' -D__USERSPACE__')
|
||||
test_exec_env.Append(CPPFLAGS = ' -D__USERSPACE__ -include l4lib/macros.h ')
|
||||
test_exec_env.Replace(PROGSUFFIX = '')
|
||||
test_exec_src = Glob('src/test_exec/*.[cS]')
|
||||
test_exec_objs = test_exec_env.Object(test_exec_src)
|
||||
@@ -81,7 +81,7 @@ AlwaysBuild(test_exec_lds)
|
||||
|
||||
env.Append(LIBS = ['posix', 'c-userspace'])
|
||||
env.Append(LINKFLAGS = '-T' + lma_lds[0].path)
|
||||
env.Append(CPPFLAGS = ' -D__USERSPACE__')
|
||||
env.Append(CPPFLAGS = ' -D__USERSPACE__ -include l4lib/macros.h ')
|
||||
env.Replace(PROGSUFFIX = '')
|
||||
objs = env.Object(src + test_exec_asm)
|
||||
test0 = env.Program('test0', objs)
|
||||
|
||||
@@ -58,7 +58,7 @@ def get_physical_base(source, target, env):
|
||||
prev_image + " >> " + physical_base_ld_script))
|
||||
|
||||
# The kernel build environment
|
||||
env = Environment(CC = config.user_toolchain + 'gcc',
|
||||
env = Environment(CC = config.toolchain + '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'],
|
||||
@@ -74,7 +74,7 @@ env = Environment(CC = config.user_toolchain + 'gcc',
|
||||
|
||||
test_exec_ld_script = "include/test_exec_linker.lds"
|
||||
# The kernel build environment:
|
||||
test_exec_env = Environment(CC = config.user_toolchain + 'gcc',
|
||||
test_exec_env = Environment(CC = config.toolchain + '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 = ['-O3', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror'],
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define __TEST0_CAP_H__
|
||||
|
||||
|
||||
#include <l4lib/capability.h>
|
||||
#include <l4lib/lib/cap.h>
|
||||
#include <l4/generic/cap-types.h>
|
||||
#include <l4/api/capability.h>
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#define __TASKNAME__ "test0"
|
||||
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
|
||||
// #define TEST_VERBOSE_PRINT
|
||||
#if defined (TEST_VERBOSE_PRINT)
|
||||
#define test_printf(...) printf(__VA_ARGS__)
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/kip.h>
|
||||
#include <l4lib/utcb.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
@@ -15,6 +14,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <atoi.h>
|
||||
#include <stdlib.h>
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
|
||||
void wait_pager(l4id_t partner)
|
||||
{
|
||||
@@ -50,10 +50,10 @@ int main(int argc, char *argv[])
|
||||
|
||||
shmtest();
|
||||
|
||||
forktest();
|
||||
|
||||
fileio();
|
||||
|
||||
forktest();
|
||||
|
||||
clonetest();
|
||||
|
||||
undeftest();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <capability.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
|
||||
int cap_request_pager(struct capability *cap)
|
||||
{
|
||||
|
||||
@@ -26,14 +26,16 @@ int clonetest(void)
|
||||
void *child_stack;
|
||||
|
||||
/* Parent loops and calls clone() to clone new threads. Children don't come back from the clone() call */
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int i = 0; i < 20; i++) {
|
||||
if ((child_stack = mmap(0, 0x1000, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_GROWSDOWN, 0, 0)) == MAP_FAILED) {
|
||||
test_printf("MMAP failed.\n");
|
||||
goto out_err;
|
||||
} else {
|
||||
test_printf("Mapped area starting at %p\n", child_stack);
|
||||
}
|
||||
((int *)child_stack)[-1] = 5; /* Test mapped area */
|
||||
// printf("mmap returned child stack: %p\n", child_stack);
|
||||
|
||||
// ((int *)child_stack)[-1] = 5; /* Test mapped area */
|
||||
|
||||
test_printf("Cloning...\n");
|
||||
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
#include <alloca.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
|
||||
#define PAGE_SIZE 0x1000
|
||||
|
||||
extern char _start_test_exec[];
|
||||
extern char _end_test_exec[];
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
*
|
||||
* Copyright (C) 2007-2009 Bahadir Bilgehan Balban
|
||||
*/
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
#include <tests.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define PAGE_SIZE 0x1000
|
||||
|
||||
int mmaptest(void)
|
||||
{
|
||||
int fd;
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
*
|
||||
* Copyright (C) 2007-2009 Bahadir Bilgehan Balban
|
||||
*/
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <l4lib/mutex.h>
|
||||
#include <errno.h>
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/kip.h>
|
||||
#include <l4lib/utcb.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
|
||||
Reference in New Issue
Block a user