/branches/dynload/contrib/toolchain/toolchain.ppc32.sh |
---|
15,8 → 15,12 |
fi |
} |
if [ -z "${CROSS_PREFIX}" ] ; then |
CROSS_PREFIX="/usr/local" |
fi |
BINUTILS_VERSION="2.18" |
GCC_VERSION="4.3.1" |
GCC_VERSION="4.3.2" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2" |
29,7 → 33,7 |
PLATFORM="ppc" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
PREFIX="${CROSS_PREFIX}/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
OBJDIR="${WORKDIR}/gcc-obj" |
/branches/dynload/contrib/toolchain/toolchain.amd64.sh |
---|
15,8 → 15,12 |
fi |
} |
if [ -z "${CROSS_PREFIX}" ] ; then |
CROSS_PREFIX="/usr/local" |
fi |
BINUTILS_VERSION="2.18" |
GCC_VERSION="4.3.1" |
GCC_VERSION="4.3.2" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2" |
29,7 → 33,7 |
PLATFORM="amd64" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
PREFIX="${CROSS_PREFIX}/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
OBJDIR="${WORKDIR}/gcc-obj" |
/branches/dynload/contrib/toolchain/toolchain.ppc64.sh |
---|
15,6 → 15,10 |
fi |
} |
if [ -z "${CROSS_PREFIX}" ] ; then |
CROSS_PREFIX="/usr/local" |
fi |
BINUTILS_VERSION="2.18" |
GCC_VERSION="4.3.1" |
29,7 → 33,7 |
PLATFORM="ppc64" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
PREFIX="${CROSS_PREFIX}/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
OBJDIR="${WORKDIR}/gcc-obj" |
/branches/dynload/contrib/toolchain/toolchain.ia32.sh |
---|
15,8 → 15,12 |
fi |
} |
if [ -z "${CROSS_PREFIX}" ] ; then |
CROSS_PREFIX="/usr/local" |
fi |
BINUTILS_VERSION="2.18" |
GCC_VERSION="4.3.1" |
GCC_VERSION="4.3.2" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2" |
29,7 → 33,7 |
PLATFORM="i686" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-pc-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
PREFIX="${CROSS_PREFIX}/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
OBJDIR="${WORKDIR}/gcc-obj" |
/branches/dynload/contrib/toolchain/toolchain.mipsel32.sh |
---|
15,6 → 15,10 |
fi |
} |
if [ -z "${CROSS_PREFIX}" ] ; then |
CROSS_PREFIX="/usr/local" |
fi |
BINUTILS_VERSION="2.18" |
GCC_VERSION="4.3.1" |
29,7 → 33,7 |
PLATFORM="mipsel" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
PREFIX="${CROSS_PREFIX}/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
OBJDIR="${WORKDIR}/gcc-obj" |
/branches/dynload/contrib/toolchain/toolchain.sparc64.sh |
---|
15,6 → 15,10 |
fi |
} |
if [ -z "${CROSS_PREFIX}" ] ; then |
CROSS_PREFIX="/usr/local" |
fi |
BINUTILS_VERSION="2.18" |
GCC_VERSION="4.3.1" |
29,7 → 33,7 |
PLATFORM="sparc64" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
PREFIX="${CROSS_PREFIX}/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
OBJDIR="${WORKDIR}/gcc-obj" |
/branches/dynload/contrib/toolchain/toolchain.ia64.sh |
---|
15,8 → 15,12 |
fi |
} |
if [ -z "${CROSS_PREFIX}" ] ; then |
CROSS_PREFIX="/usr/local" |
fi |
BINUTILS_VERSION="2.18" |
GCC_VERSION="4.3.1" |
GCC_VERSION="4.3.2" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2" |
29,7 → 33,7 |
PLATFORM="ia64" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-pc-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
PREFIX="${CROSS_PREFIX}/${PLATFORM}" |
INCLUDESDIR="${WORKDIR}/include" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
/branches/dynload/contrib/toolchain/toolchain.arm32.sh |
---|
15,8 → 15,12 |
fi |
} |
if [ -z "${CROSS_PREFIX}" ] ; then |
CROSS_PREFIX="/usr/local" |
fi |
BINUTILS_VERSION="2.18" |
GCC_VERSION="4.3.1" |
GCC_VERSION="4.3.2" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2" |
29,7 → 33,7 |
PLATFORM="arm" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
PREFIX="${CROSS_PREFIX}/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
OBJDIR="${WORKDIR}/gcc-obj" |
/branches/dynload/contrib/toolchain/toolchain.mipseb32.sh |
---|
15,6 → 15,10 |
fi |
} |
if [ -z "${CROSS_PREFIX}" ] ; then |
CROSS_PREFIX="/usr/local" |
fi |
BINUTILS_VERSION="2.18" |
GCC_VERSION="4.3.1" |
29,7 → 33,7 |
PLATFORM="mips" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-sgi-irix5" |
PREFIX="/usr/local/${PLATFORM}" |
PREFIX="${CROSS_PREFIX}/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
OBJDIR="${WORKDIR}/gcc-obj" |
/branches/dynload/contrib/conf/bootindy |
---|
File deleted |
/branches/dynload/contrib/conf/msim.conf |
---|
2,12 → 2,14 |
# MSIM configuration script |
# |
add dcpu mips1 |
add dcpu cpu0 |
add rwm mainmem 0x00000000 8M |
add rwm mainmem 0x00000000 |
mainmem generic 16M |
mainmem load "/dev/zero" |
add rom bootmem 0x1fc00000 2048k |
add rom bootmem 0x1fc00000 |
bootmem generic 4096k |
bootmem load "image.boot" |
add dprinter printer 0x10000000 |
/branches/dynload/kernel/kernel.config |
---|
81,7 → 81,6 |
@ "simics" Virtutech Simics simulator |
@ "lgxemul" GXEmul Little Endian |
@ "bgxemul" GXEmul Big Endian |
@ "indy" SGI Indy |
! [ARCH=mips32] MACHINE (choice) |
# Framebuffer support |
168,9 → 167,3 |
# Compile kernel tests |
! CONFIG_TEST (y/n) |
## Experimental features |
# Enable experimental features |
! CONFIG_EXPERIMENTAL (n/y) |
/branches/dynload/kernel/doc/BUGS_FOUND |
---|
File deleted |
/branches/dynload/kernel/doc/AUTHORS |
---|
1,12 → 1,12 |
Jakub Jermar <jermar@helenos.eu> |
Martin Decky <decky@helenos.eu> |
Ondrej Palkovsky <palkovsky@helenos.eu> |
Jakub Vana <vana@helenos.eu> |
Josef Cejka <cejka@helenos.eu> |
Michal Kebrt <michalek.k@seznam.cz> |
Sergey Bondari <bondari@helenos.eu> |
Pavel Jancik <alfik.009@seznam.cz> |
Petr Stepan <stepan.petr@volny.cz> |
Michal Konopa <mkonopa@seznam.cz> |
Jakub Jermar |
Martin Decky |
Ondrej Palkovsky |
Jiri Svoboda |
Jakub Vana |
Josef Cejka |
Michal Kebrt |
Sergey Bondari |
Pavel Jancik |
Petr Stepan |
Michal Konopa |
Vojtech Mencl |
/branches/dynload/kernel/doc/arch/mips32 |
---|
3,11 → 3,9 |
mips32 is the second port of SPARTAN kernel originally written by Jakub Jermar. |
It was first developed to run on MIPS R4000 32-bit simulator. |
Now it can run on real hardware as well. |
It can be compiled and run either as little- or big-endian. |
HARDWARE REQUIREMENTS |
o SGI Indy R4600 |
o emulated MIPS 4K CPU |
CPU |
/branches/dynload/kernel/genarch/include/mm/page_pt.h |
---|
116,9 → 116,7 |
#define PTE_WRITABLE(p) PTE_WRITABLE_ARCH((p)) |
#define PTE_EXECUTABLE(p) PTE_EXECUTABLE_ARCH((p)) |
#ifndef __OBJC__ |
extern as_operations_t as_pt_operations; |
#endif |
extern page_mapping_operations_t pt_mapping_operations; |
extern void page_mapping_insert_pt(as_t *as, uintptr_t page, uintptr_t frame, |
/branches/dynload/kernel/genarch/src/mm/as_pt.c |
---|
52,31 → 52,6 |
static void pt_lock(as_t *as, bool lock); |
static void pt_unlock(as_t *as, bool unlock); |
#ifdef __OBJC__ |
@implementation as_t |
+ (pte_t *) page_table_create: (int) flags |
{ |
return ptl0_create(flags); |
} |
+ (void) page_table_destroy: (pte_t *) page_table |
{ |
ptl0_destroy(page_table); |
} |
- (void) page_table_lock: (bool) _lock |
{ |
pt_lock(self, _lock); |
} |
- (void) page_table_unlock: (bool) unlock |
{ |
pt_unlock(self, unlock); |
} |
@end |
#else |
as_operations_t as_pt_operations = { |
.page_table_create = ptl0_create, |
.page_table_destroy = ptl0_destroy, |
83,7 → 58,6 |
.page_table_lock = pt_lock, |
.page_table_unlock = pt_unlock |
}; |
#endif |
/** Create PTL0. |
* |
/branches/dynload/kernel/generic/include/config.h |
---|
40,8 → 40,6 |
#define STACK_SIZE PAGE_SIZE |
#define CONFIG_MEMORY_SIZE (16 * 1024 * 1024) |
#define CONFIG_INIT_TASKS 32 |
typedef struct { |
/branches/dynload/kernel/generic/include/lib/objc_ext.h |
---|
File deleted |
/branches/dynload/kernel/generic/include/lib/objc.h |
---|
File deleted |
/branches/dynload/kernel/generic/include/mm/page.h |
---|
39,11 → 39,6 |
#include <mm/as.h> |
#include <memstr.h> |
/** |
* Macro for computing page color. |
*/ |
#define PAGE_COLOR(va) (((va) >> PAGE_WIDTH) & ((1 << PAGE_COLOR_BITS) - 1)) |
/** Operations to manipulate page mappings. */ |
typedef struct { |
void (* mapping_insert)(as_t *as, uintptr_t page, uintptr_t frame, |
/branches/dynload/kernel/generic/include/mm/as.h |
---|
53,10 → 53,6 |
#include <adt/btree.h> |
#include <lib/elf.h> |
#ifdef __OBJC__ |
#include <lib/objc.h> |
#endif |
/** |
* Defined to be true if user address space and kernel address space shadow each |
* other. |
84,47 → 80,6 |
/** The page fault was caused by memcpy_from_uspace() or memcpy_to_uspace(). */ |
#define AS_PF_DEFER 2 |
#ifdef __OBJC__ |
@interface as_t : base_t { |
@public |
/** Protected by asidlock. */ |
link_t inactive_as_with_asid_link; |
/** |
* Number of processors on wich is this address space active. |
* Protected by asidlock. |
*/ |
count_t cpu_refcount; |
/** |
* Address space identifier. |
* Constant on architectures that do not support ASIDs. |
* Protected by asidlock. |
*/ |
asid_t asid; |
/** Number of references (i.e tasks that reference this as). */ |
atomic_t refcount; |
mutex_t lock; |
/** B+tree of address space areas. */ |
btree_t as_area_btree; |
/** Non-generic content. */ |
as_genarch_t genarch; |
/** Architecture specific content. */ |
as_arch_t arch; |
} |
+ (pte_t *) page_table_create: (int) flags; |
+ (void) page_table_destroy: (pte_t *) page_table; |
- (void) page_table_lock: (bool) _lock; |
- (void) page_table_unlock: (bool) unlock; |
@end |
#else |
/** Address space structure. |
* |
* as_t contains the list of as_areas of userspace accessible |
168,7 → 123,6 |
void (* page_table_lock)(as_t *as, bool lock); |
void (* page_table_unlock)(as_t *as, bool unlock); |
} as_operations_t; |
#endif |
/** |
* This structure contains information associated with the shared address space |
249,10 → 203,7 |
extern as_t *AS_KERNEL; |
#ifndef __OBJC__ |
extern as_operations_t *as_operations; |
#endif |
extern link_t inactive_as_with_asid_head; |
extern void as_init(void); |
/branches/dynload/kernel/generic/include/macros.h |
---|
40,20 → 40,20 |
#define isdigit(d) (((d) >= '0') && ((d) <= '9')) |
#define islower(c) (((c) >= 'a') && ((c) <= 'z')) |
#define isupper(c) (((c) >= 'A') && ((c) <= 'Z')) |
#define isalpha(c) (is_lower(c) || is_upper(c)) |
#define isalphanum(c) (is_alpha(c) || is_digit(c)) |
#define isalpha(c) (is_lower((c)) || is_upper((c))) |
#define isalphanum(c) (is_alpha((c)) || is_digit((c))) |
#define isspace(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\n') || \ |
((c) == '\r')) |
((c) == '\r')) |
#define min(a,b) ((a) < (b) ? (a) : (b)) |
#define max(a,b) ((a) > (b) ? (a) : (b)) |
/** Return true if the interlvals overlap. |
/** Return true if the intervals overlap. |
* |
* @param s1 Start address of the first interval. |
* @param sz1 Size of the first interval. |
* @param s2 Start address of the second interval. |
* @param sz2 Size of the second interval. |
* @param s1 Start address of the first interval. |
* @param sz1 Size of the first interval. |
* @param s2 Start address of the second interval. |
* @param sz2 Size of the second interval. |
*/ |
static inline int overlaps(uintptr_t s1, size_t sz1, uintptr_t s2, size_t sz2) |
{ |
64,11 → 64,15 |
} |
/* Compute overlapping of physical addresses */ |
#define PA_overlaps(x, szx, y, szy) overlaps(KA2PA(x), szx, KA2PA(y), szy) |
#define PA_overlaps(x, szx, y, szy) \ |
overlaps(KA2PA((x)), (szx), KA2PA((y)), (szy)) |
#define SIZE2KB(size) (size >> 10) |
#define SIZE2MB(size) (size >> 20) |
#define SIZE2KB(size) ((size) >> 10) |
#define SIZE2MB(size) ((size) >> 20) |
#define KB2SIZE(kb) ((kb) << 10) |
#define MB2SIZE(mb) ((mb) << 20) |
#define STRING(arg) STRING_ARG(arg) |
#define STRING_ARG(arg) #arg |
/branches/dynload/kernel/generic/include/ipc/ipc.h |
---|
281,6 → 281,13 |
/** Buffer for IPC_M_DATA_WRITE and IPC_M_DATA_READ. */ |
uint8_t *buffer; |
/* |
* The forward operation can masquerade the caller phone. For those |
* cases, we must keep it aside so that the answer is processed |
* correctly. |
*/ |
phone_t *caller_phone; |
} call_t; |
extern void ipc_init(void); |
287,7 → 294,7 |
extern call_t * ipc_wait_for_call(answerbox_t *, uint32_t, int); |
extern void ipc_answer(answerbox_t *, call_t *); |
extern int ipc_call(phone_t *, call_t *); |
extern void ipc_call_sync(phone_t *, call_t *); |
extern int ipc_call_sync(phone_t *, call_t *); |
extern void ipc_phone_init(phone_t *); |
extern void ipc_phone_connect(phone_t *, answerbox_t *); |
extern void ipc_call_free(call_t *); |
/branches/dynload/kernel/generic/include/errno.h |
---|
56,6 → 56,7 |
#define EINVAL -13 /* Invalid value */ |
#define EBUSY -14 /* Resource is busy */ |
#define EOVERFLOW -15 /* The result does not fit its size. */ |
#define EINTR -16 /* Operation was interrupted. */ |
#endif |
/branches/dynload/kernel/generic/src/main/kinit.c |
---|
177,7 → 177,6 |
*/ |
cap_set(programs[i].task, CAP_CAP | CAP_MEM_MANAGER | |
CAP_IO_MANAGER | CAP_PREEMPT_CONTROL | CAP_IRQ_REG); |
if (!ipc_phone_0) |
ipc_phone_0 = &programs[i].task->answerbox; |
/branches/dynload/kernel/generic/src/sysinfo/sysinfo.c |
---|
281,10 → 281,15 |
return ret; |
} |
#define SYSINFO_MAX_LEN 1024 |
unative_t sys_sysinfo_valid(unative_t ptr, unative_t len) |
{ |
char *str; |
sysinfo_rettype_t ret = {0, 0}; |
if (len > SYSINFO_MAX_LEN) |
return ret.valid; |
str = malloc(len + 1, 0); |
ASSERT(str); |
299,6 → 304,9 |
{ |
char *str; |
sysinfo_rettype_t ret = {0, 0}; |
if (len > SYSINFO_MAX_LEN) |
return ret.val; |
str = malloc(len + 1, 0); |
ASSERT(str); |
/branches/dynload/kernel/generic/src/proc/task.c |
---|
71,11 → 71,7 |
static task_id_t task_counter = 0; |
/** Initialize tasks |
* |
* Initialize kernel tasks support. |
* |
*/ |
/** Initialize kernel tasks support. */ |
void task_init(void) |
{ |
TASK = NULL; |
83,7 → 79,8 |
} |
/* |
* The idea behind this walker is to remember a single task different from TASK. |
* The idea behind this walker is to remember a single task different from |
* TASK. |
*/ |
static bool task_done_walker(avltree_node_t *node, void *arg) |
{ |
98,9 → 95,7 |
return true; /* continue the walk */ |
} |
/** Kill all tasks except the current task. |
* |
*/ |
/** Kill all tasks except the current task. */ |
void task_done(void) |
{ |
task_t *t; |
132,15 → 127,13 |
} while (t != NULL); |
} |
/** Create new task |
/** Create new task with no threads. |
* |
* Create new task with no threads. |
* @param as Task's address space. |
* @param name Symbolic name. |
* |
* @param as Task's address space. |
* @param name Symbolic name. |
* @return New task's structure. |
* |
* @return New task's structure |
* |
*/ |
task_t *task_create(as_t *as, char *name) |
{ |
194,7 → 187,7 |
/** Destroy task. |
* |
* @param t Task to be destroyed. |
* @param t Task to be destroyed. |
*/ |
void task_destroy(task_t *t) |
{ |
227,16 → 220,16 |
/** Syscall for reading task ID from userspace. |
* |
* @param uspace_task_id Userspace address of 8-byte buffer where to store |
* current task ID. |
* @param uspace_task_id userspace address of 8-byte buffer |
* where to store current task ID. |
* |
* @return 0 on success or an error code from @ref errno.h. |
* @return Zero on success or an error code from @ref errno.h. |
*/ |
unative_t sys_task_get_id(task_id_t *uspace_task_id) |
{ |
/* |
* No need to acquire lock on TASK because taskid |
* remains constant for the lifespan of the task. |
* No need to acquire lock on TASK because taskid remains constant for |
* the lifespan of the task. |
*/ |
return (unative_t) copy_to_uspace(uspace_task_id, &TASK->taskid, |
sizeof(TASK->taskid)); |
244,16 → 237,15 |
/** Find task structure corresponding to task ID. |
* |
* The tasks_lock must be already held by the caller of this function |
* and interrupts must be disabled. |
* The tasks_lock must be already held by the caller of this function and |
* interrupts must be disabled. |
* |
* @param id Task ID. |
* @param id Task ID. |
* |
* @return Task structure address or NULL if there is no such task ID. |
* @return Task structure address or NULL if there is no such task |
* ID. |
*/ |
task_t *task_find_by_id(task_id_t id) |
{ |
avltree_node_t *node; |
task_t *task_find_by_id(task_id_t id) { avltree_node_t *node; |
node = avltree_search(&tasks_tree, (avltree_key_t) id); |
264,11 → 256,13 |
/** Get accounting data of given task. |
* |
* Note that task lock of 't' must be already held and |
* interrupts must be already disabled. |
* Note that task lock of 't' must be already held and interrupts must be |
* already disabled. |
* |
* @param t Pointer to thread. |
* @param t Pointer to thread. |
* |
* @return Number of cycles used by the task and all its threads |
* so far. |
*/ |
uint64_t task_get_accounting(task_t *t) |
{ |
300,9 → 294,9 |
* This function is idempotent. |
* It signals all the task's threads to bail it out. |
* |
* @param id ID of the task to be killed. |
* @param id ID of the task to be killed. |
* |
* @return 0 on success or an error code from errno.h |
* @return Zero on success or an error code from errno.h. |
*/ |
int task_kill(task_id_t id) |
{ |
323,7 → 317,7 |
spinlock_unlock(&tasks_lock); |
/* |
* Interrupt all threads except ktaskclnp. |
* Interrupt all threads. |
*/ |
spinlock_lock(&ta->lock); |
for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) { |
/branches/dynload/kernel/generic/src/lib/objc_ext.c |
---|
File deleted |
/branches/dynload/kernel/generic/src/lib/objc.c |
---|
File deleted |
/branches/dynload/kernel/generic/src/lib/rd.c |
---|
48,14 → 48,14 |
/** |
* RAM disk initialization routine. At this point, the RAM disk memory is shared |
* and information about the share is provided as sysinfo values to the userspace |
* tasks. |
* and information about the share is provided as sysinfo values to the |
* userspace tasks. |
*/ |
int init_rd(rd_header_t *header, size_t size) |
{ |
/* Identify RAM disk */ |
if ((header->magic[0] != RD_MAG0) || (header->magic[1] != RD_MAG1) || |
(header->magic[2] != RD_MAG2) || (header->magic[3] != RD_MAG3)) |
(header->magic[2] != RD_MAG2) || (header->magic[3] != RD_MAG3)) |
return RE_INVALID; |
/* Identify version */ |
86,7 → 86,8 |
if ((uint64_t) hsize + dsize > size) |
dsize = size - hsize; |
rd_parea.pbase = ALIGN_DOWN((uintptr_t) KA2PA((void *) header + hsize), FRAME_SIZE); |
rd_parea.pbase = ALIGN_DOWN((uintptr_t) KA2PA((void *) header + hsize), |
FRAME_SIZE); |
rd_parea.vbase = (uintptr_t) ((void *) header + hsize); |
rd_parea.frames = SIZE2FRAMES(dsize); |
rd_parea.cacheable = true; |
95,8 → 96,8 |
sysinfo_set_item_val("rd", NULL, true); |
sysinfo_set_item_val("rd.header_size", NULL, hsize); |
sysinfo_set_item_val("rd.size", NULL, dsize); |
sysinfo_set_item_val("rd.address.physical", NULL, (unative_t) |
KA2PA((void *) header + hsize)); |
sysinfo_set_item_val("rd.address.physical", NULL, |
(unative_t) KA2PA((void *) header + hsize)); |
return RE_OK; |
} |
/branches/dynload/kernel/generic/src/lib/memstr.c |
---|
74,7 → 74,7 |
((uint8_t *)(((unative_t *) dst) + i))[j] = ((uint8_t *)(((unative_t *) src) + i))[j]; |
} |
return (char *) src; |
return (char *) dst; |
} |
/** Fill block of memory |
/branches/dynload/kernel/generic/src/mm/backend_anon.c |
---|
78,7 → 78,6 |
int anon_page_fault(as_area_t *area, uintptr_t addr, pf_access_t access) |
{ |
uintptr_t frame; |
bool dirty = false; |
if (!as_area_check_access(area, access)) |
return AS_PF_FAULT; |
106,7 → 105,7 |
*/ |
for (i = 0; i < leaf->keys; i++) { |
if (leaf->key[i] == |
ALIGN_DOWN(addr, PAGE_SIZE)) { |
ALIGN_DOWN(addr, PAGE_SIZE) - area->base) { |
allocate = false; |
break; |
} |
114,7 → 113,6 |
if (allocate) { |
frame = (uintptr_t) frame_alloc(ONE_FRAME, 0); |
memsetb((void *) PA2KA(frame), FRAME_SIZE, 0); |
dirty = true; |
/* |
* Insert the address of the newly allocated |
145,7 → 143,6 |
*/ |
frame = (uintptr_t) frame_alloc(ONE_FRAME, 0); |
memsetb((void *) PA2KA(frame), FRAME_SIZE, 0); |
dirty = true; |
} |
/* |
/branches/dynload/kernel/generic/src/mm/as.c |
---|
82,7 → 82,6 |
#include <arch/mm/cache.h> |
#endif /* CONFIG_VIRT_IDX_DCACHE */ |
#ifndef __OBJC__ |
/** |
* Each architecture decides what functions will be used to carry out |
* address space operations such as creating or locking page tables. |
93,7 → 92,6 |
* Slab for as_t objects. |
*/ |
static slab_cache_t *as_slab; |
#endif |
/** |
* This lock serializes access to the ASID subsystem. |
113,13 → 111,11 |
/** Kernel address space. */ |
as_t *AS_KERNEL = NULL; |
static int area_flags_to_page_flags(int aflags); |
static as_area_t *find_area_and_lock(as_t *as, uintptr_t va); |
static bool check_area_conflicts(as_t *as, uintptr_t va, size_t size, |
as_area_t *avoid_area); |
static void sh_info_remove_reference(share_info_t *sh_info); |
static int area_flags_to_page_flags(int); |
static as_area_t *find_area_and_lock(as_t *, uintptr_t); |
static bool check_area_conflicts(as_t *, uintptr_t, size_t, as_area_t *); |
static void sh_info_remove_reference(share_info_t *); |
#ifndef __OBJC__ |
static int as_constructor(void *obj, int flags) |
{ |
as_t *as = (as_t *) obj; |
139,7 → 135,6 |
return as_destructor_arch(as); |
} |
#endif |
/** Initialize address space subsystem. */ |
void as_init(void) |
146,10 → 141,8 |
{ |
as_arch_init(); |
#ifndef __OBJC__ |
as_slab = slab_cache_create("as_slab", sizeof(as_t), 0, |
as_constructor, as_destructor, SLAB_CACHE_MAGDEFERRED); |
#endif |
AS_KERNEL = as_create(FLAG_AS_KERNEL); |
if (!AS_KERNEL) |
159,20 → 152,14 |
/** Create address space. |
* |
* @param flags Flags that influence way in wich the address space is created. |
* @param flags Flags that influence the way in wich the address space |
* is created. |
*/ |
as_t *as_create(int flags) |
{ |
as_t *as; |
#ifdef __OBJC__ |
as = [as_t new]; |
link_initialize(&as->inactive_as_with_asid_link); |
mutex_initialize(&as->lock, MUTEX_PASSIVE); |
(void) as_constructor_arch(as, flags); |
#else |
as = (as_t *) slab_alloc(as_slab, 0); |
#endif |
(void) as_create_arch(as, 0); |
btree_create(&as->as_area_btree); |
199,6 → 186,8 |
* zero), the address space can be destroyed. |
* |
* We know that we don't hold any spinlock. |
* |
* @param as Address space to be destroyed. |
*/ |
void as_destroy(as_t *as) |
{ |
263,11 → 252,7 |
interrupts_restore(ipl); |
#ifdef __OBJC__ |
[as free]; |
#else |
slab_free(as_slab, as); |
#endif |
} |
/** Create address space area of common attributes. |
274,19 → 259,19 |
* |
* The created address space area is added to the target address space. |
* |
* @param as Target address space. |
* @param flags Flags of the area memory. |
* @param size Size of area. |
* @param base Base address of area. |
* @param attrs Attributes of the area. |
* @param backend Address space area backend. NULL if no backend is used. |
* @param backend_data NULL or a pointer to an array holding two void *. |
* @param as Target address space. |
* @param flags Flags of the area memory. |
* @param size Size of area. |
* @param base Base address of area. |
* @param attrs Attributes of the area. |
* @param backend Address space area backend. NULL if no backend is used. |
* @param backend_data NULL or a pointer to an array holding two void *. |
* |
* @return Address space area on success or NULL on failure. |
* @return Address space area on success or NULL on failure. |
*/ |
as_area_t * |
as_area_create(as_t *as, int flags, size_t size, uintptr_t base, int attrs, |
mem_backend_t *backend, mem_backend_data_t *backend_data) |
mem_backend_t *backend, mem_backend_data_t *backend_data) |
{ |
ipl_t ipl; |
as_area_t *a; |
338,13 → 323,14 |
/** Find address space area and change it. |
* |
* @param as Address space. |
* @param address Virtual address belonging to the area to be changed. Must be |
* page-aligned. |
* @param size New size of the virtual memory block starting at address. |
* @param flags Flags influencing the remap operation. Currently unused. |
* @param as Address space. |
* @param address Virtual address belonging to the area to be changed. |
* Must be page-aligned. |
* @param size New size of the virtual memory block starting at |
* address. |
* @param flags Flags influencing the remap operation. Currently unused. |
* |
* @return Zero on success or a value from @ref errno.h otherwise. |
* @return Zero on success or a value from @ref errno.h otherwise. |
*/ |
int as_area_resize(as_t *as, uintptr_t address, size_t size, int flags) |
{ |
452,8 → 438,10 |
cond = false; /* we are almost done */ |
i = (start_free - b) >> PAGE_WIDTH; |
if (!used_space_remove(area, start_free, c - i)) |
panic("Could not remove used space.\n"); |
if (!used_space_remove(area, start_free, |
c - i)) |
panic("Could not remove used " |
"space.\n"); |
} else { |
/* |
* The interval of used space can be |
460,7 → 448,8 |
* completely removed. |
*/ |
if (!used_space_remove(area, b, c)) |
panic("Could not remove used space.\n"); |
panic("Could not remove used " |
"space.\n"); |
} |
for (; i < c; i++) { |
522,10 → 511,10 |
/** Destroy address space area. |
* |
* @param as Address space. |
* @param address Address withing the area to be deleted. |
* @param as Address space. |
* @param address Address within the area to be deleted. |
* |
* @return Zero on success or a value from @ref errno.h on failure. |
* @return Zero on success or a value from @ref errno.h on failure. |
*/ |
int as_area_destroy(as_t *as, uintptr_t address) |
{ |
622,18 → 611,19 |
* sh_info of the source area. The process of duplicating the |
* mapping is done through the backend share function. |
* |
* @param src_as Pointer to source address space. |
* @param src_base Base address of the source address space area. |
* @param acc_size Expected size of the source area. |
* @param dst_as Pointer to destination address space. |
* @param dst_base Target base address. |
* @param src_as Pointer to source address space. |
* @param src_base Base address of the source address space area. |
* @param acc_size Expected size of the source area. |
* @param dst_as Pointer to destination address space. |
* @param dst_base Target base address. |
* @param dst_flags_mask Destination address space area flags mask. |
* |
* @return Zero on success or ENOENT if there is no such task or if there is no |
* such address space area, EPERM if there was a problem in accepting the area |
* or ENOMEM if there was a problem in allocating destination address space |
* area. ENOTSUP is returned if the address space area backend does not support |
* sharing. |
* @return Zero on success or ENOENT if there is no such task or if |
* there is no such address space area, EPERM if there was |
* a problem in accepting the area or ENOMEM if there was a |
* problem in allocating destination address space area. |
* ENOTSUP is returned if the address space area backend |
* does not support sharing. |
*/ |
int as_area_share(as_t *src_as, uintptr_t src_base, size_t acc_size, |
as_t *dst_as, uintptr_t dst_base, int dst_flags_mask) |
752,10 → 742,11 |
* |
* The address space area must be locked prior to this call. |
* |
* @param area Address space area. |
* @param access Access mode. |
* @param area Address space area. |
* @param access Access mode. |
* |
* @return False if access violates area's permissions, true otherwise. |
* @return False if access violates area's permissions, true |
* otherwise. |
*/ |
bool as_area_check_access(as_area_t *area, pf_access_t access) |
{ |
771,7 → 762,7 |
return true; |
} |
/** Change adress area flags. |
/** Change adress space area flags. |
* |
* The idea is to have the same data, but with a different access mode. |
* This is needed e.g. for writing code into memory and then executing it. |
778,11 → 769,11 |
* In order for this to work properly, this may copy the data |
* into private anonymous memory (unless it's already there). |
* |
* @param as Address space. |
* @param flags Flags of the area memory. |
* @param address Address withing the area to be changed. |
* @param as Address space. |
* @param flags Flags of the area memory. |
* @param address Address withing the area to be changed. |
* |
* @return Zero on success or a value from @ref errno.h on failure. |
* @return Zero on success or a value from @ref errno.h on failure. |
*/ |
int as_area_change_flags(as_t *as, int flags, uintptr_t address) |
{ |
887,9 → 878,14 |
tlb_shootdown_finalize(); |
/* |
* Set the new flags. |
*/ |
area->flags = flags; |
/* |
* Map pages back in with new flags. This step is kept separate |
* so that there's no instant when the memory area could be |
* accesed with both the old and the new flags at once. |
* so that the memory area could not be accesed with both the old and |
* the new flags at once. |
*/ |
frame_idx = 0; |
927,19 → 923,20 |
/** Handle page fault within the current address space. |
* |
* This is the high-level page fault handler. It decides |
* whether the page fault can be resolved by any backend |
* and if so, it invokes the backend to resolve the page |
* fault. |
* This is the high-level page fault handler. It decides whether the page fault |
* can be resolved by any backend and if so, it invokes the backend to resolve |
* the page fault. |
* |
* Interrupts are assumed disabled. |
* |
* @param page Faulting page. |
* @param access Access mode that caused the fault (i.e. read/write/exec). |
* @param istate Pointer to interrupted state. |
* @param page Faulting page. |
* @param access Access mode that caused the page fault (i.e. |
* read/write/exec). |
* @param istate Pointer to the interrupted state. |
* |
* @return AS_PF_FAULT on page fault, AS_PF_OK on success or AS_PF_DEFER if the |
* fault was caused by copy_to_uspace() or copy_from_uspace(). |
* @return AS_PF_FAULT on page fault, AS_PF_OK on success or |
* AS_PF_DEFER if the fault was caused by copy_to_uspace() |
* or copy_from_uspace(). |
*/ |
int as_page_fault(uintptr_t page, pf_access_t access, istate_t *istate) |
{ |
985,9 → 982,8 |
page_table_lock(AS, false); |
/* |
* To avoid race condition between two page faults |
* on the same address, we need to make sure |
* the mapping has not been already inserted. |
* To avoid race condition between two page faults on the same address, |
* we need to make sure the mapping has not been already inserted. |
*/ |
if ((pte = page_mapping_find(AS, page))) { |
if (PTE_PRESENT(pte)) { |
1041,8 → 1037,8 |
* |
* When this function is enetered, no spinlocks may be held. |
* |
* @param old Old address space or NULL. |
* @param new New address space. |
* @param old Old address space or NULL. |
* @param new New address space. |
*/ |
void as_switch(as_t *old_as, as_t *new_as) |
{ |
1113,9 → 1109,9 |
/** Convert address space area flags to page flags. |
* |
* @param aflags Flags of some address space area. |
* @param aflags Flags of some address space area. |
* |
* @return Flags to be passed to page_mapping_insert(). |
* @return Flags to be passed to page_mapping_insert(). |
*/ |
int area_flags_to_page_flags(int aflags) |
{ |
1143,9 → 1139,9 |
* The address space area must be locked. |
* Interrupts must be disabled. |
* |
* @param a Address space area. |
* @param a Address space area. |
* |
* @return Flags to be used in page_mapping_insert(). |
* @return Flags to be used in page_mapping_insert(). |
*/ |
int as_area_get_flags(as_area_t *a) |
{ |
1154,23 → 1150,20 |
/** Create page table. |
* |
* Depending on architecture, create either address space |
* private or global page table. |
* Depending on architecture, create either address space private or global page |
* table. |
* |
* @param flags Flags saying whether the page table is for kernel address space. |
* @param flags Flags saying whether the page table is for the kernel |
* address space. |
* |
* @return First entry of the page table. |
* @return First entry of the page table. |
*/ |
pte_t *page_table_create(int flags) |
{ |
#ifdef __OBJC__ |
return [as_t page_table_create: flags]; |
#else |
ASSERT(as_operations); |
ASSERT(as_operations->page_table_create); |
return as_operations->page_table_create(flags); |
#endif |
} |
/** Destroy page table. |
1177,18 → 1170,14 |
* |
* Destroy page table in architecture specific way. |
* |
* @param page_table Physical address of PTL0. |
* @param page_table Physical address of PTL0. |
*/ |
void page_table_destroy(pte_t *page_table) |
{ |
#ifdef __OBJC__ |
return [as_t page_table_destroy: page_table]; |
#else |
ASSERT(as_operations); |
ASSERT(as_operations->page_table_destroy); |
as_operations->page_table_destroy(page_table); |
#endif |
} |
/** Lock page table. |
1200,36 → 1189,28 |
* prior to this call. Address space can be locked prior to this |
* call in which case the lock argument is false. |
* |
* @param as Address space. |
* @param lock If false, do not attempt to lock as->lock. |
* @param as Address space. |
* @param lock If false, do not attempt to lock as->lock. |
*/ |
void page_table_lock(as_t *as, bool lock) |
{ |
#ifdef __OBJC__ |
[as page_table_lock: lock]; |
#else |
ASSERT(as_operations); |
ASSERT(as_operations->page_table_lock); |
as_operations->page_table_lock(as, lock); |
#endif |
} |
/** Unlock page table. |
* |
* @param as Address space. |
* @param unlock If false, do not attempt to unlock as->lock. |
* @param as Address space. |
* @param unlock If false, do not attempt to unlock as->lock. |
*/ |
void page_table_unlock(as_t *as, bool unlock) |
{ |
#ifdef __OBJC__ |
[as page_table_unlock: unlock]; |
#else |
ASSERT(as_operations); |
ASSERT(as_operations->page_table_unlock); |
as_operations->page_table_unlock(as, unlock); |
#endif |
} |
1237,11 → 1218,11 |
* |
* The address space must be locked and interrupts must be disabled. |
* |
* @param as Address space. |
* @param va Virtual address. |
* @param as Address space. |
* @param va Virtual address. |
* |
* @return Locked address space area containing va on success or NULL on |
* failure. |
* @return Locked address space area containing va on success or |
* NULL on failure. |
*/ |
as_area_t *find_area_and_lock(as_t *as, uintptr_t va) |
{ |
1293,15 → 1274,15 |
* |
* The address space must be locked and interrupts must be disabled. |
* |
* @param as Address space. |
* @param va Starting virtual address of the area being tested. |
* @param size Size of the area being tested. |
* @param avoid_area Do not touch this area. |
* @param as Address space. |
* @param va Starting virtual address of the area being tested. |
* @param size Size of the area being tested. |
* @param avoid_area Do not touch this area. |
* |
* @return True if there is no conflict, false otherwise. |
* @return True if there is no conflict, false otherwise. |
*/ |
bool check_area_conflicts(as_t *as, uintptr_t va, size_t size, |
as_area_t *avoid_area) |
bool |
check_area_conflicts(as_t *as, uintptr_t va, size_t size, as_area_t *avoid_area) |
{ |
as_area_t *a; |
btree_node_t *leaf, *node; |
1390,7 → 1371,7 |
ipl = interrupts_disable(); |
src_area = find_area_and_lock(AS, base); |
if (src_area){ |
if (src_area) { |
size = src_area->pages * PAGE_SIZE; |
mutex_unlock(&src_area->lock); |
} else { |
1404,11 → 1385,11 |
* |
* The address space area must be already locked. |
* |
* @param a Address space area. |
* @param page First page to be marked. |
* @param count Number of page to be marked. |
* @param a Address space area. |
* @param page First page to be marked. |
* @param count Number of page to be marked. |
* |
* @return 0 on failure and 1 on success. |
* @return Zero on failure and non-zero on success. |
*/ |
int used_space_insert(as_area_t *a, uintptr_t page, count_t count) |
{ |
1678,8 → 1659,8 |
} |
} |
panic("Inconsistency detected while adding %" PRIc " pages of used space at " |
"%p.\n", count, page); |
panic("Inconsistency detected while adding %" PRIc " pages of used " |
"space at %p.\n", count, page); |
} |
/** Mark portion of address space area as unused. |
1686,11 → 1667,11 |
* |
* The address space area must be already locked. |
* |
* @param a Address space area. |
* @param page First page to be marked. |
* @param count Number of page to be marked. |
* @param a Address space area. |
* @param page First page to be marked. |
* @param count Number of page to be marked. |
* |
* @return 0 on failure and 1 on success. |
* @return Zero on failure and non-zero on success. |
*/ |
int used_space_remove(as_area_t *a, uintptr_t page, count_t count) |
{ |
1857,8 → 1838,8 |
} |
error: |
panic("Inconsistency detected while removing %" PRIc " pages of used space " |
"from %p.\n", count, page); |
panic("Inconsistency detected while removing %" PRIc " pages of used " |
"space from %p.\n", count, page); |
} |
/** Remove reference to address space area share info. |
1865,7 → 1846,7 |
* |
* If the reference count drops to 0, the sh_info is deallocated. |
* |
* @param sh_info Pointer to address space area share info. |
* @param sh_info Pointer to address space area share info. |
*/ |
void sh_info_remove_reference(share_info_t *sh_info) |
{ |
1934,7 → 1915,7 |
/** Print out information about address space. |
* |
* @param as Address space. |
* @param as Address space. |
*/ |
void as_print(as_t *as) |
{ |
1956,9 → 1937,9 |
as_area_t *area = node->value[i]; |
mutex_lock(&area->lock); |
printf("as_area: %p, base=%p, pages=%" PRIc " (%p - %p)\n", |
area, area->base, area->pages, area->base, |
area->base + FRAMES2SIZE(area->pages)); |
printf("as_area: %p, base=%p, pages=%" PRIc |
" (%p - %p)\n", area, area->base, area->pages, |
area->base, area->base + FRAMES2SIZE(area->pages)); |
mutex_unlock(&area->lock); |
} |
} |
/branches/dynload/kernel/generic/src/mm/backend_elf.c |
---|
118,7 → 118,7 |
*/ |
for (i = 0; i < leaf->keys; i++) { |
if (leaf->key[i] == page) { |
if (leaf->key[i] == page - area->base) { |
found = true; |
break; |
} |
/branches/dynload/kernel/generic/src/ipc/ipcrsc.c |
---|
170,7 → 170,6 |
int i; |
spinlock_lock(&TASK->lock); |
for (i = 0; i < IPC_MAX_PHONES; i++) { |
if (TASK->phones[i].state == IPC_PHONE_HUNGUP && |
atomic_get(&TASK->phones[i].active_calls) == 0) |
183,8 → 182,9 |
} |
spinlock_unlock(&TASK->lock); |
if (i >= IPC_MAX_PHONES) |
if (i == IPC_MAX_PHONES) |
return -1; |
return i; |
} |
/branches/dynload/kernel/generic/src/ipc/sysipc.c |
---|
270,12 → 270,12 |
/* The recipient agreed to receive data. */ |
int rc; |
uintptr_t dst; |
uintptr_t size; |
uintptr_t max_size; |
size_t size; |
size_t max_size; |
dst = IPC_GET_ARG1(answer->data); |
size = IPC_GET_ARG2(answer->data); |
max_size = IPC_GET_ARG2(*olddata); |
dst = (uintptr_t)IPC_GET_ARG1(answer->data); |
size = (size_t)IPC_GET_ARG2(answer->data); |
max_size = (size_t)IPC_GET_ARG2(*olddata); |
if (size <= max_size) { |
rc = copy_to_uspace((void *) dst, |
442,7 → 442,9 |
IPC_SET_ARG5(call.data, 0); |
if (!(res = request_preprocess(&call))) { |
ipc_call_sync(phone, &call); |
rc = ipc_call_sync(phone, &call); |
if (rc != EOK) |
return rc; |
process_answer(&call); |
} else { |
IPC_SET_RETVAL(call.data, res); |
480,7 → 482,9 |
GET_CHECK_PHONE(phone, phoneid, return ENOENT); |
if (!(res = request_preprocess(&call))) { |
ipc_call_sync(phone, &call); |
rc = ipc_call_sync(phone, &call); |
if (rc != EOK) |
return rc; |
process_answer(&call); |
} else |
IPC_SET_RETVAL(call.data, res); |
/branches/dynload/kernel/generic/src/ipc/ipc.c |
---|
171,8 → 171,10 |
* |
* @param phone Destination kernel phone structure. |
* @param request Call structure with request. |
* |
* @return EOK on success or EINTR if the sleep was interrupted. |
*/ |
void ipc_call_sync(phone_t *phone, call_t *request) |
int ipc_call_sync(phone_t *phone, call_t *request) |
{ |
answerbox_t sync_box; |
182,7 → 184,10 |
request->callerbox = &sync_box; |
ipc_call(phone, request); |
ipc_wait_for_call(&sync_box, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE); |
if (!ipc_wait_for_call(&sync_box, SYNCH_NO_TIMEOUT, |
SYNCH_FLAGS_INTERRUPTIBLE)) |
return EINTR; |
return EOK; |
} |
/** Answer a message which was not dispatched and is not listed in any queue. |
195,6 → 200,13 |
call->flags |= IPC_CALL_ANSWERED; |
if (call->flags & IPC_CALL_FORWARDED) { |
if (call->caller_phone) { |
/* Demasquerade the caller phone. */ |
call->data.phone = call->caller_phone; |
} |
} |
spinlock_lock(&callerbox->lock); |
list_append(&call->link, &callerbox->answers); |
spinlock_unlock(&callerbox->lock); |
347,8 → 359,11 |
list_remove(&call->link); |
spinlock_unlock(&oldbox->lock); |
if (mode & IPC_FF_ROUTE_FROM_ME) |
if (mode & IPC_FF_ROUTE_FROM_ME) { |
if (!call->caller_phone) |
call->caller_phone = call->data.phone; |
call->data.phone = newphone; |
} |
return ipc_call(newphone, call); |
} |
577,8 → 592,9 |
tmp = tmp->next) { |
call = list_get_instance(tmp, call_t, link); |
printf("Callid: %p Srctask:%" PRIu64 " M:%" PRIun |
" A1:%" PRIun " A2:%" PRIun " A3:%" PRIun |
" A4:%" PRIun " A5:%" PRIun " Flags:%x\n", call, call->sender->taskid, |
" A1:%" PRIun " A2:%" PRIun " A3:%" PRIun |
" A4:%" PRIun " A5:%" PRIun " Flags:%x\n", call, |
call->sender->taskid, |
IPC_GET_METHOD(call->data), IPC_GET_ARG1(call->data), |
IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data), |
IPC_GET_ARG4(call->data), IPC_GET_ARG5(call->data), |
591,8 → 607,9 |
tmp = tmp->next) { |
call = list_get_instance(tmp, call_t, link); |
printf("Callid: %p Srctask:%" PRIu64 " M:%" PRIun |
" A1:%" PRIun " A2:%" PRIun " A3:%" PRIun |
" A4:%" PRIun " A5:%" PRIun " Flags:%x\n", call, call->sender->taskid, |
" A1:%" PRIun " A2:%" PRIun " A3:%" PRIun |
" A4:%" PRIun " A5:%" PRIun " Flags:%x\n", call, |
call->sender->taskid, |
IPC_GET_METHOD(call->data), IPC_GET_ARG1(call->data), |
IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data), |
IPC_GET_ARG4(call->data), IPC_GET_ARG5(call->data), |
600,11 → 617,12 |
} |
/* Print answerbox - calls */ |
printf("ABOX - ANSWERS:\n"); |
for (tmp = task->answerbox.answers.next; tmp != &task->answerbox.answers; |
for (tmp = task->answerbox.answers.next; |
tmp != &task->answerbox.answers; |
tmp = tmp->next) { |
call = list_get_instance(tmp, call_t, link); |
printf("Callid:%p M:%" PRIun " A1:%" PRIun " A2:%" PRIun |
" A3:%" PRIun " A4:%" PRIun " A5:%" PRIun " Flags:%x\n", |
" A3:%" PRIun " A4:%" PRIun " A5:%" PRIun " Flags:%x\n", |
call, IPC_GET_METHOD(call->data), IPC_GET_ARG1(call->data), |
IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data), |
IPC_GET_ARG4(call->data), IPC_GET_ARG5(call->data), |
/branches/dynload/kernel/Makefile |
---|
317,16 → 317,6 |
test/sysinfo/sysinfo1.c |
endif |
## Experimental features |
# |
ifeq ($(CONFIG_EXPERIMENTAL),y) |
GENERIC_SOURCES += generic/src/lib/objc_ext.c \ |
generic/src/lib/objc.c |
EXTRA_OBJECTS = $(LIBDIR)/libobjc.a |
EXTRA_FLAGS += -x objective-c |
endif |
GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES))) |
ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES))) |
GENARCH_OBJECTS := $(addsuffix .o,$(basename $(GENARCH_SOURCES))) |
/branches/dynload/kernel/arch/sparc64/include/atomic.h |
---|
37,6 → 37,7 |
#include <arch/barrier.h> |
#include <arch/types.h> |
#include <preemption.h> |
/** Atomic add operation. |
* |
56,7 → 57,8 |
a = *((uint64_t *) x); |
b = a + i; |
asm volatile ("casx %0, %2, %1\n" : "+m" (*((uint64_t *)x)), "+r" (b) : "r" (a)); |
asm volatile ("casx %0, %2, %1\n" : "+m" (*((uint64_t *)x)), |
"+r" (b) : "r" (a)); |
} while (a != b); |
return a; |
97,7 → 99,8 |
uint64_t v = 1; |
volatile uintptr_t x = (uint64_t) &val->count; |
asm volatile ("casx %0, %2, %1\n" : "+m" (*((uint64_t *) x)), "+r" (v) : "r" (0)); |
asm volatile ("casx %0, %2, %1\n" : "+m" (*((uint64_t *) x)), |
"+r" (v) : "r" (0)); |
return v; |
} |
109,6 → 112,8 |
volatile uintptr_t x = (uint64_t) &val->count; |
preemption_disable(); |
asm volatile ( |
"0:\n" |
"casx %0, %3, %1\n" |
/branches/dynload/kernel/arch/sparc64/include/mm/page.h |
---|
53,11 → 53,6 |
#define MMU_PAGES_PER_PAGE (1 << (PAGE_WIDTH - MMU_PAGE_WIDTH)) |
/* |
* With 16K pages, there is only one page color. |
*/ |
#define PAGE_COLOR_BITS 0 /**< 14 - 14; 2^14 == 16K == alias boundary. */ |
#ifdef KERNEL |
#ifndef __ASM__ |
/branches/dynload/kernel/arch/sparc64/Makefile.inc |
---|
29,11 → 29,15 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf64-sparc |
BFD_ARCH = sparc |
BFD = binary |
TARGET = sparc64-linux-gnu |
TOOLCHAIN_DIR = /usr/local/sparc64 |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/sparc64 |
GCC_CFLAGS += -m64 -mcpu=ultrasparc |
SUNCC_CFLAGS += -m64 -xarch=sparc -xregs=appl,no%float |
/branches/dynload/kernel/arch/sparc64/src/asm.S |
---|
41,6 → 41,7 |
*/ |
.global memcpy |
memcpy: |
mov %o0, %o3 ! save dst |
add %o1, 7, %g1 |
and %g1, -8, %g1 |
cmp %o1, %g1 |
59,7 → 60,7 |
mov %g2, %g3 |
2: |
jmp %o7 + 8 ! exit point |
mov %o1, %o0 |
mov %o3, %o0 |
3: |
and %g1, -8, %g1 |
cmp %o0, %g1 |
93,7 → 94,7 |
mov %g2, %g3 |
jmp %o7 + 8 ! exit point |
mov %o1, %o0 |
mov %o3, %o0 |
/* |
* Almost the same as memcpy() except the loads are from userspace. |
100,6 → 101,7 |
*/ |
.global memcpy_from_uspace |
memcpy_from_uspace: |
mov %o0, %o3 ! save dst |
add %o1, 7, %g1 |
and %g1, -8, %g1 |
cmp %o1, %g1 |
118,7 → 120,7 |
mov %g2, %g3 |
2: |
jmp %o7 + 8 ! exit point |
mov %o1, %o0 |
mov %o3, %o0 |
3: |
and %g1, -8, %g1 |
cmp %o0, %g1 |
152,7 → 154,7 |
mov %g2, %g3 |
jmp %o7 + 8 ! exit point |
mov %o1, %o0 |
mov %o3, %o0 |
/* |
* Almost the same as memcpy() except the stores are to userspace. |
159,6 → 161,7 |
*/ |
.global memcpy_to_uspace |
memcpy_to_uspace: |
mov %o0, %o3 ! save dst |
add %o1, 7, %g1 |
and %g1, -8, %g1 |
cmp %o1, %g1 |
177,7 → 180,7 |
mov %g2, %g3 |
2: |
jmp %o7 + 8 ! exit point |
mov %o1, %o0 |
mov %o3, %o0 |
3: |
and %g1, -8, %g1 |
cmp %o0, %g1 |
211,7 → 214,7 |
mov %g2, %g3 |
jmp %o7 + 8 ! exit point |
mov %o1, %o0 |
mov %o3, %o0 |
.global memcpy_from_uspace_failover_address |
.global memcpy_to_uspace_failover_address |
/branches/dynload/kernel/arch/ia64/include/mm/page.h |
---|
41,8 → 41,6 |
#define PAGE_SIZE FRAME_SIZE |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#ifdef KERNEL |
/** Bit width of the TLB-locked portion of kernel address space. */ |
/branches/dynload/kernel/arch/ia64/Makefile.inc |
---|
29,14 → 29,15 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf64-little |
BFD_ARCH = ia64-elf64 |
TARGET = ia64-pc-linux-gnu |
TOOLCHAIN_DIR = /usr/local/ia64 |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ia64 |
INIT0_ADDRESS = 0xe000000004404000 |
INIT0_SIZE = 0x100000 |
CMN1 = -mconstant-gp -fno-unwind-tables -mfixed-range=f32-f127 |
GCC_CFLAGS += $(CMN1) |
ICC_CFLAGS += $(CMN1) |
44,9 → 45,8 |
LFLAGS += -EL |
AFLAGS += -mconstant-gp |
DEFS += -D__64_BITS__ -DINIT0_ADDRESS=$(INIT0_ADDRESS) -DINIT0_SIZE=$(INIT0_SIZE) -D$(MACHINE) |
DEFS += -D__64_BITS__ -D$(MACHINE) |
## Compile with page hash table support. |
# |
96,6 → 96,5 |
CONFIG_I8042 = y |
DEFS += -DI460GX -DCONFIG_I8042 |
BFD = binary |
endif |
/branches/dynload/kernel/arch/ia64/src/asm.S |
---|
51,7 → 51,7 |
adds r14 = 7, in1 |
mov r2 = ar.lc |
mov r8 = in1 ;; |
mov r8 = in0 |
and r14 = -8, r14 ;; |
cmp.ne p6, p7 = r14, in1 |
(p7) br.cond.dpnt 3f ;; |
63,7 → 63,7 |
(p6) mov r17 = r0 ;; |
(p6) mov ar.lc = r14 |
1: |
add r14 = r16, r8 |
add r14 = r16, in1 |
add r15 = r16, in0 |
adds r17 = 1, r17 ;; |
ld1 r14 = [r14] |
72,7 → 72,6 |
br.cloop.sptk.few 1b ;; |
2: |
mov ar.lc = r2 |
mov ar.pfs = loc0 |
br.ret.sptk.many rp |
3: |
90,7 → 89,7 |
4: |
shladd r14 = r16, 3, r0 |
adds r16 = 1, r17 ;; |
add r15 = r8, r14 |
add r15 = in1, r14 |
add r14 = in0, r14 |
mov r17 = r16 ;; |
ld8 r15 = [r15] ;; |
104,7 → 103,7 |
cmp.eq p6, p7 = 0, r15 |
add in0 = r14, in0 |
adds r15 = -1, r15 |
add r17 = r14, r8 |
add r17 = r14, in1 |
(p6) br.cond.dpnt 2b ;; |
mov ar.lc = r15 |
6: |
116,7 → 115,6 |
st1 [r15] = r14 |
br.cloop.sptk.few 6b ;; |
mov ar.lc = r2 |
mov ar.pfs = loc0 |
br.ret.sptk.many rp |
/branches/dynload/kernel/arch/arm32/include/mm/page.h |
---|
43,8 → 43,6 |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_SIZE FRAME_SIZE |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#ifndef __ASM__ |
# define KA2PA(x) (((uintptr_t) (x)) - 0x80000000) |
# define PA2KA(x) (((uintptr_t) (x)) + 0x80000000) |
/branches/dynload/kernel/arch/arm32/Makefile.inc |
---|
29,11 → 29,15 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf32-littlearm |
BFD_ARCH = arm |
BFD = binary |
TARGET = arm-linux-gnu |
TOOLCHAIN_DIR = /usr/local/arm |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm |
KERNEL_LOAD_ADDRESS = 0x80200000 |
/branches/dynload/kernel/arch/arm32/src/asm.S |
---|
45,7 → 45,8 |
add r3, r1, #3 |
bic r3, r3, #3 |
cmp r1, r3 |
stmdb sp!, {r4, lr} |
stmdb sp!, {r4, r5, lr} |
mov r5, r0 /* save dst */ |
beq 4f |
1: |
cmp r2, #0 |
58,8 → 59,8 |
cmp ip, r2 |
bne 2b |
3: |
mov r0, r1 |
ldmia sp!, {r4, pc} |
mov r0, r5 |
ldmia sp!, {r4, r5, pc} |
4: |
add r3, r0, #3 |
bic r3, r3, #3 |
94,5 → 95,5 |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
mov r0, #0 |
ldmia sp!, {r4, pc} |
mov r0, #0 |
ldmia sp!, {r4, r5, pc} |
/branches/dynload/kernel/arch/ppc32/include/mm/page.h |
---|
40,8 → 40,6 |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_SIZE FRAME_SIZE |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#ifdef KERNEL |
#ifndef __ASM__ |
/branches/dynload/kernel/arch/ppc32/Makefile.inc |
---|
29,11 → 29,15 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf32-powerpc |
BFD_ARCH = powerpc:common |
BFD = binary |
TARGET = ppc-linux-gnu |
TOOLCHAIN_DIR = /usr/local/ppc |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc |
GCC_CFLAGS += -mcpu=powerpc -msoft-float -m32 |
AFLAGS += -a32 |
/branches/dynload/kernel/arch/ia32xen/include/mm/page.h |
---|
40,8 → 40,6 |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_SIZE FRAME_SIZE |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#ifdef KERNEL |
#ifndef __ASM__ |
/branches/dynload/kernel/arch/ia32xen/Makefile.inc |
---|
29,11 → 29,15 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf32-i386 |
BFD_ARCH = i386 |
BFD = elf32-i386 |
TARGET = i686-pc-linux-gnu |
TOOLCHAIN_DIR = /usr/local/i686 |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/i686 |
DEFS += -DMACHINE=$(MACHINE) -D__32_BITS__ |
/branches/dynload/kernel/arch/ia32xen/src/asm.S |
---|
67,7 → 67,7 |
* @param MEMCPY_SRC(%esp) Source address. |
* @param MEMCPY_SIZE(%esp) Size. |
* |
* @return MEMCPY_SRC(%esp) on success and 0 on failure. |
* @return MEMCPY_DST(%esp) on success and 0 on failure. |
*/ |
memcpy: |
memcpy_from_uspace: |
92,7 → 92,7 |
0: |
movl %edx, %edi |
movl %eax, %esi |
movl MEMCPY_SRC(%esp), %eax /* MEMCPY_SRC(%esp), success */ |
movl MEMCPY_DST(%esp), %eax /* MEMCPY_DST(%esp), success */ |
ret |
/* |
/branches/dynload/kernel/arch/amd64/include/atomic.h |
---|
108,13 → 108,13 |
#endif |
"mov %0, %1\n" |
"testq %1, %1\n" |
"jnz 0b\n" /* Lightweight looping on locked spinlock */ |
"jnz 0b\n" /* lightweight looping on locked spinlock */ |
"incq %1\n" /* now use the atomic operation */ |
"xchgq %0, %1\n" |
"testq %1, %1\n" |
"jnz 0b\n" |
: "+m" (val->count), "=r"(tmp) |
: "+m" (val->count), "=&r" (tmp) |
); |
/* |
* Prevent critical section code from bleeding out this way up. |
/branches/dynload/kernel/arch/amd64/include/mm/page.h |
---|
52,8 → 52,6 |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_SIZE FRAME_SIZE |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#ifdef KERNEL |
#ifndef __ASM__ |
/branches/dynload/kernel/arch/amd64/Makefile.inc |
---|
29,11 → 29,15 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf64-x86-64 |
BFD_ARCH = i386:x86-64 |
BFD = binary |
TARGET = amd64-linux-gnu |
TOOLCHAIN_DIR = /usr/local/amd64 |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/amd64 |
FPU_NO_CFLAGS = -mno-sse -mno-sse2 |
CMN1 = -m64 -mcmodel=kernel -mno-red-zone -fno-unwind-tables |
/branches/dynload/kernel/arch/amd64/src/asm_utils.S |
---|
98,12 → 98,12 |
* @param MEMCPY_SRC Source address. |
* @param MEMCPY_SIZE Number of bytes to copy. |
* |
* @retrun MEMCPY_SRC on success, 0 on failure. |
* @retrun MEMCPY_DST on success, 0 on failure. |
*/ |
memcpy: |
memcpy_from_uspace: |
memcpy_to_uspace: |
movq MEMCPY_SRC, %rax |
movq MEMCPY_DST, %rax |
movq MEMCPY_SIZE, %rcx |
shrq $3, %rcx /* size / 8 */ |
/branches/dynload/kernel/arch/ppc64/include/mm/page.h |
---|
40,8 → 40,6 |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_SIZE FRAME_SIZE |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#ifdef KERNEL |
#ifndef __ASM__ |
/branches/dynload/kernel/arch/ppc64/Makefile.inc |
---|
29,11 → 29,15 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf64-powerpc |
BFD_ARCH = powerpc:common64 |
BFD = binary |
TARGET = ppc64-linux-gnu |
TOOLCHAIN_DIR = /usr/local/ppc64 |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc64 |
GCC_CFLAGS += -mcpu=powerpc64 -msoft-float -m64 |
AFLAGS += -a64 |
/branches/dynload/kernel/arch/mips32/include/mm/page.h |
---|
40,8 → 40,6 |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_SIZE FRAME_SIZE |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#ifndef __ASM__ |
# define KA2PA(x) (((uintptr_t) (x)) - 0x80000000) |
# define PA2KA(x) (((uintptr_t) (x)) + 0x80000000) |
/branches/dynload/kernel/arch/mips32/include/mm/tlb.h |
---|
35,6 → 35,9 |
#ifndef KERN_mips32_TLB_H_ |
#define KERN_mips32_TLB_H_ |
#include <arch/types.h> |
#include <typedefs.h> |
#include <arch/mm/asid.h> |
#include <arch/exception.h> |
#ifdef TLBCNT |
46,7 → 49,13 |
#define TLB_WIRED 1 |
#define TLB_KSTACK_WIRED_INDEX 0 |
#define TLB_PAGE_MASK_16K (0x3<<13) |
#define TLB_PAGE_MASK_4K (0x000 << 13) |
#define TLB_PAGE_MASK_16K (0x003 << 13) |
#define TLB_PAGE_MASK_64K (0x00f << 13) |
#define TLB_PAGE_MASK_256K (0x03f << 13) |
#define TLB_PAGE_MASK_1M (0x0ff << 13) |
#define TLB_PAGE_MASK_4M (0x3ff << 13) |
#define TLB_PAGE_MASK_16M (0xfff << 13) |
#define PAGE_UNCACHED 2 |
#define PAGE_CACHEABLE_EXC_WRITE 5 |
159,6 → 168,8 |
extern void tlb_invalid(istate_t *istate); |
extern void tlb_refill(istate_t *istate); |
extern void tlb_modified(istate_t *istate); |
extern void tlb_prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn); |
extern void tlb_prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr); |
#endif |
/branches/dynload/kernel/arch/mips32/include/mm/as.h |
---|
38,7 → 38,7 |
#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH 0 |
#define KERNEL_ADDRESS_SPACE_START_ARCH (unsigned long) 0x80000000 |
#define KERNEL_ADDRESS_SPACE_END_ARCH (unsigned long) 0xffffffff |
#define KERNEL_ADDRESS_SPACE_END_ARCH (unsigned long) 0x9fffffff |
#define USER_ADDRESS_SPACE_START_ARCH (unsigned long) 0x00000000 |
#define USER_ADDRESS_SPACE_END_ARCH (unsigned long) 0x7fffffff |
/branches/dynload/kernel/arch/mips32/include/drivers/arc.h |
---|
File deleted |
/branches/dynload/kernel/arch/mips32/include/drivers/serial.h |
---|
37,6 → 37,8 |
#include <console/chardev.h> |
#define SERIAL_ADDRESS 0x98000000 |
#define SERIAL_MAX 4 |
#define SERIAL_COM1 0x3f8 |
#define SERIAL_COM1_IRQ 4 |
43,16 → 45,19 |
#define SERIAL_COM2 0x2f8 |
#define SERIAL_COM2_IRQ 3 |
#define P_WRITEB(where,what) (*((volatile char *) (0xB8000000+where))=what) |
#define P_READB(where) (*((volatile char *)(0xB8000000+where))) |
#define P_WRITEB(where, what) (*((volatile char *) (SERIAL_ADDRESS + where)) = what) |
#define P_READB(where) (*((volatile char *) (SERIAL_ADDRESS + where))) |
#define SERIAL_READ(x) P_READB(x) |
#define SERIAL_WRITE(x,c) P_WRITEB(x,c) |
#define SERIAL_READ(x) P_READB(x) |
#define SERIAL_WRITE(x, c) P_WRITEB(x, c) |
/* Interrupt enable register */ |
#define SERIAL_READ_IER(x) (P_READB((x) + 1)) |
#define SERIAL_WRITE_IER(x,c) (P_WRITEB((x)+1,c)) |
#define SERIAL_WRITE_IER(x,c) (P_WRITEB((x) + 1, c)) |
/* Interrupt identification register */ |
#define SERIAL_READ_IIR(x) (P_READB((x) + 2)) |
/* Line status register */ |
#define SERIAL_READ_LSR(x) (P_READB((x) + 5)) |
#define TRANSMIT_EMPTY_BIT 5 |
/branches/dynload/kernel/arch/mips32/include/drivers/msim.h |
---|
35,6 → 35,11 |
#ifndef KERN_mips32_MSIM_H_ |
#define KERN_mips32_MSIM_H_ |
/** Address of devices. */ |
#define MSIM_VIDEORAM 0x90000000 |
#define MSIM_KBD_ADDRESS 0x90000000 |
#define MSIM_KBD_IRQ 2 |
#include <console/chardev.h> |
void msim_console(devno_t devno); |
/branches/dynload/kernel/arch/mips32/Makefile.inc |
---|
29,17 → 29,19 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_ARCH = mips |
TARGET = mipsel-linux-gnu |
TOOLCHAIN_DIR = /usr/local/mipsel |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mipsel |
KERNEL_LOAD_ADDRESS = 0x80100000 |
INIT_ADDRESS = 0x81000000 |
INIT_SIZE = 262144 |
GCC_CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss |
DEFS += -D__32_BITS__ -DMACHINE=$(MACHINE) -DKERNEL_LOAD_ADDRESS=${KERNEL_LOAD_ADDRESS} -DINIT_ADDRESS=${INIT_ADDRESS} -DINIT_SIZE=${INIT_SIZE} |
DEFS += -D__32_BITS__ -DMACHINE=$(MACHINE) -DKERNEL_LOAD_ADDRESS=${KERNEL_LOAD_ADDRESS} |
## Compile with hierarchical page tables support. |
# |
56,20 → 58,6 |
## Accepted MACHINEs |
# |
ifeq ($(MACHINE),indy) |
# GCC 4.0.1 compiled for mipsEL has problems compiling in |
# BigEndian mode with the swl/swr/lwl/lwr instructions. |
# We have to compile it with mips-sgi-irix5 to get it right. |
BFD_NAME = elf32-bigmips |
BFD = ecoff-bigmips --impure |
TARGET = mips-sgi-irix5 |
TOOLCHAIN_DIR = /usr/local/mips/bin |
KERNEL_LOAD_ADDRESS = 0x88002000 |
GCC_CFLAGS += -EB -DBIG_ENDIAN -DARCH_HAS_FPU -march=r4600 |
INIT_ADDRESS = 0 |
INIT_SIZE = 0 |
endif |
ifeq ($(MACHINE),lgxemul) |
BFD_NAME = elf32-tradlittlemips |
BFD = binary |
79,9 → 67,8 |
BFD_NAME = elf32-bigmips |
BFD = ecoff-bigmips |
TARGET = mips-sgi-irix5 |
TOOLCHAIN_DIR = /usr/local/mips/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips/bin |
GCC_CFLAGS += -EB -DBIG_ENDIAN -DARCH_HAS_FPU -mips3 |
INIT_ADDRESS = 0x81800000 |
endif |
ifeq ($(MACHINE),simics) |
# SIMICS 4kc emulation is broken, although for instructions |
123,7 → 110,6 |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/fpu_context.c \ |
arch/$(ARCH)/src/ddi/ddi.c \ |
arch/$(ARCH)/src/drivers/arc.c \ |
arch/$(ARCH)/src/drivers/msim.c \ |
arch/$(ARCH)/src/drivers/serial.c \ |
arch/$(ARCH)/src/smp/order.c |
/branches/dynload/kernel/arch/mips32/src/asm.S |
---|
71,6 → 71,7 |
and $v0,$v0,$v1 |
beq $a1,$v0,3f |
move $t0,$a0 |
move $t2,$a0 # save dst |
0: |
beq $a2,$zero,2f |
86,7 → 87,7 |
2: |
jr $ra |
move $v0,$a1 |
move $v0,$t2 |
3: |
addiu $v0,$a0,3 |
126,7 → 127,7 |
sb $a0,0($v1) |
jr $ra |
move $v0,$a1 |
move $v0,$t2 |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
/branches/dynload/kernel/arch/mips32/src/console.c |
---|
34,18 → 34,15 |
#include <console/console.h> |
#include <arch/console.h> |
#include <arch/drivers/arc.h> |
#include <arch/drivers/serial.h> |
#include <arch/drivers/msim.h> |
void console_init(devno_t devno) |
{ |
if (!arc_console()) { |
if (serial_init()) |
serial_console(devno); |
else |
msim_console(devno); |
} |
if (serial_init()) |
serial_console(devno); |
else |
msim_console(devno); |
} |
/** Acquire console back for kernel |
/branches/dynload/kernel/arch/mips32/src/mips32.c |
---|
48,7 → 48,6 |
#include <sysinfo/sysinfo.h> |
#include <arch/interrupt.h> |
#include <arch/drivers/arc.h> |
#include <console/chardev.h> |
#include <arch/barrier.h> |
#include <arch/debugger.h> |
97,7 → 96,6 |
/* Initialize dispatch table */ |
exception_init(); |
arc_init(); |
/* Copy the exception vectors to the right places */ |
memcpy(TLB_EXC, (char *) tlb_refill_entry, EXCEPTION_JUMP_SIZE); |
187,8 → 185,7 |
void arch_reboot(void) |
{ |
if (!arc_reboot()) |
___halt(); |
___halt(); |
while (1) |
; |
/branches/dynload/kernel/arch/mips32/src/mm/tlb.c |
---|
47,18 → 47,14 |
#include <align.h> |
#include <interrupt.h> |
static void tlb_refill_fail(istate_t *istate); |
static void tlb_invalid_fail(istate_t *istate); |
static void tlb_modified_fail(istate_t *istate); |
static void tlb_refill_fail(istate_t *); |
static void tlb_invalid_fail(istate_t *); |
static void tlb_modified_fail(istate_t *); |
static pte_t *find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, int *pfrc); |
static pte_t *find_mapping_and_check(uintptr_t, int, istate_t *, int *); |
static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn); |
static void prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr); |
/** Initialize TLB |
/** Initialize TLB. |
* |
* Initialize TLB. |
* Invalidate all entries and mark wired entries. |
*/ |
void tlb_arch_init(void) |
76,7 → 72,6 |
cp0_index_write(i); |
tlbwi(); |
} |
/* |
* The kernel is going to make use of some wired |
85,11 → 80,9 |
cp0_wired_write(TLB_WIRED); |
} |
/** Process TLB Refill Exception |
/** Process TLB Refill Exception. |
* |
* Process TLB Refill Exception. |
* |
* @param istate Interrupted register context. |
* @param istate Interrupted register context. |
*/ |
void tlb_refill(istate_t *istate) |
{ |
131,14 → 124,15 |
*/ |
pte->a = 1; |
prepare_entry_hi(&hi, asid, badvaddr); |
prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn); |
tlb_prepare_entry_hi(&hi, asid, badvaddr); |
tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, |
pte->pfn); |
/* |
* New entry is to be inserted into TLB |
*/ |
cp0_entry_hi_write(hi.value); |
if ((badvaddr/PAGE_SIZE) % 2 == 0) { |
if ((badvaddr / PAGE_SIZE) % 2 == 0) { |
cp0_entry_lo0_write(lo.value); |
cp0_entry_lo1_write(0); |
} |
157,11 → 151,9 |
tlb_refill_fail(istate); |
} |
/** Process TLB Invalid Exception |
/** Process TLB Invalid Exception. |
* |
* Process TLB Invalid Exception. |
* |
* @param istate Interrupted register context. |
* @param istate Interrupted register context. |
*/ |
void tlb_invalid(istate_t *istate) |
{ |
178,7 → 170,7 |
* Locate the faulting entry in TLB. |
*/ |
hi.value = cp0_entry_hi_read(); |
prepare_entry_hi(&hi, hi.asid, badvaddr); |
tlb_prepare_entry_hi(&hi, hi.asid, badvaddr); |
cp0_entry_hi_write(hi.value); |
tlbp(); |
index.value = cp0_index_read(); |
221,12 → 213,13 |
*/ |
pte->a = 1; |
prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn); |
tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, |
pte->pfn); |
/* |
* The entry is to be updated in TLB. |
*/ |
if ((badvaddr/PAGE_SIZE) % 2 == 0) |
if ((badvaddr / PAGE_SIZE) % 2 == 0) |
cp0_entry_lo0_write(lo.value); |
else |
cp0_entry_lo1_write(lo.value); |
241,11 → 234,9 |
tlb_invalid_fail(istate); |
} |
/** Process TLB Modified Exception |
/** Process TLB Modified Exception. |
* |
* Process TLB Modified Exception. |
* |
* @param istate Interrupted register context. |
* @param istate Interrupted register context. |
*/ |
void tlb_modified(istate_t *istate) |
{ |
262,7 → 253,7 |
* Locate the faulting entry in TLB. |
*/ |
hi.value = cp0_entry_hi_read(); |
prepare_entry_hi(&hi, hi.asid, badvaddr); |
tlb_prepare_entry_hi(&hi, hi.asid, badvaddr); |
cp0_entry_hi_write(hi.value); |
tlbp(); |
index.value = cp0_index_read(); |
296,12 → 287,6 |
} |
/* |
* Fail if the page is not writable. |
*/ |
if (!pte->w) |
goto fail; |
/* |
* Read the faulting TLB entry. |
*/ |
tlbr(); |
312,12 → 297,13 |
pte->a = 1; |
pte->d = 1; |
prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->cacheable, pte->pfn); |
tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->cacheable, |
pte->pfn); |
/* |
* The entry is to be updated in TLB. |
*/ |
if ((badvaddr/PAGE_SIZE) % 2 == 0) |
if ((badvaddr / PAGE_SIZE) % 2 == 0) |
cp0_entry_lo0_write(lo.value); |
else |
cp0_entry_lo1_write(lo.value); |
344,8 → 330,10 |
if (s) |
sym2 = s; |
fault_if_from_uspace(istate, "TLB Refill Exception on %p", cp0_badvaddr_read()); |
panic("%x: TLB Refill Exception at %x(%s<-%s)\n", cp0_badvaddr_read(), istate->epc, symbol, sym2); |
fault_if_from_uspace(istate, "TLB Refill Exception on %p", |
cp0_badvaddr_read()); |
panic("%x: TLB Refill Exception at %x(%s<-%s)\n", cp0_badvaddr_read(), |
istate->epc, symbol, sym2); |
} |
356,8 → 344,10 |
char *s = get_symtab_entry(istate->epc); |
if (s) |
symbol = s; |
fault_if_from_uspace(istate, "TLB Invalid Exception on %p", cp0_badvaddr_read()); |
panic("%x: TLB Invalid Exception at %x(%s)\n", cp0_badvaddr_read(), istate->epc, symbol); |
fault_if_from_uspace(istate, "TLB Invalid Exception on %p", |
cp0_badvaddr_read()); |
panic("%x: TLB Invalid Exception at %x(%s)\n", cp0_badvaddr_read(), |
istate->epc, symbol); |
} |
void tlb_modified_fail(istate_t *istate) |
367,23 → 357,27 |
char *s = get_symtab_entry(istate->epc); |
if (s) |
symbol = s; |
fault_if_from_uspace(istate, "TLB Modified Exception on %p", cp0_badvaddr_read()); |
panic("%x: TLB Modified Exception at %x(%s)\n", cp0_badvaddr_read(), istate->epc, symbol); |
fault_if_from_uspace(istate, "TLB Modified Exception on %p", |
cp0_badvaddr_read()); |
panic("%x: TLB Modified Exception at %x(%s)\n", cp0_badvaddr_read(), |
istate->epc, symbol); |
} |
/** Try to find PTE for faulting address |
/** Try to find PTE for faulting address. |
* |
* Try to find PTE for faulting address. |
* The AS->lock must be held on entry to this function. |
* |
* @param badvaddr Faulting virtual address. |
* @param access Access mode that caused the fault. |
* @param istate Pointer to interrupted state. |
* @param pfrc Pointer to variable where as_page_fault() return code will be stored. |
* @param badvaddr Faulting virtual address. |
* @param access Access mode that caused the fault. |
* @param istate Pointer to interrupted state. |
* @param pfrc Pointer to variable where as_page_fault() return code |
* will be stored. |
* |
* @return PTE on success, NULL otherwise. |
* @return PTE on success, NULL otherwise. |
*/ |
pte_t *find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, int *pfrc) |
pte_t * |
find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, |
int *pfrc) |
{ |
entry_hi_t hi; |
pte_t *pte; |
402,7 → 396,7 |
* Check if the mapping exists in page tables. |
*/ |
pte = page_mapping_find(AS, badvaddr); |
if (pte && pte->p) { |
if (pte && pte->p && (pte->w || access != PF_ACCESS_WRITE)) { |
/* |
* Mapping found in page tables. |
* Immediately succeed. |
425,6 → 419,7 |
page_table_lock(AS, true); |
pte = page_mapping_find(AS, badvaddr); |
ASSERT(pte && pte->p); |
ASSERT(pte->w || access != PF_ACCESS_WRITE); |
return pte; |
break; |
case AS_PF_DEFER: |
445,7 → 440,9 |
} |
} |
void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn) |
void |
tlb_prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, |
uintptr_t pfn) |
{ |
lo->value = 0; |
lo->g = g; |
455,7 → 452,7 |
lo->pfn = pfn; |
} |
void prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr) |
void tlb_prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr) |
{ |
hi->value = ALIGN_DOWN(addr, PAGE_SIZE * 2); |
hi->asid = asid; |
484,10 → 481,10 |
lo1.value = cp0_entry_lo1_read(); |
printf("%-2u %-4u %#6x %#4x %1u %1u %1u %1u %#6x\n", |
i, hi.asid, hi.vpn2, mask.mask, |
lo0.g, lo0.v, lo0.d, lo0.c, lo0.pfn); |
i, hi.asid, hi.vpn2, mask.mask, |
lo0.g, lo0.v, lo0.d, lo0.c, lo0.pfn); |
printf(" %1u %1u %1u %1u %#6x\n", |
lo1.g, lo1.v, lo1.d, lo1.c, lo1.pfn); |
lo1.g, lo1.v, lo1.d, lo1.c, lo1.pfn); |
} |
cp0_entry_hi_write(hi_save.value); |
564,11 → 561,12 |
cp0_entry_hi_write(hi_save.value); |
} |
/** Invalidate TLB entries for specified page range belonging to specified address space. |
/** Invalidate TLB entries for specified page range belonging to specified |
* address space. |
* |
* @param asid Address space identifier. |
* @param page First page whose TLB entry is to be invalidated. |
* @param cnt Number of entries to invalidate. |
* @param asid Address space identifier. |
* @param page First page whose TLB entry is to be invalidated. |
* @param cnt Number of entries to invalidate. |
*/ |
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt) |
{ |
585,7 → 583,7 |
for (i = 0; i < cnt + 1; i += 2) { |
hi.value = 0; |
prepare_entry_hi(&hi, asid, page + i * PAGE_SIZE); |
tlb_prepare_entry_hi(&hi, asid, page + i * PAGE_SIZE); |
cp0_entry_hi_write(hi.value); |
tlbp(); |
592,7 → 590,10 |
index.value = cp0_index_read(); |
if (!index.p) { |
/* Entry was found, index register contains valid index. */ |
/* |
* Entry was found, index register contains valid |
* index. |
*/ |
tlbr(); |
lo0.value = cp0_entry_lo0_read(); |
/branches/dynload/kernel/arch/mips32/src/mm/as.c |
---|
44,7 → 44,7 |
/** Architecture dependent address space init. */ |
void as_arch_init(void) |
{ |
as_operations = &as_pt_operations; |
as_operations = &as_pt_operations; |
asid_fifo_init(); |
} |
/branches/dynload/kernel/arch/mips32/src/mm/frame.c |
---|
32,27 → 32,238 |
/** @file |
*/ |
#include <macros.h> |
#include <arch/mm/frame.h> |
#include <arch/mm/tlb.h> |
#include <interrupt.h> |
#include <mm/frame.h> |
#include <mm/asid.h> |
#include <config.h> |
#include <arch/drivers/arc.h> |
#include <arch/drivers/msim.h> |
#include <arch/drivers/serial.h> |
#include <print.h> |
#define ZERO_PAGE_MASK TLB_PAGE_MASK_256K |
#define ZERO_FRAMES 2048 |
#define ZERO_PAGE_WIDTH 18 /* 256K */ |
#define ZERO_PAGE_SIZE (1 << ZERO_PAGE_WIDTH) |
#define ZERO_PAGE_ASID ASID_INVALID |
#define ZERO_PAGE_TLBI 0 |
#define ZERO_PAGE_ADDR 0 |
#define ZERO_PAGE_OFFSET (ZERO_PAGE_SIZE / sizeof(uint32_t) - 1) |
#define ZERO_PAGE_VALUE (((volatile uint32_t *) ZERO_PAGE_ADDR)[ZERO_PAGE_OFFSET]) |
#define ZERO_PAGE_VALUE_KSEG1(frame) (((volatile uint32_t *) (0xa0000000 + (frame << ZERO_PAGE_WIDTH)))[ZERO_PAGE_OFFSET]) |
#define MAX_REGIONS 32 |
typedef struct { |
pfn_t start; |
pfn_t count; |
} phys_region_t; |
static count_t phys_regions_count = 0; |
static phys_region_t phys_regions[MAX_REGIONS]; |
/** Check whether frame is available |
* |
* Returns true if given frame is generally available for use. |
* Returns false if given frame is used for physical memory |
* mapped devices and cannot be used. |
* |
*/ |
static bool frame_available(pfn_t frame) |
{ |
#if MACHINE == msim |
/* MSIM device (dprinter) */ |
if (frame == (KA2PA(MSIM_VIDEORAM) >> ZERO_PAGE_WIDTH)) |
return false; |
/* MSIM device (dkeyboard) */ |
if (frame == (KA2PA(MSIM_KBD_ADDRESS) >> ZERO_PAGE_WIDTH)) |
return false; |
#endif |
#if MACHINE == simics |
/* Simics device (serial line) */ |
if (frame == (KA2PA(SERIAL_ADDRESS) >> ZERO_PAGE_WIDTH)) |
return false; |
#endif |
#if (MACHINE == lgxemul) || (MACHINE == bgxemul) |
/* gxemul devices */ |
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE, |
0x10000000, MB2SIZE(256))) |
return false; |
#endif |
return true; |
} |
/** Check whether frame is safe to write |
* |
* Returns true if given frame is safe for read/write test. |
* Returns false if given frame should not be touched. |
* |
*/ |
static bool frame_safe(pfn_t frame) |
{ |
/* Kernel structures */ |
if ((frame << ZERO_PAGE_WIDTH) < KA2PA(config.base)) |
return false; |
/* Kernel */ |
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE, |
KA2PA(config.base), config.kernel_size)) |
return false; |
/* Kernel stack */ |
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE, |
KA2PA(config.stack_base), config.stack_size)) |
return false; |
/* Init tasks */ |
bool safe = true; |
count_t i; |
for (i = 0; i < init.cnt; i++) |
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE, |
KA2PA(init.tasks[i].addr), init.tasks[i].size)) { |
safe = false; |
break; |
} |
return safe; |
} |
static void frame_add_region(pfn_t start_frame, pfn_t end_frame) |
{ |
if (end_frame > start_frame) { |
/* Convert 1M frames to 16K frames */ |
pfn_t first = ADDR2PFN(start_frame << ZERO_PAGE_WIDTH); |
pfn_t count = ADDR2PFN((end_frame - start_frame) << ZERO_PAGE_WIDTH); |
/* Interrupt vector frame is blacklisted */ |
pfn_t conf_frame; |
if (first == 0) |
conf_frame = 1; |
else |
conf_frame = first; |
zone_create(first, count, conf_frame, 0); |
if (phys_regions_count < MAX_REGIONS) { |
phys_regions[phys_regions_count].start = first; |
phys_regions[phys_regions_count].count = count; |
phys_regions_count++; |
} |
} |
} |
/** Create memory zones |
* |
* If ARC is known, read information from ARC, otherwise |
* assume some defaults. |
* - blacklist first FRAME because there is an exception vector |
* Walk through available 256 KB chunks of physical |
* memory and create zones. |
* |
* Note: It is assumed that the TLB is not yet being |
* used in any way, thus there is no interference. |
* |
*/ |
void frame_arch_init(void) |
{ |
if (!arc_frame_init()) { |
zone_create(0, ADDR2PFN(CONFIG_MEMORY_SIZE), 1, 0); |
/* |
* Blacklist interrupt vector |
*/ |
frame_mark_unavailable(0, 1); |
ipl_t ipl = interrupts_disable(); |
/* Clear and initialize TLB */ |
cp0_pagemask_write(ZERO_PAGE_MASK); |
cp0_entry_lo0_write(0); |
cp0_entry_lo1_write(0); |
cp0_entry_hi_write(0); |
count_t i; |
for (i = 0; i < TLB_ENTRY_COUNT; i++) { |
cp0_index_write(i); |
tlbwi(); |
} |
pfn_t start_frame = 0; |
pfn_t frame; |
bool avail = true; |
/* Walk through all 1 MB frames */ |
for (frame = 0; frame < ZERO_FRAMES; frame++) { |
if (!frame_available(frame)) |
avail = false; |
else { |
if (frame_safe(frame)) { |
entry_lo_t lo0; |
entry_lo_t lo1; |
entry_hi_t hi; |
tlb_prepare_entry_lo(&lo0, false, true, true, false, frame << (ZERO_PAGE_WIDTH - 12)); |
tlb_prepare_entry_lo(&lo1, false, false, false, false, 0); |
tlb_prepare_entry_hi(&hi, ZERO_PAGE_ASID, ZERO_PAGE_ADDR); |
cp0_pagemask_write(ZERO_PAGE_MASK); |
cp0_entry_lo0_write(lo0.value); |
cp0_entry_lo1_write(lo1.value); |
cp0_entry_hi_write(hi.value); |
cp0_index_write(ZERO_PAGE_TLBI); |
tlbwi(); |
ZERO_PAGE_VALUE = 0; |
if (ZERO_PAGE_VALUE != 0) |
avail = false; |
else { |
ZERO_PAGE_VALUE = 0xdeadbeef; |
if (ZERO_PAGE_VALUE != 0xdeadbeef) |
avail = false; |
#if (MACHINE == lgxemul) || (MACHINE == bgxemul) |
else { |
ZERO_PAGE_VALUE_KSEG1(frame) = 0xaabbccdd; |
if (ZERO_PAGE_VALUE_KSEG1(frame) != 0xaabbccdd) |
avail = false; |
} |
#endif |
} |
} |
} |
if (!avail) { |
frame_add_region(start_frame, frame); |
start_frame = frame + 1; |
avail = true; |
} |
} |
frame_add_region(start_frame, frame); |
/* Blacklist interrupt vector frame */ |
frame_mark_unavailable(0, 1); |
/* Cleanup */ |
cp0_pagemask_write(ZERO_PAGE_MASK); |
cp0_entry_lo0_write(0); |
cp0_entry_lo1_write(0); |
cp0_entry_hi_write(0); |
cp0_index_write(ZERO_PAGE_TLBI); |
tlbwi(); |
interrupts_restore(ipl); |
} |
void physmem_print(void) |
{ |
printf("Base Size\n"); |
printf("---------- ----------\n"); |
count_t i; |
for (i = 0; i < phys_regions_count; i++) { |
printf("%#010x %10u\n", |
PFN2ADDR(phys_regions[i].start), PFN2ADDR(phys_regions[i].count)); |
} |
} |
/** @} |
*/ |
/branches/dynload/kernel/arch/mips32/src/interrupt.c |
---|
38,7 → 38,6 |
#include <arch.h> |
#include <arch/cp0.h> |
#include <time/clock.h> |
#include <arch/drivers/arc.h> |
#include <ipc/sysipc.h> |
#include <ddi/device.h> |
/branches/dynload/kernel/arch/mips32/src/drivers/arc.c |
---|
File deleted |
/branches/dynload/kernel/arch/mips32/src/drivers/msim.c |
---|
39,12 → 39,9 |
#include <arch/cp0.h> |
#include <console/console.h> |
#include <sysinfo/sysinfo.h> |
#include <ddi/ddi.h> |
/** Address of devices. */ |
#define MSIM_VIDEORAM 0xB0000000 |
#define MSIM_KBD_ADDRESS 0xB0000000 |
#define MSIM_KBD_IRQ 2 |
static parea_t msim_parea; |
static chardev_t console; |
static irq_t msim_irq; |
158,6 → 155,16 |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, MSIM_KBD_IRQ); |
sysinfo_set_item_val("kbd.address.virtual", NULL, MSIM_KBD_ADDRESS); |
msim_parea.pbase = KA2PA(MSIM_VIDEORAM); |
msim_parea.vbase = MSIM_VIDEORAM; |
msim_parea.frames = 1; |
msim_parea.cacheable = false; |
ddi_parea_register(&msim_parea); |
sysinfo_set_item_val("fb", NULL, true); |
sysinfo_set_item_val("fb.kind", NULL, 3); |
sysinfo_set_item_val("fb.address.physical", NULL, KA2PA(MSIM_VIDEORAM)); |
} |
/** @} |
/branches/dynload/kernel/arch/ia32/include/atomic.h |
---|
113,7 → 113,7 |
"xchgl %0, %1\n" |
"testl %1, %1\n" |
"jnz 0b\n" |
: "+m" (val->count), "=r"(tmp) |
: "+m" (val->count), "=&r"(tmp) |
); |
/* |
* Prevent critical section code from bleeding out this way up. |
/branches/dynload/kernel/arch/ia32/include/mm/page.h |
---|
40,8 → 40,6 |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_SIZE FRAME_SIZE |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#ifdef KERNEL |
#ifndef __ASM__ |
/branches/dynload/kernel/arch/ia32/Makefile.inc |
---|
29,11 → 29,15 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf32-i386 |
BFD_ARCH = i386 |
BFD = binary |
TARGET = i686-pc-linux-gnu |
TOOLCHAIN_DIR = /usr/local/i686 |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/i686 |
DEFS += -DMACHINE=$(MACHINE) -D__32_BITS__ |
74,7 → 78,7 |
CONFIG_HT = n |
endif |
ifeq ($(MACHINE),core) |
FPU_NO_CFLAGS = -mno-mmmx -mno-sse -mno-sse2 -mno-sse3 |
FPU_NO_CFLAGS = -mno-mmx -mno-sse -mno-sse2 -mno-sse3 |
CMN2 = -march=prescott |
GCC_CFLAGS += $(CMN2) |
ICC_CFLAGS += $(CMN2) |
/branches/dynload/kernel/arch/ia32/src/asm.S |
---|
71,7 → 71,7 |
* @param MEMCPY_SRC(%esp) Source address. |
* @param MEMCPY_SIZE(%esp) Size. |
* |
* @return MEMCPY_SRC(%esp) on success and 0 on failure. |
* @return MEMCPY_DST(%esp) on success and 0 on failure. |
*/ |
memcpy: |
memcpy_from_uspace: |
96,7 → 96,7 |
0: |
movl %edx, %edi |
movl %eax, %esi |
movl MEMCPY_SRC(%esp), %eax /* MEMCPY_SRC(%esp), success */ |
movl MEMCPY_DST(%esp), %eax /* MEMCPY_DST(%esp), success */ |
ret |
/* |
/branches/dynload/kernel/arch/ia32/src/mm/as.c |
---|
39,9 → 39,7 |
/** Architecture dependent address space init. */ |
void as_arch_init(void) |
{ |
#ifndef __OBJC__ |
as_operations = &as_pt_operations; |
#endif |
} |
/** @} |
/branches/dynload/kernel/arch/ia32/src/drivers/ega.c |
---|
93,12 → 93,6 |
sysinfo_set_item_val("fb.width", NULL, ROW); |
sysinfo_set_item_val("fb.height", NULL, ROWS); |
sysinfo_set_item_val("fb.address.physical", NULL, VIDEORAM); |
sysinfo_set_item_val("fb.address.color", NULL, PAGE_COLOR((uintptr_t) |
videoram)); |
#ifndef CONFIG_FB |
putchar('\n'); |
#endif |
} |
static void ega_display_char(char ch) |
/branches/dynload/tools/xstruct.py |
---|
0,0 → 1,110 |
# |
# Copyright (c) 2008 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
""" |
Convert descriptive structure definitions to structure object |
""" |
import struct |
class Struct: |
def size(self): |
return struct.calcsize(self._format_) |
def pack(self): |
args = [] |
for variable in self._args_: |
if (isinstance(self.__dict__[variable], list)): |
for item in self.__dict__[variable]: |
args.append(item) |
else: |
args.append(self.__dict__[variable]) |
return struct.pack(self._format_, *args) |
def create(definition): |
"Create structure object" |
tokens = definition.split(None) |
# Initial byte order tag |
format = { |
"little:": lambda: "<", |
"big:": lambda: ">", |
"network:": lambda: "!" |
}[tokens[0]]() |
inst = Struct() |
args = [] |
# Member tags |
comment = False |
variable = None |
for token in tokens[1:]: |
if (comment): |
if (token == "*/"): |
comment = False |
continue |
if (token == "/*"): |
comment = True |
continue |
if (variable != None): |
subtokens = token.split("[") |
if (len(subtokens) > 1): |
format += "%d" % int(subtokens[1].split("]")[0]) |
format += variable |
inst.__dict__[subtokens[0]] = None |
args.append(subtokens[0]) |
variable = None |
continue |
if (token[0:8] == "padding["): |
size = token[8:].split("]")[0] |
format += "%dx" % int(size) |
continue |
variable = { |
"char": lambda: "s", |
"uint8_t": lambda: "B", |
"uint16_t": lambda: "H", |
"uint32_t": lambda: "L", |
"uint64_t": lambda: "Q", |
"int8_t": lambda: "b", |
"int16_t": lambda: "h", |
"int32_t": lambda: "l", |
"int64_t": lambda: "q" |
}[token]() |
inst.__dict__['_format_'] = format |
inst.__dict__['_args_'] = args |
return inst |
/branches/dynload/tools/mktmpfs.py |
---|
32,84 → 32,105 |
import sys |
import os |
import struct |
import xstruct |
def align_up(size, alignment): |
"Align upwards to a given alignment" |
return (((size) + ((alignment) - 1)) & ~((alignment) - 1)) |
HEADER = """little: |
char tag[5] /* 'TMPFS' */ |
""" |
DENTRY_NONE = """little: |
uint8_t kind /* NONE */ |
uint32_t fname_len /* 0 */ |
""" |
DENTRY_FILE = """little: |
uint8_t kind /* FILE */ |
uint32_t fname_len /* filename length */ |
char fname[%d] /* filename */ |
uint32_t flen /* file length */ |
""" |
DENTRY_DIRECTORY = """little: |
uint8_t kind /* DIRECTORY */ |
uint32_t fname_len /* filename length */ |
char fname[%d] /* filename */ |
""" |
TMPFS_NONE = 0 |
TMPFS_FILE = 1 |
TMPFS_DIRECTORY = 2 |
def usage(prname): |
"Print usage syntax" |
print prname + " <ALIGNMENT> <PATH> <IMAGE>" |
print prname + " <PATH> <IMAGE>" |
def recursion(root, outf): |
"Recursive directory walk" |
payload_size = 0 |
for name in os.listdir(root): |
canon = os.path.join(root, name) |
if (os.path.isfile(canon)): |
outf.write(struct.pack("<BL" + ("%d" % len(name)) + "s", 1, len(name), name)) |
payload_size += 5 + len(name) |
size = os.path.getsize(canon) |
rd = 0; |
outf.write(struct.pack("<L", size)) |
payload_size += 4 |
dentry = xstruct.create(DENTRY_FILE % len(name)) |
dentry.kind = TMPFS_FILE |
dentry.fname_len = len(name) |
dentry.fname = name |
dentry.flen = size |
outf.write(dentry.pack()) |
inf = file(canon, "r") |
rd = 0; |
while (rd < size): |
data = inf.read(4096); |
outf.write(data) |
payload_size += len(data) |
rd += len(data) |
inf.close() |
if (os.path.isdir(canon)): |
outf.write(struct.pack("<BL" + ("%d" % len(name)) + "s", 2, len(name), name)) |
payload_size += 5 + len(name) |
payload_size += recursion(canon, outf) |
outf.write(struct.pack("<BL", 0, 0)) |
payload_size += 5 |
return payload_size |
dentry = xstruct.create(DENTRY_DIRECTORY % len(name)) |
dentry.kind = TMPFS_DIRECTORY |
dentry.fname_len = len(name) |
dentry.fname = name |
outf.write(dentry.pack()) |
recursion(canon, outf) |
dentry = xstruct.create(DENTRY_NONE) |
dentry.kind = TMPFS_NONE |
dentry.fname_len = 0 |
outf.write(dentry.pack()) |
def main(): |
if (len(sys.argv) < 4): |
if (len(sys.argv) < 3): |
usage(sys.argv[0]) |
return |
if (not sys.argv[1].isdigit()): |
print "<ALIGNMENT> must be a number" |
return |
align = int(sys.argv[1], 0) |
path = os.path.abspath(sys.argv[2]) |
path = os.path.abspath(sys.argv[1]) |
if (not os.path.isdir(path)): |
print "<PATH> must be a directory" |
return |
header_size = align_up(18, align) |
outf = file(sys.argv[3], "w") |
outf.write(struct.pack("<" + ("%d" % header_size) + "x")) |
outf = file(sys.argv[2], "w") |
outf.write(struct.pack("<5s", "TMPFS")) |
payload_size = 5 |
header = xstruct.create(HEADER) |
header.tag = "TMPFS" |
payload_size += recursion(path, outf) |
outf.write(struct.pack("<BL", 0, 0)) |
payload_size += 5 |
outf.write(header.pack()) |
aligned_size = align_up(payload_size, align) |
recursion(path, outf) |
if (aligned_size - payload_size > 0): |
outf.write(struct.pack("<" + ("%d" % (aligned_size - payload_size)) + "x")) |
outf.seek(0) |
outf.write(struct.pack("<4sBBLQ", "HORD", 1, 1, header_size, aligned_size)) |
dentry = xstruct.create(DENTRY_NONE) |
dentry.kind = TMPFS_NONE |
dentry.fname_len = 0 |
outf.write(dentry.pack()) |
outf.close() |
if __name__ == '__main__': |
main() |
/branches/dynload/tools/mkfat.py |
---|
0,0 → 1,109 |
#!/usr/bin/env python |
# |
# Copyright (c) 2008 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
""" |
FAT creator |
""" |
import sys |
import os |
import random |
import xstruct |
BOOT_SECTOR = """little: |
uint8_t jmp[3] /* jump instruction */ |
char oem[8] /* OEM string */ |
uint16_t sector /* bytes per sector */ |
uint8_t cluster /* sectors per cluster */ |
uint16_t reserved /* reserved sectors */ |
uint8_t fats /* number of FATs */ |
uint16_t rootdir /* root directory entries */ |
uint16_t sectors /* total number of sectors */ |
uint8_t descriptor /* media descriptor */ |
uint16_t fat_sectors /* sectors per single FAT */ |
uint16_t track_sectors /* sectors per track */ |
uint16_t heads /* number of heads */ |
uint32_t hidden /* hidden sectors */ |
uint32_t sectors_big /* total number of sectors (if sectors == 0) */ |
/* Extended BIOS Parameter Block */ |
uint8_t drive /* physical drive number */ |
padding[1] /* reserved (current head) */ |
uint8_t extboot_signature /* extended boot signature */ |
uint32_t serial /* serial number */ |
char label[11] /* volume label */ |
char fstype[8] /* filesystem type */ |
padding[448] /* boot code */ |
uint8_t boot_signature[2] /* boot signature */ |
""" |
def usage(prname): |
"Print usage syntax" |
print prname + " <PATH> <IMAGE>" |
def main(): |
if (len(sys.argv) < 3): |
usage(sys.argv[0]) |
return |
path = os.path.abspath(sys.argv[1]) |
if (not os.path.isdir(path)): |
print "<PATH> must be a directory" |
return |
outf = file(sys.argv[2], "w") |
boot_sector = xstruct.create(BOOT_SECTOR) |
boot_sector.jmp = [0xEB, 0x3C, 0x90] |
boot_sector.oem = "MSDOS5.0" |
boot_sector.sector = 512 |
boot_sector.cluster = 8 # 4096 bytes per cluster |
boot_sector.reserved = 1 |
boot_sector.fats = 2 |
boot_sector.rootdir = 224 # FIXME: root directory should be sector aligned |
boot_sector.sectors = 0 # FIXME |
boot_sector.descriptor = 0xF8 |
boot_sector.fat_sectors = 0 # FIXME |
boot_sector.track_sectors = 0 # FIXME |
boot_sector.heads = 0 # FIXME |
boot_sector.hidden = 0 |
boot_sector.sectors_big = 0 # FIXME |
boot_sector.drive = 0 |
boot_sector.extboot_signature = 0x29 |
boot_sector.serial = random.randint(0, 0xFFFFFFFF) |
boot_sector.label = "HELENOS" |
boot_sector.fstype = "FAT16 " |
boot_sector.boot_signature = [0x55, 0xAA] |
outf.write(boot_sector.pack()) |
outf.close() |
if __name__ == '__main__': |
main() |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/branches/dynload/tools/mkfat.sh |
---|
0,0 → 1,73 |
#!/bin/bash |
# |
# Copyright (c) 2008 Jakub Jermar |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
MFORMAT=`which mformat` |
MCOPY=`which mcopy` |
if [ `which mformat` == "" ]; then |
echo "Please install mtools." |
exit 1 |
fi |
if [ `which mcopy` == "" ]; then |
echo "Please install mtools." |
exit 1 |
fi |
if [ $# -ne 2 ]; then |
echo "Usage: $0 <PATH> <IMAGE>" |
exit 1 |
fi |
if [ ! -d $1 ]; then |
echo "Usage: $0 <PATH> <IMAGE>" |
exit 1 |
fi |
BPS=512 |
SPC=4 |
FAT16_MIN_SEC=$((4085 * $SPC)) |
HEADS=2 |
TRACKS=16 |
BYTES=`du -sb $1 | cut -f 1` |
SECTORS=$(($BYTES / $BPS)) |
SPTPH=$((($SECTORS + $FAT16_MIN_SEC) / ($HEADS * $TRACKS))) |
# Format the image as FAT16 |
$MFORMAT -h $HEADS -t $TRACKS -s $SPTPH -M $BPS -c $SPC -v "FAT16HORD" -B /dev/zero -C -i $2 :: |
if [ $? -ne 0 ]; then |
echo "$MFORMAT failed: $?" |
exit $? |
fi |
# Copy the subtree to the image |
$MCOPY -vspQmi $2 $1/* :: |
exit $? |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/branches/dynload/tools/mkhord.py |
---|
0,0 → 1,104 |
#!/usr/bin/env python |
# |
# Copyright (c) 2008 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
""" |
HORD encapsulator |
""" |
import sys |
import os |
import xstruct |
HEADER = """little: |
char tag[4] /* 'HORD' */ |
uint8_t version /* version */ |
uint8_t encoding /* encoding */ |
uint32_t header_size /* header size */ |
uint64_t payload_size /* payload size */ |
""" |
HORD_LSB = 1 |
def align_up(size, alignment): |
"Align upwards to a given alignment" |
return (((size) + ((alignment) - 1)) & ~((alignment) - 1)) |
def usage(prname): |
"Print usage syntax" |
print prname + " <ALIGNMENT> <FS_IMAGE> <HORD_IMAGE>" |
def main(): |
if (len(sys.argv) < 4): |
usage(sys.argv[0]) |
return |
if (not sys.argv[1].isdigit()): |
print "<ALIGNMENT> must be a number" |
return |
align = int(sys.argv[1], 0) |
if (align <= 0): |
print "<ALIGNMENT> must be positive" |
return |
fs_image = os.path.abspath(sys.argv[2]) |
if (not os.path.isfile(fs_image)): |
print "<FS_IMAGE> must be a file" |
return |
inf = file(fs_image, "rb") |
outf = file(sys.argv[3], "wb") |
header = xstruct.create(HEADER) |
header_size = header.size() |
payload_size = os.path.getsize(fs_image) |
header_size_aligned = align_up(header_size, align) |
payload_size_aligned = align_up(payload_size, align) |
header.tag = "HORD" |
header.version = 1 |
header.encoding = HORD_LSB |
header.header_size = header_size_aligned |
header.payload_size = payload_size_aligned |
outf.write(header.pack()) |
outf.write(xstruct.create("little: padding[%d]" % (header_size_aligned - header_size)).pack()) |
outf.write(inf.read()) |
padding = payload_size_aligned - payload_size |
if (padding > 0): |
outf.write(xstruct.create("little: padding[%d]" % padding).pack()) |
inf.close() |
outf.close() |
if __name__ == '__main__': |
main() |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/branches/dynload/uspace/app/cli/Makefile |
---|
File deleted |
/branches/dynload/uspace/app/cli/cli.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/parser.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/var.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/arith.y |
---|
File deleted |
/branches/dynload/uspace/app/ash/jobs.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/memalloc.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/setmode.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/options.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/output.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/parser.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/jobs.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/output.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/builtins.def |
---|
File deleted |
/branches/dynload/uspace/app/ash/mystring.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/histedit.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/tags |
---|
File deleted |
/branches/dynload/uspace/app/ash/tools/mknodes.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/tools/mkinit.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/tools/Makefile |
---|
File deleted |
/branches/dynload/uspace/app/ash/tools/mksyntax.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/tools/mksignames.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/show.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/mystring.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/show.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/myhistedit.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/nodetypes |
---|
File deleted |
/branches/dynload/uspace/app/ash/error.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/error.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/trap.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/machdep.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/hetio.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/trap.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/shell.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/hetio.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/expand.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/mail.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/expand.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/main.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/mail.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/eval.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/bltin/times.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/bltin/echo.1 |
---|
File deleted |
/branches/dynload/uspace/app/ash/bltin/bltin.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/bltin/echo.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/bltin/test.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/alias.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/main.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/nodes.c.pat |
---|
File deleted |
/branches/dynload/uspace/app/ash/eval.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/alias.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/mkbuiltins |
---|
File deleted |
/branches/dynload/uspace/app/ash/fake.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/init.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/fake.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/lex.yy.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/arith_lex.l |
---|
File deleted |
/branches/dynload/uspace/app/ash/sh.1 |
---|
File deleted |
/branches/dynload/uspace/app/ash/Makefile |
---|
File deleted |
/branches/dynload/uspace/app/ash/funcs/suspend |
---|
File deleted |
/branches/dynload/uspace/app/ash/funcs/dirs |
---|
File deleted |
/branches/dynload/uspace/app/ash/funcs/popd |
---|
File deleted |
/branches/dynload/uspace/app/ash/funcs/newgrp |
---|
File deleted |
/branches/dynload/uspace/app/ash/funcs/pushd |
---|
File deleted |
/branches/dynload/uspace/app/ash/funcs/cmv |
---|
File deleted |
/branches/dynload/uspace/app/ash/funcs/login |
---|
File deleted |
/branches/dynload/uspace/app/ash/funcs/kill |
---|
File deleted |
/branches/dynload/uspace/app/ash/input.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/input.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/redir.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/arith.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/TOUR |
---|
File deleted |
/branches/dynload/uspace/app/ash/redir.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/mktokens |
---|
File deleted |
/branches/dynload/uspace/app/ash/arith.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/miscbltin.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/exec.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/cd.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/var.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/miscbltin.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/memalloc.c |
---|
File deleted |
/branches/dynload/uspace/app/ash/exec.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/cd.h |
---|
File deleted |
/branches/dynload/uspace/app/ash/options.c |
---|
File deleted |
/branches/dynload/uspace/app/bdsh/scli.c |
---|
0,0 → 1,106 |
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com> |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions are met: |
* |
* Redistributions of source code must retain the above copyright notice, this |
* list of conditions and the following disclaimer. |
* |
* Redistributions in binary form must reproduce the above copyright notice, |
* this list of conditions and the following disclaimer in the documentation |
* and/or other materials provided with the distribution. |
* |
* Neither the name of the original program's authors nor the names of its |
* contributors may be used to endorse or promote products derived from this |
* software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <unistd.h> |
#include "config.h" |
#include "scli.h" |
#include "input.h" |
#include "util.h" |
#include "errors.h" |
#include "cmds/cmds.h" |
/* See scli.h */ |
static cliuser_t usr; |
/* Globals that are modified during start-up that modules/builtins |
* should be aware of. */ |
volatile unsigned int cli_quit = 0; |
volatile unsigned int cli_interactive = 1; |
volatile unsigned int cli_verbocity = 1; |
/* The official name of this program |
* (change to your liking in configure.ac and re-run autoconf) */ |
const char *progname = PACKAGE_NAME; |
/* These are not exposed, even to builtins */ |
static int cli_init(cliuser_t *usr); |
static void cli_finit(cliuser_t *usr); |
/* Constructor */ |
static int cli_init(cliuser_t *usr) |
{ |
usr->line = (char *) NULL; |
usr->name = "root"; |
usr->home = "/"; |
usr->cwd = (char *) NULL; |
usr->prompt = (char *) NULL; |
chdir(usr->home); |
usr->lasterr = 0; |
return (int) cli_set_prompt(usr); |
} |
/* Destructor */ |
static void cli_finit(cliuser_t *usr) |
{ |
if (NULL != usr->line) |
free(usr->line); |
if (NULL != usr->prompt) |
free(usr->prompt); |
if (NULL != usr->cwd) |
free(usr->cwd); |
} |
int main(int argc, char *argv[]) |
{ |
int ret = 0; |
if (cli_init(&usr)) |
exit(EXIT_FAILURE); |
printf("Welcome to %s - %s\nType `help' at any time for usage information.\n", |
progname, PACKAGE_STRING); |
while (!cli_quit) { |
get_input(&usr); |
if (NULL != usr.line) { |
ret = tok_input(&usr); |
cli_set_prompt(&usr); |
usr.lasterr = ret; |
} |
} |
goto finit; |
finit: |
cli_finit(&usr); |
return ret; |
} |
/branches/dynload/uspace/app/bdsh/scli.h |
---|
0,0 → 1,16 |
#ifndef SCLI_H |
#define SCLI_H |
#include "config.h" |
#include <stdint.h> |
typedef struct { |
char *name; |
char *home; |
char *line; |
char *cwd; |
char *prompt; |
int lasterr; |
} cliuser_t; |
#endif |
/branches/dynload/uspace/app/bdsh/cmds/builtins/cd/cd.c |
---|
0,0 → 1,106 |
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com> |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions are met: |
* |
* Redistributions of source code must retain the above copyright notice, this |
* list of conditions and the following disclaimer. |
* |
* Redistributions in binary form must reproduce the above copyright notice, |
* this list of conditions and the following disclaimer in the documentation |
* and/or other materials provided with the distribution. |
* |
* Neither the name of the original program's authors nor the names of its |
* contributors may be used to endorse or promote products derived from this |
* software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <string.h> |
#include <errno.h> |
#include "util.h" |
#include "errors.h" |
#include "entry.h" |
#include "cmds.h" |
#include "cd.h" |
static char * cmdname = "cd"; |
void * help_cmd_cd(unsigned int level) |
{ |
if (level == HELP_SHORT) { |
printf("`%s' changes the current working directory.\n", cmdname); |
} else { |
printf( |
" %s <directory>\n" |
" Change directory to <directory>, e.g `%s /sbin'\n", |
cmdname, cmdname); |
} |
return CMD_VOID; |
} |
/* This is a very rudamentary 'cd' command. It is not 'link smart' (yet) */ |
int * cmd_cd(char **argv, cliuser_t *usr) |
{ |
int argc, rc = 0; |
argc = cli_count_args(argv); |
/* We don't yet play nice with whitespace, a getopt implementation should |
* protect "quoted\ destination" as a single argument. Its not our job to |
* look for && || or redirection as the tokenizer should have done that |
* (currently, it does not) */ |
if (argc > 2) { |
cli_error(CL_EFAIL, "Too many arguments to `%s'", cmdname); |
return CMD_FAILURE; |
} |
if (argc < 2) { |
printf("%s - no directory specified. Try `help %s extended'\n", |
cmdname, cmdname); |
return CMD_FAILURE; |
} |
/* We have the correct # of arguments |
* TODO: handle tidle (~) expansion? */ |
rc = chdir(argv[1]); |
if (rc == 0) { |
cli_set_prompt(usr); |
return CMD_SUCCESS; |
} else { |
switch (rc) { |
case ENOMEM: |
cli_error(CL_EFAIL, "Destination path too long"); |
break; |
case ENOENT: |
cli_error(CL_ENOENT, "Invalid directory `%s'", argv[1]); |
break; |
default: |
cli_error(CL_EFAIL, "Unable to change to `%s'", argv[1]); |
break; |
} |
} |
return CMD_FAILURE; |
} |
/branches/dynload/uspace/app/bdsh/cmds/builtins/cd/cd_def.h |
---|
0,0 → 1,14 |
{ |
"cd", |
"Change the current working directory", |
&cmd_cd, |
&help_cmd_cd, |
-1 |
}, |
{ |
"chdir", |
NULL, |
&cmd_cd, |
&help_cmd_cd, |
-1 |
}, |
/branches/dynload/uspace/app/bdsh/cmds/builtins/cd/entry.h |
---|
0,0 → 1,12 |
#ifndef CD_ENTRY_H_ |
#define CD_ENTRY_H_ |
#include "scli.h" |
/* Entry points for the cd command */ |
extern void * help_cmd_cd(unsigned int); |
extern int * cmd_cd(char **, cliuser_t *); |
#endif |
/branches/dynload/uspace/app/bdsh/cmds/builtins/cd/cd.h |
---|
0,0 → 1,7 |
#ifndef CD_H |
#define CD_H |
/* Prototypes for the cd command (excluding entry points) */ |
#endif |
/branches/dynload/uspace/app/bdsh/cmds/builtins/builtins.h |
---|
0,0 → 1,13 |
#ifndef BUILTINS_H |
#define BUILTINS_H |
#include "config.h" |
#include "cd/entry.h" |
builtin_t builtins[] = { |
#include "cd/cd_def.h" |
{NULL, NULL, NULL, NULL} |
}; |
#endif |
/branches/dynload/uspace/app/bdsh/cmds/builtins/README |
---|
0,0 → 1,21 |
Commands that need to modify the running user structure defined in scli.h |
should reside here. They (will) have a slightly different prototype that |
allows passing the user structure to them for ease of modifications. |
Examples of what should be a built-in and not a module would be: |
cd (cliuser_t->cwd needs to be updated) |
In the future, more user preferences will be set via built-in commands, |
such as the formatting of the prompt string (HelenOS doesn't yet have |
an environment, much less PS*, even if it did we'd likely do it a little |
differently). |
.... etc. |
Anything that does _not_ need to use this structure should be included |
as a module, not a built in. If you want to include a new command, there |
is a 99% chance that you want it to be a module. |
/branches/dynload/uspace/app/bdsh/cmds/builtins/builtin_aliases.h |
---|
0,0 → 1,11 |
#ifndef BUILTIN_ALIASES_H |
#define BUILTIN_ALIASES_H |
/* See modules/module_aliases.h for an explanation of this file */ |
char *builtin_aliases[] = { |
"chdir", "cd", |
NULL, NULL |
}; |
#endif |
/branches/dynload/uspace/app/bdsh/cmds/modules/touch/touch.c |
---|
0,0 → 1,107 |
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com> |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions are met: |
* |
* Redistributions of source code must retain the above copyright notice, this |
* list of conditions and the following disclaimer. |
* |
* Redistributions in binary form must reproduce the above copyright notice, |
* this list of conditions and the following disclaimer in the documentation |
* and/or other materials provided with the distribution. |
* |
* Neither the name of the original program's authors nor the names of its |
* contributors may be used to endorse or promote products derived from this |
* software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
/* TODO: Options that people would expect, such as not creating the file if |
* it doesn't exist, specifying the access time, etc */ |
#include <stdio.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <fcntl.h> |
#include <dirent.h> |
#include <sys/types.h> |
#include "config.h" |
#include "errors.h" |
#include "util.h" |
#include "entry.h" |
#include "touch.h" |
#include "cmds.h" |
static char *cmdname = "touch"; |
/* Dispays help for touch in various levels */ |
void * help_cmd_touch(unsigned int level) |
{ |
if (level == HELP_SHORT) { |
printf("`%s' updates access times for files\n", cmdname); |
} else { |
help_cmd_touch(HELP_SHORT); |
printf(" `%s' <file>, if the file does not exist it will be " |
"created\n", cmdname); |
} |
return CMD_VOID; |
} |
/* Main entry point for touch, accepts an array of arguments */ |
int * cmd_touch(char **argv) |
{ |
unsigned int argc, i = 0, ret = 0; |
int fd; |
char *buff = NULL; |
DIR *dirp; |
argc = cli_count_args(argv); |
if (argc == 1) { |
printf("%s - incorrect number of arguments. Try `help %s extended'\n", |
cmdname, cmdname); |
return CMD_FAILURE; |
} |
for (i = 1; i < argc; i ++) { |
buff = cli_strdup(argv[i]); |
dirp = opendir(buff); |
if (dirp) { |
cli_error(CL_ENOTSUP, "%s is a directory", buff); |
closedir(dirp); |
ret ++; |
continue; |
} |
fd = open(buff, O_RDWR | O_CREAT); |
if (fd < 0) { |
cli_error(CL_EFAIL, "Could not update / create %s ", buff); |
ret ++; |
continue; |
} else |
close(fd); |
free(buff); |
} |
if (ret) |
return CMD_FAILURE; |
else |
return CMD_SUCCESS; |
} |
/branches/dynload/uspace/app/bdsh/cmds/modules/touch/touch_def.h |
---|
0,0 → 1,8 |
{ |
"touch", |
"Create files or update access times", |
&cmd_touch, |
&help_cmd_touch, |
0 |
}, |
/branches/dynload/uspace/app/bdsh/cmds/modules/touch/entry.h |
---|
0,0 → 1,9 |
#ifndef TOUCH_ENTRY_H |
#define TOUCH_ENTRY_H |
/* Entry points for the touch command */ |
extern int * cmd_touch(char **); |
extern void * help_cmd_touch(unsigned int); |
#endif /* TOUCH_ENTRY_H */ |
/branches/dynload/uspace/app/bdsh/cmds/modules/touch/touch.h |
---|
0,0 → 1,8 |
#ifndef TOUCH_H |
#define TOUCH_H |
/* Prototypes for the touch command, excluding entry points */ |
#endif /* TOUCH_H */ |
/branches/dynload/uspace/app/bdsh/cmds/modules/mkdir/mkdir.c |
---|
0,0 → 1,251 |
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com> |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions are met: |
* |
* Redistributions of source code must retain the above copyright notice, this |
* list of conditions and the following disclaimer. |
* |
* Redistributions in binary form must reproduce the above copyright notice, |
* this list of conditions and the following disclaimer in the documentation |
* and/or other materials provided with the distribution. |
* |
* Neither the name of the original program's authors nor the names of its |
* contributors may be used to endorse or promote products derived from this |
* software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <dirent.h> |
#include <fcntl.h> |
#include <sys/types.h> |
#include <sys/stat.h> |
#include <getopt.h> |
#include <stdarg.h> |
#include "config.h" |
#include "errors.h" |
#include "util.h" |
#include "entry.h" |
#include "mkdir.h" |
#include "cmds.h" |
#define MKDIR_VERSION "0.0.1" |
static char *cmdname = "mkdir"; |
static struct option const long_options[] = { |
{"parents", no_argument, 0, 'p'}, |
{"verbose", no_argument, 0, 'v'}, |
{"mode", required_argument, 0, 'm'}, |
{"help", no_argument, 0, 'h'}, |
{"version", no_argument, 0, 'V'}, |
{"follow", no_argument, 0, 'f'}, |
{0, 0, 0, 0} |
}; |
void * help_cmd_mkdir(unsigned int level) |
{ |
if (level == HELP_SHORT) { |
printf("`%s' creates a new directory\n", cmdname); |
} else { |
help_cmd_mkdir(HELP_SHORT); |
printf( |
"Usage: %s [options] <path>\n" |
"Options:\n" |
" -h, --help A short option summary\n" |
" -V, --version Print version information and exit\n" |
" -p, --parents Create needed parents for <path>\n" |
" -m, --mode Set permissions to [mode] (UNUSED)\n" |
" -v, --verbose Be extremely noisy about what is happening\n" |
" -f, --follow Go to the new directory once created\n" |
"Currently, %s is under development, some options don't work.\n", |
cmdname, cmdname); |
} |
return CMD_VOID; |
} |
/* This is kind of clunky, but effective for now */ |
static unsigned int |
create_directory(const char *path, unsigned int p) |
{ |
DIR *dirp; |
char *tmp = NULL, *buff = NULL, *wdp = NULL; |
char *dirs[255]; |
unsigned int absolute = 0, i = 0, ret = 0; |
/* Its a good idea to allocate path, plus we (may) need a copy of |
* path to tokenize if parents are specified */ |
if (NULL == (tmp = cli_strdup(path))) { |
cli_error(CL_ENOMEM, "%s: path too big?", cmdname); |
return 1; |
} |
if (NULL == (wdp = (char *) malloc(PATH_MAX))) { |
cli_error(CL_ENOMEM, "%s: could not alloc cwd", cmdname); |
free(tmp); |
return 1; |
} |
/* The only reason for wdp is to be (optionally) verbose */ |
getcwd(wdp, PATH_MAX); |
/* Typical use without specifying the creation of parents */ |
if (p == 0) { |
dirp = opendir(tmp); |
if (dirp) { |
cli_error(CL_EEXISTS, "%s: can not create %s, try -p", cmdname, path); |
closedir(dirp); |
goto finit; |
} |
if (-1 == (mkdir(tmp, 0))) { |
cli_error(CL_EFAIL, "%s: could not create %s", cmdname, path); |
goto finit; |
} |
} |
/* Parents need to be created, path has to be broken up */ |
/* See if path[0] is a slash, if so we have to remember to append it */ |
if (tmp[0] == '/') |
absolute = 1; |
/* TODO: Canonify the path prior to tokenizing it, see below */ |
dirs[i] = cli_strtok(tmp, "/"); |
while (dirs[i] && i < 255) |
dirs[++i] = cli_strtok(NULL, "/"); |
if (NULL == dirs[0]) |
return 1; |
if (absolute == 1) { |
asprintf(&buff, "/%s", dirs[0]); |
mkdir(buff, 0); |
chdir(buff); |
free(buff); |
getcwd(wdp, PATH_MAX); |
i = 1; |
} else { |
i = 0; |
} |
while (dirs[i] != NULL) { |
/* Sometimes make or scripts conjoin odd paths. Account for something |
* like this: ../../foo/bar/../foo/foofoo/./bar */ |
if (!strcmp(dirs[i], "..") || !strcmp(dirs[i], ".")) { |
if (0 != (chdir(dirs[i]))) { |
cli_error(CL_EFAIL, "%s: impossible path: %s", |
cmdname, path); |
ret ++; |
goto finit; |
} |
getcwd(wdp, PATH_MAX); |
} else { |
if (-1 == (mkdir(dirs[i], 0))) { |
cli_error(CL_EFAIL, |
"%s: failed at %s/%s", wdp, dirs[i]); |
ret ++; |
goto finit; |
} |
if (0 != (chdir(dirs[i]))) { |
cli_error(CL_EFAIL, "%s: failed creating %s\n", |
cmdname, dirs[i]); |
ret ++; |
break; |
} |
} |
i++; |
} |
goto finit; |
finit: |
free(wdp); |
free(tmp); |
return ret; |
} |
int * cmd_mkdir(char **argv) |
{ |
unsigned int argc, create_parents = 0, i, ret = 0, follow = 0; |
unsigned int verbose = 0; |
int c, opt_ind; |
char *cwd; |
argc = cli_count_args(argv); |
for (c = 0, optind = 0, opt_ind = 0; c != -1;) { |
c = getopt_long(argc, argv, "pvhVfm:", long_options, &opt_ind); |
switch (c) { |
case 'p': |
create_parents = 1; |
break; |
case 'v': |
verbose = 1; |
break; |
case 'h': |
help_cmd_mkdir(HELP_LONG); |
return CMD_SUCCESS; |
case 'V': |
printf("%s\n", MKDIR_VERSION); |
return CMD_SUCCESS; |
case 'f': |
follow = 1; |
break; |
case 'm': |
printf("%s: [W] Ignoring mode %s\n", cmdname, optarg); |
break; |
} |
} |
argc -= optind; |
if (argc < 1) { |
printf("%s - incorrect number of arguments. Try `%s --help'\n", |
cmdname, cmdname); |
return CMD_FAILURE; |
} |
if (NULL == (cwd = (char *) malloc(PATH_MAX))) { |
cli_error(CL_ENOMEM, "%s: could not allocate cwd", cmdname); |
return CMD_FAILURE; |
} |
memset(cwd, 0, sizeof(cwd)); |
getcwd(cwd, PATH_MAX); |
for (i = optind; argv[i] != NULL; i++) { |
if (verbose == 1) |
printf("%s: creating %s%s\n", |
cmdname, argv[i], |
create_parents ? " (and all parents)" : ""); |
ret += create_directory(argv[i], create_parents); |
} |
if (follow == 0) |
chdir(cwd); |
free(cwd); |
if (ret) |
return CMD_FAILURE; |
else |
return CMD_SUCCESS; |
} |
/branches/dynload/uspace/app/bdsh/cmds/modules/mkdir/mkdir_def.h |
---|
0,0 → 1,16 |
{ |
"mkdir", |
"Create new directories", |
&cmd_mkdir, |
&help_cmd_mkdir, |
0 |
}, |
{ |
"md", |
NULL, |
&cmd_mkdir, |
&help_cmd_mkdir, |
0 |
}, |
/branches/dynload/uspace/app/bdsh/cmds/modules/mkdir/mkdir.h |
---|
0,0 → 1,8 |
#ifndef MKDIR_H |
#define MKDIR_H |
/* Prototypes for the mkdir command, excluding entry points */ |
static unsigned int create_directory(const char *, unsigned int); |
#endif /* MKDIR_H */ |
/branches/dynload/uspace/app/bdsh/cmds/modules/mkdir/entry.h |
---|
0,0 → 1,9 |
#ifndef MKDIR_ENTRY_H |
#define MKDIR_ENTRY_H |
/* Entry points for the mkdir command */ |
extern int * cmd_mkdir(char **); |
extern void * help_cmd_mkdir(unsigned int); |
#endif /* MKDIR_ENTRY_H */ |
/branches/dynload/uspace/app/bdsh/cmds/modules/cat/cat.c |
---|
0,0 → 1,186 |
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com> |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions are met: |
* |
* Redistributions of source code must retain the above copyright notice, this |
* list of conditions and the following disclaimer. |
* |
* Redistributions in binary form must reproduce the above copyright notice, |
* this list of conditions and the following disclaimer in the documentation |
* and/or other materials provided with the distribution. |
* |
* Neither the name of the original program's authors nor the names of its |
* contributors may be used to endorse or promote products derived from this |
* software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <getopt.h> |
#include <string.h> |
#include <fcntl.h> |
#include "config.h" |
#include "util.h" |
#include "errors.h" |
#include "entry.h" |
#include "cat.h" |
#include "cmds.h" |
static char *cmdname = "cat"; |
#define CAT_VERSION "0.0.1" |
#define CAT_DEFAULT_BUFLEN 1024 |
static char *cat_oops = "That option is not yet supported\n"; |
static struct option const long_options[] = { |
{ "help", no_argument, 0, 'h' }, |
{ "version", no_argument, 0, 'v' }, |
{ "head", required_argument, 0, 'H' }, |
{ "tail", required_argument, 0, 't' }, |
{ "buffer", required_argument, 0, 'b' }, |
{ "more", no_argument, 0, 'm' }, |
{ 0, 0, 0, 0 } |
}; |
/* Dispays help for cat in various levels */ |
void * help_cmd_cat(unsigned int level) |
{ |
if (level == HELP_SHORT) { |
printf("`%s' shows the contents of files\n", cmdname); |
} else { |
help_cmd_cat(HELP_SHORT); |
printf( |
"Usage: %s [options] <file1> [file2] [...]\n" |
"Options:\n" |
" -h, --help A short option summary\n" |
" -v, --version Print version information and exit\n" |
" -H, --head ## Print only the first ## bytes\n" |
" -t, --tail ## Print only the last ## bytes\n" |
" -b, --buffer ## Set the read buffer size to ##\n" |
" -m, --more Pause after each screen full\n" |
"Currently, %s is under development, some options don't work.\n", |
cmdname, cmdname); |
} |
return CMD_VOID; |
} |
static unsigned int cat_file(const char *fname, size_t blen) |
{ |
int fd, bytes = 0, count = 0, reads = 0; |
off_t total = 0; |
char *buff = NULL; |
if (-1 == (fd = open(fname, O_RDONLY))) { |
printf("Unable to open %s\n", fname); |
return 1; |
} |
total = lseek(fd, 0, SEEK_END); |
lseek(fd, 0, SEEK_SET); |
if (NULL == (buff = (char *) malloc(blen + 1))) { |
close(fd); |
printf("Unable to allocate enough memory to read %s\n", |
fname); |
return 1; |
} |
do { |
memset(buff, 0, sizeof(buff)); |
bytes = read(fd, buff, blen); |
if (bytes > 0) { |
count += bytes; |
if (bytes < blen) |
buff[bytes] = '\0'; |
printf(buff); |
reads++; |
} |
} while (bytes > 0); |
close(fd); |
if (bytes == -1) { |
printf("Error reading %s\n", fname); |
free(buff); |
return 1; |
} |
/* Debug stuff, newline not added purposefully */ |
printf("** %s is a file with the size of %ld bytes\n", |
fname, total); |
printf( "** %d bytes were read in a buffer of %d bytes in %d reads\n", |
count, blen, reads); |
printf("** Read %s\n", count == total ? "Succeeded" : "Failed"); |
free(buff); |
return 0; |
} |
/* Main entry point for cat, accepts an array of arguments */ |
int * cmd_cat(char **argv) |
{ |
unsigned int argc, i, ret = 0, buffer = 0; |
int c, opt_ind; |
argc = cli_count_args(argv); |
for (c = 0, optind = 0, opt_ind = 0; c != -1;) { |
c = getopt_long(argc, argv, "hvmH:t:b:", long_options, &opt_ind); |
switch (c) { |
case 'h': |
help_cmd_cat(HELP_LONG); |
return CMD_SUCCESS; |
case 'v': |
printf("%s\n", CAT_VERSION); |
return CMD_SUCCESS; |
case 'H': |
printf(cat_oops); |
return CMD_FAILURE; |
case 't': |
printf(cat_oops); |
return CMD_FAILURE; |
case 'b': |
printf(cat_oops); |
break; |
case 'm': |
printf(cat_oops); |
return CMD_FAILURE; |
} |
} |
argc -= optind; |
if (argc < 1) { |
printf("%s - incorrect number of arguments. Try `%s --help'\n", |
cmdname, cmdname); |
return CMD_FAILURE; |
} |
if (buffer <= 0) |
buffer = CAT_DEFAULT_BUFLEN; |
for (i = optind; argv[i] != NULL; i++) |
ret += cat_file(argv[i], buffer); |
if (ret) |
return CMD_FAILURE; |
else |
return CMD_SUCCESS; |
} |
/branches/dynload/uspace/app/bdsh/cmds/modules/cat/cat_def.h |
---|
0,0 → 1,8 |
{ |
"cat", |
"Show the contents of a file", |
&cmd_cat, |
&help_cmd_cat, |
0 |
}, |
/branches/dynload/uspace/app/bdsh/cmds/modules/cat/cat.h |
---|
0,0 → 1,9 |
#ifndef CAT_H |
#define CAT_H |
/* Prototypes for the cat command, excluding entry points */ |
static unsigned int cat_file(const char *, size_t); |
#endif /* CAT_H */ |
/branches/dynload/uspace/app/bdsh/cmds/modules/cat/entry.h |
---|
0,0 → 1,9 |
#ifndef CAT_ENTRY_H |
#define CAT_ENTRY_H |
/* Entry points for the cat command */ |
extern int * cmd_cat(char **); |
extern void * help_cmd_cat(unsigned int); |
#endif /* CAT_ENTRY_H */ |
/branches/dynload/uspace/app/bdsh/cmds/modules/help/help.c |
---|
0,0 → 1,162 |
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com> |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions are met: |
* |
* Redistributions of source code must retain the above copyright notice, this |
* list of conditions and the following disclaimer. |
* |
* Redistributions in binary form must reproduce the above copyright notice, |
* this list of conditions and the following disclaimer in the documentation |
* and/or other materials provided with the distribution. |
* |
* Neither the name of the original program's authors nor the names of its |
* contributors may be used to endorse or promote products derived from this |
* software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include "config.h" |
#include "entry.h" |
#include "help.h" |
#include "cmds.h" |
#include "modules.h" |
#include "builtins.h" |
#include "errors.h" |
#include "util.h" |
static char *cmdname = "help"; |
extern const char *progname; |
#define HELP_IS_MODULE 1 |
#define HELP_IS_BUILTIN 0 |
#define HELP_IS_RUBBISH -1 |
volatile int mod_switch = -1; |
/* Just use a pointer here, no need for mod_switch */ |
static int is_mod_or_builtin(char *cmd) |
{ |
int rc = HELP_IS_RUBBISH; |
rc = is_builtin(cmd); |
if (rc > -1) { |
mod_switch = rc; |
return HELP_IS_BUILTIN; |
} |
rc = is_module(cmd); |
if (rc > -1) { |
mod_switch = rc; |
return HELP_IS_MODULE; |
} |
return HELP_IS_RUBBISH; |
} |
void *help_cmd_help(unsigned int level) |
{ |
if (level == HELP_SHORT) { |
printf( |
"\n %s [command] <extended>\n" |
" Use help [command] extended for detailed help on [command] " |
", even `help'\n\n", cmdname); |
} else { |
printf( |
"\n `%s' - shows help for commands\n" |
" Examples:\n" |
" %s [command] Show help for [command]\n" |
" %s [command] extended Show extended help for [command]\n" |
"\n If no argument is given to %s, a list of commands are shown\n\n", |
cmdname, cmdname, cmdname, cmdname); |
} |
return CMD_VOID; |
} |
int *cmd_help(char *argv[]) |
{ |
module_t *mod; |
builtin_t *cmd; |
unsigned int i = 0; |
int rc = 0; |
int argc; |
int level = HELP_SHORT; |
argc = cli_count_args(argv); |
if (argc > 3) { |
printf("\nToo many arguments to `%s', try:\n", cmdname); |
help_cmd_help(HELP_SHORT); |
return CMD_FAILURE; |
} |
if (argc == 3) { |
if (!strcmp("extended", argv[2])) |
level = HELP_LONG; |
else |
level = HELP_SHORT; |
} |
if (argc > 1) { |
rc = is_mod_or_builtin(argv[1]); |
switch (rc) { |
case HELP_IS_RUBBISH: |
printf("Invalid command %s\n", argv[1]); |
return CMD_FAILURE; |
case HELP_IS_MODULE: |
help_module(mod_switch, level); |
return CMD_SUCCESS; |
case HELP_IS_BUILTIN: |
help_builtin(mod_switch, level); |
return CMD_SUCCESS; |
} |
} |
printf("\n Available commands are:\n"); |
printf(" ------------------------------------------------------------\n"); |
/* First, show a list of built in commands that are available in this mode */ |
for (cmd = builtins; cmd->name != NULL; cmd++, i++) { |
if (!builtin_is_restricted(i)) { |
if (is_builtin_alias(cmd->name)) |
printf(" %-16s\tAlias for `%s'\n", cmd->name, |
alias_for_builtin(cmd->name)); |
else |
printf(" %-16s\t%s\n", cmd->name, cmd->desc); |
} |
} |
i = 0; |
/* Now, show a list of module commands that are available in this mode */ |
for (mod = modules; mod->name != NULL; mod++, i++) { |
if (!module_is_restricted(i)) { |
if (is_module_alias(mod->name)) |
printf(" %-16s\tAlias for `%s'\n", mod->name, |
alias_for_module(mod->name)); |
else |
printf(" %-16s\t%s\n", mod->name, mod->desc); |
} |
} |
printf("\n Try %s %s for more information on how `%s' works.\n\n", |
cmdname, cmdname, cmdname); |
return CMD_SUCCESS; |
} |
/branches/dynload/uspace/app/bdsh/cmds/modules/help/help_def.h |
---|
0,0 → 1,7 |
{ |
"help", |
"Show help for commands", |
&cmd_help, |
&help_cmd_help, |
0 |
}, |
/branches/dynload/uspace/app/bdsh/cmds/modules/help/help.h |
---|
0,0 → 1,7 |
#ifndef HELP_H |
#define HELP_H |
/* Prototypes for the help command (excluding entry points) */ |
static int is_mod_or_builtin(char *); |
#endif |
/branches/dynload/uspace/app/bdsh/cmds/modules/help/entry.h |
---|
0,0 → 1,8 |
#ifndef HELP_ENTRY_H_ |
#define HELP_ENTRY_H_ |
/* Entry points for the help command */ |
extern void * help_cmd_help(unsigned int); |
extern int * cmd_help(char *[]); |
#endif |
/branches/dynload/uspace/app/bdsh/cmds/modules/ls/ls.c |
---|
0,0 → 1,196 |
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com> |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions are met: |
* |
* Redistributions of source code must retain the above copyright notice, this |
* list of conditions and the following disclaimer. |
* |
* Redistributions in binary form must reproduce the above copyright notice, |
* this list of conditions and the following disclaimer in the documentation |
* and/or other materials provided with the distribution. |
* |
* Neither the name of the original program's authors nor the names of its |
* contributors may be used to endorse or promote products derived from this |
* software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
/* NOTE: |
* This is a bit of an ugly hack, working around the absence of fstat / etc. |
* As more stuff is completed and exposed in libc, this will improve */ |
#include <stdio.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <dirent.h> |
#include <fcntl.h> |
#include <sys/types.h> |
#include <sys/stat.h> |
#include <string.h> |
#include "errors.h" |
#include "config.h" |
#include "util.h" |
#include "entry.h" |
#include "ls.h" |
#include "cmds.h" |
static char *cmdname = "ls"; |
static unsigned int ls_scope(const char *path) |
{ |
int fd; |
DIR *dirp; |
dirp = opendir(path); |
if (dirp) { |
closedir(dirp); |
return LS_DIR; |
} |
fd = open(path, O_RDONLY); |
if (fd > 0) { |
close(fd); |
return LS_FILE; |
} |
return LS_BOGUS; |
} |
static void ls_scan_dir(const char *d, DIR *dirp) |
{ |
struct dirent *dp; |
unsigned int scope; |
char *buff; |
if (! dirp) |
return; |
buff = (char *)malloc(PATH_MAX); |
if (NULL == buff) { |
cli_error(CL_ENOMEM, "ls: failed to scan %s", d); |
return; |
} |
while ((dp = readdir(dirp))) { |
memset(buff, 0, sizeof(buff)); |
/* Don't worry if inserting a double slash, this will be fixed by |
* absolutize() later with subsequent calls to open() or readdir() */ |
snprintf(buff, PATH_MAX - 1, "%s/%s", d, dp->d_name); |
scope = ls_scope(buff); |
switch (scope) { |
case LS_DIR: |
ls_print_dir(dp->d_name); |
break; |
case LS_FILE: |
ls_print_file(dp->d_name); |
break; |
case LS_BOGUS: |
/* Odd chance it was deleted from the time readdir() found |
* it and the time that it was scoped */ |
printf("ls: skipping bogus node %s\n", dp->d_name); |
break; |
} |
} |
free(buff); |
return; |
} |
/* ls_print_* currently does nothing more than print the entry. |
* in the future, we will likely pass the absolute path, and |
* some sort of ls_options structure that controls how each |
* entry is printed and what is printed about it. |
* |
* Now we just print basic DOS style lists */ |
static void ls_print_dir(const char *d) |
{ |
printf("%-40s\t<DIR>\n", d); |
return; |
} |
static void ls_print_file(const char *f) |
{ |
printf("%-40s\n", f); |
return; |
} |
void * help_cmd_ls(unsigned int level) |
{ |
if (level == HELP_SHORT) { |
printf("`%s' lists files and directories.\n", cmdname); |
} else { |
help_cmd_ls(HELP_SHORT); |
printf(" `%s' [path], if no path is given the current " |
"working directory is used.\n", cmdname); |
} |
return CMD_VOID; |
} |
int * cmd_ls(char **argv) |
{ |
unsigned int argc; |
unsigned int scope; |
char *buff; |
DIR *dirp; |
argc = cli_count_args(argv); |
buff = (char *) malloc(PATH_MAX); |
if (NULL == buff) { |
cli_error(CL_ENOMEM, "%s: ", cmdname); |
return CMD_FAILURE; |
} |
memset(buff, 0, sizeof(buff)); |
if (argc == 1) |
getcwd(buff, PATH_MAX); |
else |
strncpy(buff, argv[1], PATH_MAX); |
scope = ls_scope(buff); |
switch (scope) { |
case LS_BOGUS: |
cli_error(CL_ENOENT, buff); |
free(buff); |
return CMD_FAILURE; |
case LS_FILE: |
ls_print_file(buff); |
break; |
case LS_DIR: |
dirp = opendir(buff); |
if (! dirp) { |
/* May have been deleted between scoping it and opening it */ |
cli_error(CL_EFAIL, "Could not stat %s", buff); |
free(buff); |
return CMD_FAILURE; |
} |
ls_scan_dir(buff, dirp); |
closedir(dirp); |
break; |
} |
free(buff); |
return CMD_SUCCESS; |
} |
/branches/dynload/uspace/app/bdsh/cmds/modules/ls/ls_def.h |
---|
0,0 → 1,16 |
{ |
"ls", |
"List files and directories", |
&cmd_ls, |
&help_cmd_ls, |
0 |
}, |
{ |
"dir", |
NULL, |
&cmd_ls, |
&help_cmd_ls, |
0 |
}, |
/branches/dynload/uspace/app/bdsh/cmds/modules/ls/ls.h |
---|
0,0 → 1,16 |
#ifndef LS_H |
#define LS_H |
/* Various values that can be returned by ls_scope() */ |
#define LS_BOGUS 0 |
#define LS_FILE 1 |
#define LS_DIR 2 |
static unsigned int ls_scope(const char *); |
static void ls_scan_dir(const char *, DIR *); |
static void ls_print_dir(const char *); |
static void ls_print_file(const char *); |
#endif /* LS_H */ |
/branches/dynload/uspace/app/bdsh/cmds/modules/ls/entry.h |
---|
0,0 → 1,9 |
#ifndef LS_ENTRY_H |
#define LS_ENTRY_H |
/* Entry points for the ls command */ |
extern int * cmd_ls(char **); |
extern void * help_cmd_ls(unsigned int); |
#endif /* LS_ENTRY_H */ |
/branches/dynload/uspace/app/bdsh/cmds/modules/rm/rm.c |
---|
0,0 → 1,254 |
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com> |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions are met: |
* |
* Redistributions of source code must retain the above copyright notice, this |
* list of conditions and the following disclaimer. |
* |
* Redistributions in binary form must reproduce the above copyright notice, |
* this list of conditions and the following disclaimer in the documentation |
* and/or other materials provided with the distribution. |
* |
* Neither the name of the original program's authors nor the names of its |
* contributors may be used to endorse or promote products derived from this |
* software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <fcntl.h> |
#include <dirent.h> |
#include <assert.h> |
#include <getopt.h> |
#include "config.h" |
#include "errors.h" |
#include "util.h" |
#include "entry.h" |
#include "rm.h" |
#include "cmds.h" |
static char *cmdname = "rm"; |
#define RM_VERSION "0.0.1" |
static rm_job_t rm; |
static struct option const long_options[] = { |
{ "help", no_argument, 0, 'h' }, |
{ "version", no_argument, 0, 'v' }, |
{ "recursive", no_argument, 0, 'r' }, |
{ "force", no_argument, 0, 'f' }, |
{ "safe", no_argument, 0, 's' }, |
{ 0, 0, 0, 0 } |
}; |
static unsigned int rm_start(rm_job_t *rm) |
{ |
rm->recursive = 0; |
rm->force = 0; |
rm->safe = 0; |
/* Make sure we can allocate enough memory to store |
* what is needed in the job structure */ |
if (NULL == (rm->nwd = (char *) malloc(PATH_MAX))) |
return 0; |
memset(rm->nwd, 0, sizeof(rm->nwd)); |
if (NULL == (rm->owd = (char *) malloc(PATH_MAX))) |
return 0; |
memset(rm->owd, 0, sizeof(rm->owd)); |
if (NULL == (rm->cwd = (char *) malloc(PATH_MAX))) |
return 0; |
memset(rm->cwd, 0, sizeof(rm->cwd)); |
chdir("."); |
if (NULL == (getcwd(rm->owd, PATH_MAX))) |
return 0; |
return 1; |
} |
static void rm_end(rm_job_t *rm) |
{ |
if (NULL != rm->nwd) |
free(rm->nwd); |
if (NULL != rm->owd) |
free(rm->owd); |
if (NULL != rm->cwd) |
free(rm->cwd); |
return; |
} |
static unsigned int rm_recursive(const char *path) |
{ |
int rc; |
/* First see if it will just go away */ |
rc = rmdir(path); |
if (rc == 0) |
return 0; |
/* Its not empty, recursively scan it */ |
cli_error(CL_ENOTSUP, |
"Can not remove %s, directory not empty", path); |
return 1; |
} |
static unsigned int rm_single(const char *path) |
{ |
if (unlink(path)) { |
cli_error(CL_EFAIL, "rm: could not remove file %s", path); |
return 1; |
} |
return 0; |
} |
static unsigned int rm_scope(const char *path) |
{ |
int fd; |
DIR *dirp; |
dirp = opendir(path); |
if (dirp) { |
closedir(dirp); |
return RM_DIR; |
} |
fd = open(path, O_RDONLY); |
if (fd > 0) { |
close(fd); |
return RM_FILE; |
} |
return RM_BOGUS; |
} |
/* Dispays help for rm in various levels */ |
void * help_cmd_rm(unsigned int level) |
{ |
if (level == HELP_SHORT) { |
printf("`%s' removes files and directories.\n", cmdname); |
} else { |
help_cmd_rm(HELP_SHORT); |
printf( |
"Usage: %s [options] <path>\n" |
"Options:\n" |
" -h, --help A short option summary\n" |
" -v, --version Print version information and exit\n" |
" -r, --recursive Recursively remove sub directories\n" |
" -f, --force Do not prompt prior to removing files\n" |
" -s, --safe Stop if directories change during removal\n\n" |
"Currently, %s is under development, some options don't work.\n", |
cmdname, cmdname); |
} |
return CMD_VOID; |
} |
/* Main entry point for rm, accepts an array of arguments */ |
int * cmd_rm(char **argv) |
{ |
unsigned int argc; |
unsigned int i, scope, ret = 0; |
int c, opt_ind; |
size_t len; |
char *buff = NULL; |
argc = cli_count_args(argv); |
if (argc < 2) { |
cli_error(CL_EFAIL, |
"%s: insufficient arguments. Try %s --help", cmdname, cmdname); |
return CMD_FAILURE; |
} |
if (!rm_start(&rm)) { |
cli_error(CL_ENOMEM, "%s: could not initialize", cmdname); |
rm_end(&rm); |
return CMD_FAILURE; |
} |
for (c = 0, optind = 0, opt_ind = 0; c != -1;) { |
c = getopt_long(argc, argv, "hvrfs", long_options, &opt_ind); |
switch (c) { |
case 'h': |
help_cmd_rm(HELP_LONG); |
return CMD_SUCCESS; |
case 'v': |
printf("%s\n", RM_VERSION); |
return CMD_SUCCESS; |
case 'r': |
rm.recursive = 1; |
break; |
case 'f': |
rm.force = 1; |
break; |
case 's': |
rm.safe = 1; |
break; |
} |
} |
if (optind == argc) { |
cli_error(CL_EFAIL, |
"%s: insufficient arguments. Try %s --help", cmdname, cmdname); |
rm_end(&rm); |
return CMD_FAILURE; |
} |
i = optind; |
while (NULL != argv[i]) { |
len = strlen(argv[i]) + 2; |
buff = (char *) realloc(buff, len); |
assert(buff != NULL); |
memset(buff, 0, sizeof(buff)); |
snprintf(buff, len, argv[i]); |
scope = rm_scope(buff); |
switch (scope) { |
case RM_BOGUS: /* FIXME */ |
case RM_FILE: |
ret += rm_single(buff); |
break; |
case RM_DIR: |
if (! rm.recursive) { |
printf("%s is a directory, use -r to remove it.\n", buff); |
ret ++; |
} else { |
ret += rm_recursive(buff); |
} |
break; |
} |
i++; |
} |
if (NULL != buff) |
free(buff); |
rm_end(&rm); |
if (ret) |
return CMD_FAILURE; |
else |
return CMD_SUCCESS; |
} |
/branches/dynload/uspace/app/bdsh/cmds/modules/rm/rm_def.h |
---|
0,0 → 1,16 |
{ |
"rm", |
"Remove files and directories", |
&cmd_rm, |
&help_cmd_rm, |
0 |
}, |
{ |
"del", |
NULL, |
&cmd_rm, |
&help_cmd_rm, |
0 |
}, |
/branches/dynload/uspace/app/bdsh/cmds/modules/rm/rm.h |
---|
0,0 → 1,43 |
#ifndef RM_H |
#define RM_H |
/* Return values for rm_scope() */ |
#define RM_BOGUS 0 |
#define RM_FILE 1 |
#define RM_DIR 2 |
/* Flags for rm_update() */ |
#define _RM_ENTRY 0 |
#define _RM_ADVANCE 1 |
#define _RM_REWIND 2 |
#define _RM_EXIT 3 |
/* A simple job structure */ |
typedef struct { |
/* Options set at run time */ |
unsigned int force; /* -f option */ |
unsigned int recursive; /* -r option */ |
unsigned int safe; /* -s option */ |
/* Keeps track of the job in progress */ |
int advance; /* How far deep we've gone since entering */ |
DIR *entry; /* Entry point to the tree being removed */ |
char *owd; /* Where we were when we invoked rm */ |
char *cwd; /* Current directory being transversed */ |
char *nwd; /* Next directory to be transversed */ |
/* Counters */ |
int f_removed; /* Number of files unlinked */ |
int d_removed; /* Number of directories unlinked */ |
} rm_job_t; |
/* Prototypes for the rm command, excluding entry points */ |
static unsigned int rm_start(rm_job_t *); |
static void rm_end(rm_job_t *rm); |
static unsigned int rm_recursive(const char *); |
static unsigned int rm_single(const char *); |
static unsigned int rm_scope(const char *); |
#endif /* RM_H */ |
/branches/dynload/uspace/app/bdsh/cmds/modules/rm/entry.h |
---|
0,0 → 1,9 |
#ifndef RM_ENTRY_H |
#define RM_ENTRY_H |
/* Entry points for the rm command */ |
extern int * cmd_rm(char **); |
extern void * help_cmd_rm(unsigned int); |
#endif /* RM_ENTRY_H */ |
/branches/dynload/uspace/app/bdsh/cmds/modules/quit/quit_def.h |
---|
0,0 → 1,14 |
{ |
"quit", |
"Exit the console", |
&cmd_quit, |
&help_cmd_quit, |
-1 |
}, |
{ |
"exit", |
NULL, |
&cmd_quit, |
&help_cmd_quit, |
-1 |
}, |
/branches/dynload/uspace/app/bdsh/cmds/modules/quit/quit.c |
---|
0,0 → 1,55 |
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com> |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions are met: |
* |
* Redistributions of source code must retain the above copyright notice, this |
* list of conditions and the following disclaimer. |
* |
* Redistributions in binary form must reproduce the above copyright notice, |
* this list of conditions and the following disclaimer in the documentation |
* and/or other materials provided with the distribution. |
* |
* Neither the name of the original program's authors nor the names of its |
* contributors may be used to endorse or promote products derived from this |
* software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include "entry.h" |
#include "quit.h" |
#include "cmds.h" |
static char *cmdname = "quit"; |
extern volatile unsigned int cli_quit; |
extern const char *progname; |
void * help_cmd_quit(unsigned int level) |
{ |
printf("Type `%s' to exit %s\n", cmdname, progname); |
return CMD_VOID; |
} |
/* Quits the program and returns the status of whatever command |
* came before invoking 'quit' */ |
int * cmd_quit(char *argv[]) |
{ |
/* Inform that we're outta here */ |
cli_quit = 1; |
return CMD_SUCCESS; |
} |
/branches/dynload/uspace/app/bdsh/cmds/modules/quit/entry.h |
---|
0,0 → 1,10 |
#ifndef QUIT_ENTRY_H_ |
#define QUIT_ENTRY_H_ |
/* Entry points for the quit command */ |
extern void * help_cmd_quit(unsigned int); |
extern int * cmd_quit(char *[]); |
#endif |
/branches/dynload/uspace/app/bdsh/cmds/modules/quit/quit.h |
---|
0,0 → 1,6 |
#ifndef QUIT_H |
#define QUIT_H |
/* Prototypes for the quit command (excluding entry points) */ |
#endif |
/branches/dynload/uspace/app/bdsh/cmds/modules/pwd/pwd_def.h |
---|
0,0 → 1,7 |
{ |
"pwd", |
"Prints the current working directory", |
&cmd_pwd, |
&help_cmd_pwd, |
-1 |
}, |
/branches/dynload/uspace/app/bdsh/cmds/modules/pwd/pwd.h |
---|
0,0 → 1,6 |
#ifndef PWD_H_ |
#define PWD_H_ |
/* Prototypes for the pwd command (excluding entry points) */ |
#endif |
/branches/dynload/uspace/app/bdsh/cmds/modules/pwd/entry.h |
---|
0,0 → 1,12 |
#ifndef PWD_ENTRY_H |
#define PWD_ENTRY_H |
#include "scli.h" |
/* Entry points for the pwd command */ |
extern void * help_cmd_pwd(unsigned int); |
extern int * cmd_pwd(char **); |
#endif |
/branches/dynload/uspace/app/bdsh/cmds/modules/pwd/pwd.c |
---|
0,0 → 1,71 |
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com> |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions are met: |
* |
* Redistributions of source code must retain the above copyright notice, this |
* list of conditions and the following disclaimer. |
* |
* Redistributions in binary form must reproduce the above copyright notice, |
* this list of conditions and the following disclaimer in the documentation |
* and/or other materials provided with the distribution. |
* |
* Neither the name of the original program's authors nor the names of its |
* contributors may be used to endorse or promote products derived from this |
* software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include "config.h" |
#include "errors.h" |
#include "entry.h" |
#include "cmds.h" |
#include "pwd.h" |
static char * cmdname = "pwd"; |
void * help_cmd_pwd(unsigned int level) |
{ |
printf("`%s' prints your current working directory.\n", cmdname); |
return CMD_VOID; |
} |
int * cmd_pwd(char *argv[]) |
{ |
char *buff; |
buff = (char *) malloc(PATH_MAX); |
if (NULL == buff) { |
cli_error(CL_ENOMEM, "%s:", cmdname); |
return CMD_FAILURE; |
} |
memset(buff, 0, sizeof(buff)); |
getcwd(buff, PATH_MAX); |
if (! buff) { |
cli_error(CL_EFAIL, |
"Unable to determine the current working directory"); |
free(buff); |
return CMD_FAILURE; |
} else { |
printf("%s\n", buff); |
free(buff); |
return CMD_SUCCESS; |
} |
} |
/branches/dynload/uspace/app/bdsh/cmds/modules/modules.h |
---|
0,0 → 1,45 |
#ifndef MODULES_H |
#define MODULES_H |
/* Each built in function has two files, one being an entry.h file which |
* prototypes the run/help entry functions, the other being a .def file |
* which fills the modules[] array according to the cmd_t structure |
* defined in cmds.h. |
* |
* To add or remove a module, just make a new directory in cmds/modules |
* for it and copy the 'show' example for basics, then include it here. |
* (or reverse the process to remove one) |
* |
* NOTE: See module_ aliases.h as well, this is where aliases (commands that |
* share an entry point with others) are indexed */ |
#include "config.h" |
/* Prototypes for each module's entry (help/exec) points */ |
#include "help/entry.h" |
#include "quit/entry.h" |
#include "mkdir/entry.h" |
#include "rm/entry.h" |
#include "cat/entry.h" |
#include "touch/entry.h" |
#include "ls/entry.h" |
#include "pwd/entry.h" |
/* Each .def function fills the module_t struct with the individual name, entry |
* point, help entry point, etc. You can use config.h to control what modules |
* are loaded based on what libraries exist on the system. */ |
module_t modules[] = { |
#include "help/help_def.h" |
#include "quit/quit_def.h" |
#include "mkdir/mkdir_def.h" |
#include "rm/rm_def.h" |
#include "cat/cat_def.h" |
#include "touch/touch_def.h" |
#include "ls/ls_def.h" |
#include "pwd/pwd_def.h" |
{NULL, NULL, NULL, NULL} |
}; |
#endif |
/branches/dynload/uspace/app/bdsh/cmds/modules/README |
---|
0,0 → 1,15 |
Modules are commands or full programs (anything can be made into a module |
that can return int type) should go here. Note, modules do not (can not) |
update or read cliuser_t. |
Stuff that needs to write to the user structures contained in scli.h should |
be made as built-in commands, not modules, but there are very few times when |
you would want to do that. |
See the README file in the bdsh root directory for a quick overview of how to |
write a new command, or convert an existig stand-alone program into a module |
for BDSH. |
/branches/dynload/uspace/app/bdsh/cmds/modules/module_aliases.h |
---|
0,0 → 1,22 |
#ifndef MODULE_ALIASES_H |
#define MODULE_ALIASES_H |
/* Modules that declare multiple names for themselves but use the |
* same entry functions are aliases. This array helps to determine if |
* a module is an alias, as such it can be invoked differently. |
* format is alias , real_name */ |
/* So far, this is only used in the help display but could be used to |
* handle a module differently even prior to reaching its entry code. |
* For instance, 'exit' could behave differently than 'quit', prior to |
* the entry point being reached. */ |
char *mod_aliases[] = { |
"exit", "quit", |
"md", "mkdir", |
"del", "rm", |
"dir", "ls", |
NULL, NULL |
}; |
#endif |
/branches/dynload/uspace/app/bdsh/cmds/mknewcmd |
---|
0,0 → 1,347 |
#!/bin/sh |
# Copyright (C) 2008 Tim Post - All Rights Reserved |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions are met: |
# |
# Redistributions of source code must retain the above copyright notice, this |
# list of conditions and the following disclaimer. |
# |
# Redistributions in binary form must reproduce the above copyright notice, |
# this list of conditions and the following disclaimer in the documentation |
# and/or other materials provided with the distribution. |
# |
# Neither the name of the original program's authors nor the names of its |
# contributors may be used to endorse or promote products derived from this |
# software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
# POSSIBILITY OF SUCH DAMAGE. |
# Script to generate skeletal files for a new command |
# Uses `getopt', not quite a bash-ism but might be |
# lacking on some legacy systems. |
# If your shell does not support eval, shift (x) or |
# here-now documents, sorry :) |
usage() |
{ |
def="$DEFAULT_COMMAND" |
cat << EOF |
\`$PROGNAME' generates skeletal command files to simplify adding commands |
Usage: $PROGNAME [options] <location> |
Options: |
-n, --name Name of the command (default: ${def}) |
-d, --desc Short (20 30 chars) description of the command |
(def: "The $def command") |
-e, --entry Entry function of the command (def: cmd_${def}) |
-h, --help-entry Entry function for command help (def: help_cmd_${def}) |
-a, --alias Alias (nickname) for this command (def: none) |
-r, --restrict Restriction level (interactive, non-interactive, both) |
(def: module is both, builtin is interactive only) |
-t, --type Type of command (module or builtin) (def: module) |
-H, --help This help summary |
-V, --version Print $PROGNAME version and exit normally |
Notes: |
You must supply at least the name of the command. |
If you do not specify a location (i.e. modules/foo), the command will be |
created in modules/command_name or builtins/command_name depending on your |
selection. |
This script will only create skeletal files and inform you what headers |
need to be modified to incorporate the command. You will also have to |
manually update the main Makefile. |
This script is intended only to be a convenience for developers. Example use: |
$PROGNAME -n foo -d "Foo power" -a bar -r both -t module modules/foo |
The example would generate a modular command named 'foo', which is also |
reached by typing 'bar' and available in either interactive or noninteractive |
mode. |
Skeletal files do *not* depend on the autoconf generated "config.h" unless you |
include it. This may or may not be desirable depending on your use. |
Report bugs to $PROGMAINT |
EOF |
} |
# Convert a string to all uppercase |
toupper() |
{ |
local str="$1" |
echo "${str}" | tr 'a-z' 'A-Z' |
} |
# Template stored `here-now' style, this generates all files needed |
# for a new command according to arguments passed. |
generate_code() |
{ |
echo "Creating ${OUTDIR}/${CMDNAME}_def.h ..." |
cat << EOF > ${OUTDIR}/${CMDNAME}_def.h |
{ |
"${CMDNAME}", |
"${CMDDESC}", |
&${CMDENTRY}, |
&${HELPENTRY}, |
${CMDRESTRICT} |
}, |
EOF |
[ -n "${CMDALIAS}" ] && cat << EOF >> ${OUTDIR}/${CMDNAME}_def.h |
{ |
"${CMDALIAS}", |
NULL, |
&${CMDENTRY}, |
&${HELPENTRY}, |
${CMDRESTRICT} |
}, |
EOF |
local defname=$(toupper "${CMDNAME}") |
echo "Creating ${OUTDIR}/entry.h ..." |
cat << EOF > ${OUTDIR}/entry.h |
#ifndef ${defname}_ENTRY_H |
#define ${defname}_ENTRY_H |
EOF |
[ "${CMDTYPE}" = "module" ] && cat << EOF >> ${OUTDIR}/entry.h |
/* Entry points for the ${CMDNAME} command */ |
extern int * ${CMDENTRY}(char **); |
extern void * ${HELPENTRY}(unsigned int); |
#endif /* ${defname}_ENTRY_H */ |
EOF |
[ "${CMDTYPE}" = "builtin" ] && cat << EOF >> ${OUTDIR}/entry.h |
/* Pick up cliuser_t */ |
#include "scli.h" |
/* Entry points for the ${CMDNAME} command */ |
extern int * ${CMDENTRY}(char **, cliuser_t *); |
extern void * ${HELPENTRY}(unsigned int); |
#endif /* ${defname}_ENTRY_H */ |
EOF |
echo "Creating ${OUTDIR}/${CMDNAME}.h ..." |
cat << EOF > ${OUTDIR}/${CMDNAME}.h |
#ifndef ${defname}_H |
#define ${defname}_H |
/* Prototypes for the ${CMDNAME} command, excluding entry points */ |
#endif /* ${defname}_H */ |
EOF |
echo "Creating ${OUTDIR}/${CMDNAME}.c ..." |
cat << EOF > ${OUTDIR}/${CMDNAME}.c |
/* Automatically generated by ${PROGNAME} on ${TIMESTAMP} |
* This is machine generated output. The author of ${PROGNAME} claims no |
* copyright over the contents of this file. Where legally permitted, the |
* contents herein are donated to the public domain. |
* |
* You should apply any license and copyright that you wish to this file, |
* replacing this header in its entirety. */ |
#include <stdio.h> |
#include <stdlib.h> |
#include "config.h" |
#include "util.h" |
#include "errors.h" |
#include "entry.h" |
#include "${CMDNAME}.h" |
#include "cmds.h" |
static char *cmdname = "${CMDNAME}"; |
/* Dispays help for ${CMDNAME} in various levels */ |
void * ${HELPENTRY}(unsigned int level) |
{ |
printf("This is the %s help for '%s'.\n", |
level ? EXT_HELP : SHORT_HELP, cmdname); |
return CMD_VOID; |
} |
EOF |
[ "${CMDTYPE}" = "module" ] && cat << EOF >> ${OUTDIR}/${CMDNAME}.c |
/* Main entry point for ${CMDNAME}, accepts an array of arguments */ |
int * ${CMDENTRY}(char **argv) |
EOF |
[ "${CMDTYPE}" = "builtin" ] && cat << EOF >> ${OUTDIR}/${CMDNAME}.c |
/* Main entry point for ${CMDNAME}, accepts an array of arguments and a |
* pointer to the cliuser_t structure */ |
int * ${CMDENTRY}(char **argv, cliuser_t *usr) |
EOF |
cat << EOF >> ${OUTDIR}/${CMDNAME}.c |
{ |
unsigned int argc; |
unsigned int i; |
/* Count the arguments */ |
for (argc = 0; argv[argc] != NULL; argc ++); |
printf("%s %s\n", TEST_ANNOUNCE, cmdname); |
printf("%d arguments passed to %s", argc - 1, cmdname); |
if (argc < 2) { |
printf("\n"); |
return CMD_SUCCESS; |
} |
printf(":\n"); |
for (i = 1; i < argc; i++) |
printf("[%d] -> %s\n", i, argv[i]); |
return CMD_SUCCESS; |
} |
EOF |
printf "Done.\n\nYou should now modify %ss/%ss.h and ../Makefile" \ |
"${CMDTYPE}" "${CMDTYPE}" |
printf " to include your new command.\n" |
[ -n "$CMDALIAS" ] && { |
printf "\nYou should also modify %ss/%s_aliases.h and " \ |
"${CMDTYPE}" "${CMDTYPE}" |
printf "add %s as an alias for %s\n" \ |
"${CMDALIAS}" "${CMDNAME}" |
} |
printf "\nOnce completed, re-run make\n\n" |
} |
# Main program |
TIMESTAMP="$(date)" |
PROGNAME=$(basename $0) |
PROGVER="0.0.1" |
PROGMAINT="Tim Post <echo@echoreply.us>" |
DEFAULT_COMMAND="cmdname" |
# We need at least one |
[ $# = 0 ] && usage && exit 1; |
TEMP=$(getopt -o n:d:e:h:a:r:t:HV \ |
--long name:,desc:,entry:,help-entry:,alias:,restrict:,type:,help,version \ |
-- "$@") || { |
echo "Try $PROGNAME --help for help" |
} |
eval set -- "$TEMP" |
while true; do |
case "$1" in |
-n | --name) |
CMDNAME="$2" |
shift 2 |
continue |
;; |
-d | --desc) |
CMDDESC="$2" |
shift 2 |
continue |
;; |
-e | --entry) |
CMDENTRY="$2" |
shift 2 |
continue |
;; |
-h | --help-entry) |
HELPENTRY="$2" |
shift 2 |
continue |
;; |
-a | --alias) |
CMDALIAS="$2" |
shift 2 |
continue |
;; |
-r | --restrict) |
CMDRESTRICT="$2" |
shift 2 |
continue |
;; |
-t | --type) |
CMDTYPE="$2" |
shift 2 |
continue |
;; |
-H | --help) |
usage |
exit 0 |
;; |
-V | --version) |
echo "$PROGVER" |
exit 0 |
;; |
--) |
break |
;; |
esac |
done |
# Pick up a location if one was specified |
eval set -- "$*" |
[ -n "$2" ] && OUTDIR="$2" |
# Fill in defaults for whatever was not specified |
[ -n "$CMDNAME" ] || CMDNAME="$DEFAULT_COMMAND" |
[ -n "$CMDDESC" ] || CMDDESC="The $CMDNAME command" |
[ -n "$CMDENTRY" ] || CMDENTRY="cmd_${CMDNAME}" |
[ -n "$HELPENTRY" ] || HELPENTRY="help_cmd_${CMDNAME}" |
[ -n "$CMDTYPE" ] || CMDTYPE="module" |
[ -n "$OUTDIR" ] || OUTDIR="${CMDTYPE}s/${CMDNAME}" |
# Builtins typically only need to be available in interactive mode, |
# set the default accordingly. |
[ -n "$CMDRESTRICT" ] || { |
[ "$CMDTYPE" = "module" ] && CMDRESTRICT="both" |
[ "$CMDTYPE" = "builtin" ] && CMDRESTRICT="interactive" |
} |
# Set the restriction level as the structure expects to see it |
case "$CMDRESTRICT" in |
0 | both) |
CMDRESTRICT="0" |
;; |
1 | non-interactive) |
CMDRESTRICT="1" |
;; |
-1 | interactive) |
CMDRESTRICT="-1" |
;; |
*) |
usage |
exit 1 |
;; |
esac |
# Do a little sanity |
[ -d $OUTDIR ] && { |
echo "$OUTDIR already exists, remove it to proceed." |
exit 1 |
} |
mkdir -p ${OUTDIR} >/dev/null 2>&1 || { |
echo "Could not create ${OUTDIR}, aborting!" |
exit 1 |
} |
# Generate the files and inform on how to include them based on options |
generate_code |
exit 0 |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/branches/dynload/uspace/app/bdsh/cmds/mod_cmds.c |
---|
0,0 → 1,156 |
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com> |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions are met: |
* |
* Redistributions of source code must retain the above copyright notice, this |
* list of conditions and the following disclaimer. |
* |
* Redistributions in binary form must reproduce the above copyright notice, |
* this list of conditions and the following disclaimer in the documentation |
* and/or other materials provided with the distribution. |
* |
* Neither the name of the original program's authors nor the names of its |
* contributors may be used to endorse or promote products derived from this |
* software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
/* NOTES: |
* module_* functions are pretty much identical to builtin_* functions at this |
* point. On the surface, it would appear that making each function dual purpose |
* would be economical. |
* |
* These are kept separate because the structures (module_t and builtin_t) may |
* grow apart and become rather different, even though they're identical at this |
* point. |
* |
* To keep things easy to hack, everything is separated. In reality this only adds |
* 6 - 8 extra functions, but keeps each function very easy to read and modify. */ |
/* TODO: |
* Many of these could be unsigned, provided the modules and builtins themselves |
* can follow suit. Long term goal. */ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include "errors.h" |
#include "cmds.h" |
#include "module_aliases.h" |
extern volatile unsigned int cli_interactive; |
int module_is_restricted(int pos) |
{ |
/* Restriction Levels: |
* -1 -> Available only in interactive mode |
* 0 -> Available in any mode |
* 1 -> Available only in non-interactive mode */ |
module_t *mod = modules; |
mod += pos; |
/* We're interactive, and the module is OK to run */ |
if (cli_interactive && mod->restricted <= 0) |
return 0; |
/* We're not interactive, and the module is OK to run */ |
if (!cli_interactive && mod->restricted >= 0) |
return 0; |
/* Anything else is just a big fat no :) */ |
return 1; |
} |
/* Checks if an entry function matching command exists in modules[], if so |
* its position in the array is returned */ |
int is_module(const char *command) |
{ |
module_t *mod; |
unsigned int i = 0; |
if (NULL == command) |
return -2; |
for (mod = modules; mod->name != NULL; mod++, i++) { |
if (!strcmp(mod->name, command)) |
return i; |
} |
return -1; |
} |
/* Checks if a module is an alias (sharing an entry point with another |
* module). Returns 1 if so */ |
int is_module_alias(const char *command) |
{ |
unsigned int i = 0; |
if (NULL == command) |
return -1; |
for(i=0; mod_aliases[i] != NULL; i+=2) { |
if (!strcmp(mod_aliases[i], command)) |
return 1; |
} |
return 0; |
} |
/* Returns the name of the module that an alias points to */ |
char *alias_for_module(const char *command) |
{ |
unsigned int i = 0; |
if (NULL == command) |
return (char *)NULL; |
for(i=0; mod_aliases[i] != NULL; i++) { |
if (!strcmp(mod_aliases[i], command)) |
return (char *)mod_aliases[++i]; |
i++; |
} |
return (char *)NULL; |
} |
/* Invokes the 'help' entry function for the module at position (int) module, |
* which wants an unsigned int to determine brief or extended display. */ |
int help_module(int module, unsigned int extended) |
{ |
module_t *mod = modules; |
mod += module; |
if (NULL != mod->help) { |
mod->help(extended); |
return CL_EOK; |
} else |
return CL_ENOENT; |
} |
/* Invokes the module entry point modules[module], passing argv[] as an argument |
* stack. */ |
int run_module(int module, char *argv[]) |
{ |
module_t *mod = modules; |
mod += module; |
if (NULL != mod->entry) |
return ((int)mod->entry(argv)); |
return CL_ENOENT; |
} |
/branches/dynload/uspace/app/bdsh/cmds/cmds.h |
---|
0,0 → 1,73 |
#ifndef CMDS_H |
#define CMDS_H |
#include "config.h" |
#include "scli.h" |
/* Temporary to store strings */ |
#define EXT_HELP "extended" |
#define SHORT_HELP "short" |
#define TEST_ANNOUNCE "Hello, this is :" |
/* Simple levels of help displays */ |
#define HELP_SHORT 0 |
#define HELP_LONG 1 |
/* Acceptable buffer sizes (for strn functions) */ |
/* TODO: Move me, other files duplicate these needlessly */ |
#define BUFF_LARGE 1024 |
#define BUFF_SMALL 255 |
/* Return macros for int type entry points */ |
#define CMD_FAILURE (int*)1 |
#define CMD_SUCCESS 0 |
#define CMD_VOID (void *)NULL |
/* Types for module command entry and help */ |
typedef int * (* mod_entry_t)(char **); |
typedef void * (* mod_help_t)(unsigned int); |
/* Built-in commands need to be able to modify cliuser_t */ |
typedef int * (* builtin_entry_t)(char **, cliuser_t *); |
typedef void * (* builtin_help_t)(unsigned int); |
/* Module structure */ |
typedef struct { |
char *name; /* Name of the command */ |
char *desc; /* Description of the command */ |
mod_entry_t entry; /* Command (exec) entry function */ |
mod_help_t help; /* Command (help) entry function */ |
int restricted; /* Restricts to interactive/non-interactive only */ |
} module_t; |
/* Builtin structure, same as modules except different types of entry points */ |
typedef struct { |
char *name; |
char *desc; |
builtin_entry_t entry; |
builtin_help_t help; |
int restricted; |
} builtin_t; |
/* Declared in cmds/modules/modules.h and cmds/builtins/builtins.h |
* respectively */ |
extern module_t modules[]; |
extern builtin_t builtins[]; |
/* Prototypes for module launchers */ |
extern int module_is_restricted(int); |
extern int is_module(const char *); |
extern int is_module_alias(const char *); |
extern char * alias_for_module(const char *); |
extern int help_module(int, unsigned int); |
extern int run_module(int, char *[]); |
/* Prototypes for builtin launchers */ |
extern int builtin_is_restricted(int); |
extern int is_builtin(const char *); |
extern int is_builtin_alias(const char *); |
extern char * alias_for_builtin(const char *); |
extern int help_builtin(int, unsigned int); |
extern int run_builtin(int, char *[], cliuser_t *); |
#endif |
/branches/dynload/uspace/app/bdsh/cmds/builtin_cmds.c |
---|
0,0 → 1,126 |
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com> |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions are met: |
* |
* Redistributions of source code must retain the above copyright notice, this |
* list of conditions and the following disclaimer. |
* |
* Redistributions in binary form must reproduce the above copyright notice, |
* this list of conditions and the following disclaimer in the documentation |
* and/or other materials provided with the distribution. |
* |
* Neither the name of the original program's authors nor the names of its |
* contributors may be used to endorse or promote products derived from this |
* software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
/* Almost identical (for now) to mod_cmds.c , however this will not be the case |
* soon as builtin_t is going to grow way beyond module_t */ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include "errors.h" |
#include "cmds.h" |
#include "builtin_aliases.h" |
extern volatile unsigned int cli_interactive; |
int builtin_is_restricted(int pos) |
{ |
builtin_t *cmd = builtins; |
cmd += pos; |
if (cli_interactive && cmd->restricted <= 0) |
return 0; |
if (!cli_interactive && cmd->restricted >= 0) |
return 0; |
return 1; |
} |
int is_builtin(const char *command) |
{ |
builtin_t *cmd; |
unsigned int i = 0; |
if (NULL == command) |
return -2; |
for (cmd = builtins; cmd->name != NULL; cmd++, i++) { |
if (!strcmp(cmd->name, command)) |
return i; |
} |
return -1; |
} |
int is_builtin_alias(const char *command) |
{ |
unsigned int i = 0; |
if (NULL == command) |
return -1; |
for(i=0; builtin_aliases[i] != NULL; i+=2) { |
if (!strcmp(builtin_aliases[i], command)) |
return 1; |
} |
return 0; |
} |
char *alias_for_builtin(const char *command) |
{ |
unsigned int i = 0; |
if (NULL == command) |
return (char *)NULL; |
for(i=0; builtin_aliases[i] != NULL; i++) { |
if (!strcmp(builtin_aliases[i], command)) |
return (char *)builtin_aliases[++i]; |
i++; |
} |
return (char *)NULL; |
} |
int help_builtin(int builtin, unsigned int extended) |
{ |
builtin_t *cmd = builtins; |
cmd += builtin; |
if (NULL != cmd->help) { |
cmd->help(extended); |
return CL_EOK; |
} else |
return CL_ENOENT; |
} |
int run_builtin(int builtin, char *argv[], cliuser_t *usr) |
{ |
builtin_t *cmd = builtins; |
cmd += builtin; |
if (NULL != cmd->entry) |
return((int)cmd->entry(argv, usr)); |
return CL_ENOENT; |
} |
/branches/dynload/uspace/app/bdsh/util.c |
---|
0,0 → 1,284 |
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com> |
* Copyright (C) 1998 by Wes Peters <wes@softweyr.com> |
* Copyright (c) 1988, 1993 The Regents of the University of California. |
* All rights reserved by all copyright holders. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions are met: |
* |
* Redistributions of source code must retain the above copyright notice, this |
* list of conditions and the following disclaimer. |
* |
* Redistributions in binary form must reproduce the above copyright notice, |
* this list of conditions and the following disclaimer in the documentation |
* and/or other materials provided with the distribution. |
* |
* Neither the name of the original program's authors nor the names of its |
* contributors may be used to endorse or promote products derived from this |
* software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
/* NOTES: |
* 1 - Various functions were adapted from FreeBSD (copyright holders noted above) |
* these functions are identified with comments. |
* |
* 2 - Some of these have since appeared in libc. They remain here for various |
* reasons, such as the eventual integration of garbage collection for things |
* that allocate memory and don't automatically free it. |
* |
* 3 - Things that expect a pointer to an allocated string do _no_ sanity checking |
* if developing on a simulator with no debugger, take care :) |
*/ |
#include <stdio.h> |
#include <string.h> |
#include <stdarg.h> |
#include <stdlib.h> |
#include <stdarg.h> |
#include "config.h" |
#include "errors.h" |
#include "util.h" |
extern volatile int cli_errno; |
/* some platforms do not have strdup, implement it here. |
* Returns a pointer to an allocated string or NULL on failure */ |
char * cli_strdup(const char *s1) |
{ |
size_t len = strlen(s1) + 1; |
void *ret = malloc(len); |
if (ret == NULL) { |
cli_errno = CL_ENOMEM; |
return (char *) NULL; |
} |
cli_errno = CL_EOK; |
return (char *) memcpy(ret, s1, len); |
} |
/* |
* Take a previously allocated string (s1), re-size it to accept s2 and copy |
* the contents of s2 into s1. |
* Return -1 on failure, or the length of the copied string on success. |
*/ |
int cli_redup(char **s1, const char *s2) |
{ |
size_t len = strlen(s2) + 1; |
if (! len) |
return -1; |
*s1 = realloc(*s1, len); |
if (*s1 == NULL) { |
cli_errno = CL_ENOMEM; |
return -1; |
} |
memset(*s1, 0, sizeof(*s1)); |
memcpy(*s1, s2, len); |
cli_errno = CL_EOK; |
return (int) len; |
} |
/* An asprintf() for formatting paths, similar to asprintf() but ensures |
* the returned allocated string is <= PATH_MAX. On failure, an attempt |
* is made to return the original string (if not null) unmodified. |
* |
* Returns: Length of the new string on success, 0 if the string was handed |
* back unmodified, -1 on failure. On failure, cli_errno is set. |
* |
* We do not use POSIX_PATH_MAX, as it is typically much smaller than the |
* PATH_MAX defined by the kernel. |
* |
* Use this like: |
* if (1 > cli_psprintf(&char, "%s/%s", foo, bar)) { |
* cli_error(cli_errno, "Failed to format path"); |
* stop_what_your_doing_as_your_out_of_memory(); |
* } |
*/ |
int cli_psprintf(char **s1, const char *fmt, ...) |
{ |
va_list ap; |
size_t needed, base = PATH_MAX + 1; |
int skipped = 0; |
char *orig = NULL; |
char *tmp = (char *) malloc(base); |
/* Don't even touch s1, not enough memory */ |
if (NULL == tmp) { |
cli_errno = CL_ENOMEM; |
return -1; |
} |
/* If re-allocating s1, save a copy in case we fail */ |
if (NULL != *s1) |
orig = cli_strdup(*s1); |
/* Print the string to tmp so we can determine the size that |
* we actually need */ |
memset(tmp, 0, sizeof(tmp)); |
va_start(ap, fmt); |
/* vsnprintf will return the # of bytes not written */ |
skipped = vsnprintf(tmp, base, fmt, ap); |
va_end(ap); |
/* realloc/alloc s1 to be just the size that we need */ |
needed = strlen(tmp) + 1; |
*s1 = realloc(*s1, needed); |
if (NULL == *s1) { |
/* No string lived here previously, or we failed to |
* make a copy of it, either way there's nothing we |
* can do. */ |
if (NULL == *orig) { |
cli_errno = CL_ENOMEM; |
return -1; |
} |
/* We can't even allocate enough size to restore the |
* saved copy, just give up */ |
*s1 = realloc(*s1, strlen(orig) + 1); |
if (NULL == *s1) { |
free(tmp); |
free(orig); |
cli_errno = CL_ENOMEM; |
return -1; |
} |
/* Give the string back as we found it */ |
memset(*s1, 0, sizeof(*s1)); |
memcpy(*s1, orig, strlen(orig) + 1); |
free(tmp); |
free(orig); |
cli_errno = CL_ENOMEM; |
return 0; |
} |
/* Ok, great, we have enough room */ |
memset(*s1, 0, sizeof(*s1)); |
memcpy(*s1, tmp, needed); |
free(tmp); |
/* Free tmp only if s1 was reallocated instead of allocated */ |
if (NULL != orig) |
free(orig); |
if (skipped) { |
/* s1 was bigger than PATH_MAX when expanded, however part |
* of the string was printed. Tell the caller not to use it */ |
cli_errno = CL_ETOOBIG; |
return -1; |
} |
/* Success! */ |
cli_errno = CL_EOK; |
return (int) needed; |
} |
/* Ported from FBSD strtok.c 8.1 (Berkeley) 6/4/93 */ |
char * cli_strtok_r(char *s, const char *delim, char **last) |
{ |
char *spanp, *tok; |
int c, sc; |
if (s == NULL && (s = *last) == NULL) { |
cli_errno = CL_EFAIL; |
return (NULL); |
} |
cont: |
c = *s++; |
for (spanp = (char *)delim; (sc = *spanp++) != 0;) { |
if (c == sc) |
goto cont; |
} |
if (c == 0) { /* no non-delimiter characters */ |
*last = NULL; |
return (NULL); |
} |
tok = s - 1; |
for (;;) { |
c = *s++; |
spanp = (char *)delim; |
do { |
if ((sc = *spanp++) == c) { |
if (c == 0) |
s = NULL; |
else |
s[-1] = '\0'; |
*last = s; |
return (tok); |
} |
} while (sc != 0); |
} |
} |
/* Ported from FBSD strtok.c 8.1 (Berkeley) 6/4/93 */ |
char * cli_strtok(char *s, const char *delim) |
{ |
static char *last; |
return (cli_strtok_r(s, delim, &last)); |
} |
/* Count and return the # of elements in an array */ |
unsigned int cli_count_args(char **args) |
{ |
unsigned int i; |
for (i=0; args[i] != NULL; i++); |
return i; |
} |
/* (re)allocates memory to store the current working directory, gets |
* and updates the current working directory, formats the prompt |
* string */ |
unsigned int cli_set_prompt(cliuser_t *usr) |
{ |
usr->prompt = (char *) realloc(usr->prompt, PATH_MAX); |
if (NULL == usr->prompt) { |
cli_error(CL_ENOMEM, "Can not allocate prompt"); |
cli_errno = CL_ENOMEM; |
return 1; |
} |
memset(usr->prompt, 0, sizeof(usr->prompt)); |
usr->cwd = (char *) realloc(usr->cwd, PATH_MAX); |
if (NULL == usr->cwd) { |
cli_error(CL_ENOMEM, "Can not allocate cwd"); |
cli_errno = CL_ENOMEM; |
return 1; |
} |
memset(usr->cwd, 0, sizeof(usr->cwd)); |
usr->cwd = getcwd(usr->cwd, PATH_MAX - 1); |
if (NULL == usr->cwd) |
snprintf(usr->cwd, PATH_MAX, "(unknown)"); |
if (1 < cli_psprintf(&usr->prompt, "%s # ", usr->cwd)) { |
cli_error(cli_errno, "Failed to set prompt"); |
return 1; |
} |
return 0; |
} |
/branches/dynload/uspace/app/bdsh/util.h |
---|
0,0 → 1,17 |
#ifndef UTIL_H |
#define UTIL_H |
#include "scli.h" |
/* Internal string handlers */ |
extern char * cli_strdup(const char *); |
extern int cli_redup(char **, const char *); |
extern int cli_psprintf(char **, const char *, ...); |
extern char * cli_strtok_r(char *, const char *, char **); |
extern char * cli_strtok(char *, const char *); |
/* Utility functions */ |
extern unsigned int cli_count_args(char **); |
extern unsigned int cli_set_prompt(cliuser_t *usr); |
#endif |
/branches/dynload/uspace/app/bdsh/Makefile |
---|
0,0 → 1,134 |
# Copyright (c) 2005, Martin Decky |
# All rights reserved. |
# Copyright (c) 2008, Tim Post <tinkertim@gmail.com> |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions are met: |
# |
# Redistributions of source code must retain the above copyright notice, this |
# list of conditions and the following disclaimer. |
# |
# Redistributions in binary form must reproduce the above copyright notice, |
# this list of conditions and the following disclaimer in the documentation |
# and/or other materials provided with the distribution. |
# |
# Neither the name of the original program's authors nor the names of its |
# contributors may be used to endorse or promote products derived from this |
# software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
# POSSIBILITY OF SUCH DAMAGE. |
include ../../../version |
include ../../Makefile.config |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += -I../../srv/kbd/include |
LIBS = $(LIBC_PREFIX)/libc.a |
DEFS += -DRELEASE=\"$(RELEASE)\" |
ifdef REVISION |
DEFS += "-DREVISION=\"$(TIMESTAMP)\"" |
endif |
ifdef TIMESTAMP |
DEFS += "-DTIMESTAMP=\"$(TIMESTAMP)\"" |
endif |
PROGRAM = bdsh |
# Any directory that cleaning targets should know about |
SUBDIRS = \ |
./ \ |
cmds/ \ |
cmds/modules/ \ |
cmds/modules/help/ \ |
cmds/modules/quit/ \ |
cmds/modules/mkdir/ \ |
cmds/modules/rm/ \ |
cmds/modules/cat/ \ |
cmds/modules/touch/ \ |
cmds/modules/ls/ \ |
cmds/modules/pwd/ \ |
cmds/builtins/ \ |
cmds/builtins/cd/ |
SOURCES = \ |
cmds/modules/help/help.c \ |
cmds/modules/quit/quit.c \ |
cmds/modules/mkdir/mkdir.c \ |
cmds/modules/rm/rm.c \ |
cmds/modules/cat/cat.c \ |
cmds/modules/touch/touch.c \ |
cmds/modules/ls/ls.c \ |
cmds/modules/pwd/pwd.c \ |
cmds/builtins/cd/cd.c \ |
cmds/mod_cmds.c \ |
cmds/builtin_cmds.c \ |
errors.c \ |
input.c \ |
util.c \ |
exec.c \ |
scli.c |
CFLAGS += -I. -Icmds/ -Icmds/builtins -Icmds/modules |
OBJECTS = $(SOURCES:.c=.o) |
# For easy cleaning, *.o is already handled |
CLEANDIRS := $(addsuffix *~,$(SUBDIRS)) |
CLEANDIRS += $(addsuffix *.bak,$(SUBDIRS)) |
CLEANDIRS += $(addsuffix *.tmp,$(SUBDIRS)) |
CLEANDIRS += $(addsuffix *.out,$(SUBDIRS)) |
CLEANDIRS += $(addsuffix *.d,$(SUBDIRS)) |
CLEANDIRS += $(addsuffix *.gch,$(SUBDIRS) ) |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
%.o: %.s |
$(AS) $(AFLAGS) $< -o $@ |
%.o: %.c |
$(CC) $(CFLAGS) $(INC) -c $< -o $@ |
@$(CC) -M $(CFLAGS) $(INC) $*.c > $*.d |
$(PROGRAM): $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(PROGRAM).map |
# Everything else is a phony target |
.PHONY: all clean distclean depend disasm |
all: $(PROGRAM) disasm |
clean: |
@-rm -f $(OBJECTS) |
@-rm -f $(PROGRAM) |
@-rm -f $(PROGRAM).map |
@-rm -f $(PROGRAM).disasm |
@-rm -f $(CLEANDIRS) |
depend: |
@echo '' |
disasm: |
$(OBJDUMP) -d $(PROGRAM) >$(PROGRAM).disasm |
distclean: clean |
# Do not delete - dependencies |
-include $(OBJECTS:.o=.d) |
/branches/dynload/uspace/app/bdsh/input.c |
---|
0,0 → 1,177 |
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com> |
* All rights reserved. |
* Copyright (c) 2008, Jiri Svoboda - All Rights Reserved |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions are met: |
* |
* Redistributions of source code must retain the above copyright notice, this |
* list of conditions and the following disclaimer. |
* |
* Redistributions in binary form must reproduce the above copyright notice, |
* this list of conditions and the following disclaimer in the documentation |
* and/or other materials provided with the distribution. |
* |
* Neither the name of the original program's authors nor the names of its |
* contributors may be used to endorse or promote products derived from this |
* software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <io/stream.h> |
#include "config.h" |
#include "util.h" |
#include "scli.h" |
#include "input.h" |
#include "errors.h" |
#include "exec.h" |
extern volatile unsigned int cli_interactive; |
/* Not exposed in input.h */ |
static void cli_restricted(char *); |
static void read_line(char *, int); |
/* More than a macro than anything */ |
static void cli_restricted(char *cmd) |
{ |
printf("%s is not available in %s mode\n", cmd, |
cli_interactive ? "interactive" : "non-interactive"); |
return; |
} |
/* Tokenizes input from console, sees if the first word is a built-in, if so |
* invokes the built-in entry point (a[0]) passing all arguments in a[] to |
* the handler */ |
int tok_input(cliuser_t *usr) |
{ |
char *cmd[WORD_MAX]; |
int n = 0, i = 0; |
int rc = 0; |
char *tmp; |
if (NULL == usr->line) |
return CL_EFAIL; |
tmp = cli_strdup(usr->line); |
/* Break up what the user typed, space delimited */ |
/* TODO: Protect things in quotes / ticks, expand wildcards */ |
cmd[n] = cli_strtok(tmp, " "); |
while (cmd[n] && n < WORD_MAX) { |
cmd[++n] = cli_strtok(NULL, " "); |
} |
/* We have rubbish */ |
if (NULL == cmd[0]) { |
rc = CL_ENOENT; |
goto finit; |
} |
/* Its a builtin command */ |
if ((i = (is_builtin(cmd[0]))) > -1) { |
/* Its not available in this mode, see what try_exec() thinks */ |
if (builtin_is_restricted(i)) { |
rc = try_exec(cmd[0], cmd); |
if (rc) |
/* No external matching it could be found, tell the |
* user that the command does exist, but is not |
* available in this mode. */ |
cli_restricted(cmd[0]); |
goto finit; |
} |
/* Its a builtin, its available, run it */ |
rc = run_builtin(i, cmd, usr); |
goto finit; |
/* We repeat the same dance for modules */ |
} else if ((i = (is_module(cmd[0]))) > -1) { |
if (module_is_restricted(i)) { |
rc = try_exec(cmd[0], cmd); |
if (rc) |
cli_restricted(cmd[0]); |
goto finit; |
} |
rc = run_module(i, cmd); |
goto finit; |
} else { |
/* Its not a module or builtin, restricted or otherwise. |
* See what try_exec() thinks of it and just pass its return |
* value back to the caller */ |
rc = try_exec(cmd[0], cmd); |
goto finit; |
} |
finit: |
if (NULL != usr->line) { |
free(usr->line); |
usr->line = (char *) NULL; |
} |
if (NULL != tmp) |
free(tmp); |
return rc; |
} |
/* Borrowed from Jiri Svoboda's 'cli' uspace app */ |
static void read_line(char *buffer, int n) |
{ |
char c; |
int chars; |
chars = 0; |
while (chars < n - 1) { |
c = getchar(); |
if (c < 0) |
return; |
if (c == '\n') |
break; |
if (c == '\b') { |
if (chars > 0) { |
putchar('\b'); |
--chars; |
} |
continue; |
} |
putchar(c); |
buffer[chars++] = c; |
} |
putchar('\n'); |
buffer[chars] = '\0'; |
} |
/* TODO: |
* Implement something like editline() / readline(), if even |
* just for command history and making arrows work. */ |
void get_input(cliuser_t *usr) |
{ |
char line[INPUT_MAX]; |
size_t len = 0; |
printf("%s", usr->prompt); |
read_line(line, INPUT_MAX); |
len = strlen(line); |
/* Make sure we don't have rubbish or a C/R happy user */ |
if (len == 0 || line[0] == '\n') |
return; |
usr->line = cli_strdup(line); |
return; |
} |
/branches/dynload/uspace/app/bdsh/input.h |
---|
0,0 → 1,11 |
#ifndef INPUT_H |
#define INPUT_H |
#include "cmds/cmds.h" |
/* prototypes */ |
extern void get_input(cliuser_t *); |
extern int tok_input(cliuser_t *); |
#endif |
/branches/dynload/uspace/app/bdsh/exec.c |
---|
0,0 → 1,129 |
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com> |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions are met: |
* |
* Redistributions of source code must retain the above copyright notice, this |
* list of conditions and the following disclaimer. |
* |
* Redistributions in binary form must reproduce the above copyright notice, |
* this list of conditions and the following disclaimer in the documentation |
* and/or other materials provided with the distribution. |
* |
* Neither the name of the original program's authors nor the names of its |
* contributors may be used to endorse or promote products derived from this |
* software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
/* The VERY basics of execute in place support. These are buggy, leaky |
* and not nearly done. Only here for beta testing!! You were warned!! |
* TODO: |
* Hash command lookups to save time |
* Create a running pointer to **path and advance/rewind it as we go */ |
#include <stdio.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <string.h> |
#include <fcntl.h> |
#include "config.h" |
#include "util.h" |
#include "exec.h" |
#include "errors.h" |
/* FIXME: Just have find_command() return an allocated string */ |
char *found; |
static char *find_command(char *); |
static unsigned int try_access(const char *); |
/* work-around for access() */ |
static unsigned int try_access(const char *f) |
{ |
int fd; |
fd = open(f, O_RDONLY); |
if (fd > -1) { |
close(fd); |
return 0; |
} else |
return -1; |
} |
/* Returns the full path of "cmd" if cmd is found, else just hand back |
* cmd as it was presented */ |
static char *find_command(char *cmd) |
{ |
char *path_tok; |
char *path[PATH_MAX]; |
int n = 0, i = 0; |
size_t x = strlen(cmd) + 2; |
found = (char *)malloc(PATH_MAX); |
/* The user has specified a full or relative path, just give it back. */ |
if (-1 != try_access(cmd)) { |
return (char *) cmd; |
} |
path_tok = cli_strdup(PATH); |
/* Extract the PATH env to a path[] array */ |
path[n] = cli_strtok(path_tok, PATH_DELIM); |
while (NULL != path[n]) { |
if ((strlen(path[n]) + x ) > PATH_MAX) { |
cli_error(CL_ENOTSUP, |
"Segment %d of path is too large, search ends at segment %d", |
n, n-1); |
break; |
} |
path[++n] = cli_strtok(NULL, PATH_DELIM); |
} |
/* We now have n places to look for the command */ |
for (i=0; path[i]; i++) { |
memset(found, 0, sizeof(found)); |
snprintf(found, PATH_MAX, "%s/%s", path[i], cmd); |
if (-1 != try_access(found)) { |
free(path_tok); |
return (char *) found; |
} |
} |
/* We didn't find it, just give it back as-is. */ |
free(path_tok); |
return (char *) cmd; |
} |
unsigned int try_exec(char *cmd, char **argv) |
{ |
task_id_t tid; |
char *tmp; |
tmp = cli_strdup(find_command(cmd)); |
free(found); |
tid = task_spawn((const char *)tmp, (const char **)argv); |
free(tmp); |
if (tid == 0) { |
cli_error(CL_EEXEC, "Can not spawn %s", cmd); |
return 1; |
} else { |
return 0; |
} |
} |
/branches/dynload/uspace/app/bdsh/exec.h |
---|
0,0 → 1,7 |
#ifndef EXEC_H |
#define EXEC_H |
#include <task.h> |
extern unsigned int try_exec(char *, char **); |
#endif |
/branches/dynload/uspace/app/bdsh/README |
---|
0,0 → 1,268 |
BDSH - The Brain Dead Shell | Design Documentation |
-------------------------------------------------- |
Overview: |
========= |
BDSH was written as a drop in command line interface for HelenOS to permit |
interactive access to persistent file systems in development. BDSH was |
written from scratch with a very limited userspace standard C library in |
mind. Much like the popular Busybox program, BDSH provides a very limited |
shell with limited common UNIX creature comforts built in. |
Porting Busybox (and by extension ASH) would have taken much longer to |
complete, much less make stable due to stark differences between Linux and |
Spartan with regards to IPC, term I/O and process creation. BDSH was written |
and made stable within the space of less than 30 days. |
BDSH will eventually evolve and be refined into the HelenOS equivalent |
of Busybox. While BDSH is now very intrinsic to HelenOS, its structure and |
use of strictly lower level functions makes it extremely easy to port. |
Design: |
======= |
BDSH is made up of three basic components: |
1. Main i/o, error handling and task management |
2. The builtin sub system |
3. The module sub system |
The main part handles user input, reports errors, spawns external tasks and |
provides a convenient entry point for built-in and modular commands. A simple |
structure, cliuser_t keeps track of the user's vitals, such as their current |
working directory (and eventually uid, home directory, etc if they apply). |
This part defines and exposes all functions that are not intrinsic to a |
certain built in or modular command. For instance: string handlers, |
module/builtin search and launch functions, error handlers and other things |
can be found here. |
Builtin commands are commands that must have access to cliuser_t, which is |
not exposed to modular commands. For instance, the 'cd' command must update |
the current working directory, which is stored in cliuser_t. As such, the |
entry types for builtin commands are slightly different. |
Modular commands do not need anything more than the basic functions that are |
exposed by default. They do not need to modify cliuser_t, they are just self |
contained. A modular command could very easily be made into a stand alone |
program, likewise any stand alone program could easily become a modular |
command. |
Both modular and builtin commands share two things in common. Both must have |
two entry points, one to invoke the command and one to invoke a help display |
for the command. Exec (main()) entry points are int * and are expected to |
return a value. Help entry points are void *, no return value is expected. |
They are typed as such (from cmds.h): |
/* Types for module command entry and help */ |
typedef int * (* mod_entry_t)(char **); |
typedef void * (* mod_help_t)(unsigned int); |
/* Built-in commands need to be able to modify cliuser_t */ |
typedef int * (* builtin_entry_t)(char **, cliuser_t *); |
typedef void * (* builtin_help_t)(unsigned int); |
As you can see, both modular and builtin commands expect an array of |
arguments, however bulitins also expect to be pointed to cliuser_t. |
Both are defined with the same simple structure: |
/* Module structure */ |
typedef struct { |
char *name; /* Name of the command */ |
char *desc; /* Description of the command */ |
mod_entry_t entry; /* Command (exec) entry function */ |
mod_help_t help; /* Command (help) entry function */ |
int restricted; /* Restricts to interactive/non-interactive only */ |
} module_t; |
NOTE: Builtin commands may grow in this respect, that is why they are |
defined separately. |
Builtins, of course, would use the builtin_entry_t type. The name of the |
command is used to associate user input to a possible entry point. The |
description is a short (40 - 60 chars) summary of what the command does. Both |
entry points are then defined, and the restrict value is used to determine a |
commands availability. |
Restriction levels are easy, a command is either available exclusively within |
interactive mode, exclusively within non-interactive mode or both. If you are |
looking at a prompt, you are in interactive mode. If you issue a command like |
this: |
/sbin/bdsh command [arg1] [arg2] |
... you are in non interactive mode. This is done when you need to force the |
parent shell to be the one who actually handles the command, or ensure that |
/sbin/ls was used in lieu of the built in 'ls' when in non-interactive mode. |
The values are: |
0 : Unrestricted |
-1 : Interactive only |
1 : Non-interactive only |
A script to generate skeletal files for a new command is included, it can be |
found in cmds/mknewcmd. To generate a new modular command named 'foo', which |
should also be reachable by typing 'f00', you would issue this command: |
./mknewcmd -n foo -a f00 -t module |
This generates all needed files and instructs you on how to include your new |
command in the build and make it accessible. By default, the command will be |
unrestricted. Builtin commands can be created by changing 'module' to |
'builtin' |
There are more options to mknewcmd, which allow you to specify the |
description, entry point, help entry point, or restriction. By default, names |
just follow the command such as cmd_foo(), help_cmd_foo(), 'The foo command', |
etc. If you want to see the options and explanations in detail, use |
./mknewcmd --help. |
When working with commands, keep in mind that only the main and help entry |
points need to be exposed. If commands share the same functions, put them |
where they are exposed to all commands, without the potential oops of those |
functions going away if the command is eliminated in favor of a stand alone |
external program. |
The util.c file is a great place to put those types of functions. |
Also, be careful with globals, option structures, etc. The compiler will |
generally tell you if you've made a mistake, however declaring: |
volatile int foo |
... in a command will allow for anything else to pick it up. Sometimes |
this could be desirable .. other times not. When communicating between |
builtins and the main system, try to use cliuser_t. The one exception |
for this is the cli_quit global, since everything may at some point |
need to check it. Modules should only communicate their return value. |
Symbolic constants that everything needs should go in the config.h file, |
however this is not the place to define shared macros. |
Making a program into a module |
============================== |
If you have some neat program that would be useful as a modular command, |
converting it is not very hard. The following steps should get you through |
the process easily (assuming your program is named 'foo'): |
1: Use mknewcmd to generate the skeletal files. |
2: Change your "usage()" command as shown: |
-- void usage(...) |
++ void * help_cmd_foo(unsigned int level) |
-- return; |
++ retrn CMD_VOID; |
'level' is either 0 or 1, indicating the level of help requested. |
If the help / usage function currently exits based on how it is |
called, you'll need to change it. |
3: Change the programs "main()" as shown: |
-- int main(int argc, char **argv) |
++ int * cmd_foo(char **argv) |
-- return 1; |
++ return CMD_FAILURE; |
-- return 0; |
++ return CMD_SUCCESS; |
If main() returns an int that is not 1 or 0 (e.g. 127), cast it as |
such: |
-- return 127; |
++ return (int *) 127; |
NOTE: _ONLY_ the main and help entry points need to return int * or |
void *, respectively. Also take note that argc has changed. The type |
for entry points may soon change. |
NOTE: If main is void, you'll need to change it and ensure that its |
expecting an array of arguments, even if they'll never be read or |
used. I.e.: |
-- void main(void) |
++ int * cmd_foo(char **argv) |
Similararly, do not try to return CMD_VOID within the modules main |
entry point. If somehow you escape the compiler yelling at you, you |
will surely see pretty blue and yellow fireworks once its reached. |
4: Don't expose more than the entry and help points: |
-- void my_function(int n) |
++ static void my_function(int n) |
5: Copy/paste to the stub generated by mknewcmd then add your files to the |
Makefile. Be sure to add any directories that you made to the SUBDIRS so |
that a 'make clean' will clean them. |
Provided that all functions that your calling are available in the |
userspace C library, your program should compile just fine and appear |
as a modular command. |
Overcoming userspace libc obstacles |
=================================== |
A quick glance through the util.c file will reveal functions like |
cli_strdup(), cli_strtok(), cli_strtok_r() and more. Those are functions |
that were missing from userspace libc when BDSH was born. Later, after |
porting what was needed from FBSD/NBSD, the real functions appeared in |
the userspace libc after being tested in their cli_* implementations. |
Those functions remain because they guarantee that bdsh will work even |
on systems that lack them. Additionally, more BDSH specific stuff can |
go into them, such as error handling and reporting when malloc() fails. |
You will also notice that FILE, fopen() (and all friends), ato*() and |
other common things might be missing. The HelenOS userspace C library is |
still very young, you are sure to run into something that you want/need |
which is missing. |
When that happens, you have three options: |
1 - Implement it internally in util.c , when its tested and stable send a |
patch to HelenOS asking for your function to be included in libc. This is |
the best option, as you not only improve BDSH .. but HelenOS as a whole. |
2 - Work around it. Not everyone can implement / port fopen() and all of |
its friends. Make open(), read(), write() (etc) work if at all possible. |
3 - Send an e-mail to the HelenOS development mailing list. Explain why you |
need the function and what its absence is holding up. |
If what you need is part of a library that is typically a shared object, try |
to implement a 'mini' version of it. Currently, all userspace applications |
are statically linked. Giving up creature comforts for size while avoiding |
temporary 'band aids' is never frowned upon. |
Most of all, don't get discouraged .. ask for some help prior to giving up |
if you just can't accomplish something with the limited means provided. |
Contributing |
============ |
I will take any well written patch that sanely improves or expands BDSH. Send |
me a patch against the trunk revision, or, if you like a Mercurial repository |
is also maintained at http://echoreply.us/hg/bdsh.hg and kept in sync with |
the trunk. |
Please be sure to follow the simple coding standards outlined at |
http://www.helenos.eu/cstyle (mostly just regarding formatting), test your |
changes and make sure your patch applies cleanly against the latest revision. |
All patches submitted must be your original code, or a derivative work of |
something licensed under the same 3 clause BSD license as BDSH. See LICENSE |
for more information. |
When sending patches, you agree that your work will be published under the |
same 3 clause BSD license as BDSH itself. Failure to ensure that anything |
you used is not under the same or less restrictive license could cause major |
issues for BDSH in the future .. please be sure. Also, please don't forget |
to add yourself in the AUTHORS file, as I am horrible about keeping such |
things up to date. |
/branches/dynload/uspace/app/bdsh/errors.c |
---|
0,0 → 1,87 |
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com> |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions are met: |
* |
* Redistributions of source code must retain the above copyright notice, this |
* list of conditions and the following disclaimer. |
* |
* Redistributions in binary form must reproduce the above copyright notice, |
* this list of conditions and the following disclaimer in the documentation |
* and/or other materials provided with the distribution. |
* |
* Neither the name of the original program's authors nor the names of its |
* contributors may be used to endorse or promote products derived from this |
* software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <stdio.h> |
#include <string.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <stdarg.h> |
#include "config.h" |
#include "errors.h" |
#include "errstr.h" |
volatile int cli_errno = CL_EOK; |
extern volatile unsigned int cli_quit; |
/* Error printing, translation and handling functions */ |
/* Look up errno in cl_errors and return the corresponding string. |
* Return NULL if not found */ |
static char *err2str(int err) |
{ |
if (NULL != cl_errors[err]) |
return cl_errors[err]; |
return (char *)NULL; |
} |
/* Print an error report signifying errno, which is translated to |
* its corresponding human readable string. If errno > 0, raise the |
* cli_quit int that tells the main program loop to exit immediately */ |
void cli_error(int err, const char *fmt, ...) |
{ |
va_list vargs; |
va_start(vargs, fmt); |
vprintf(fmt, vargs); |
va_end(vargs); |
if (NULL != err2str(err)) |
printf(" (%s)\n", err2str(err)); |
else |
printf(" (Unknown Error %d)\n", err); |
/* If fatal, raise cli_quit so that we try to exit |
* gracefully. This will break the main loop and |
* invoke the destructor */ |
if (err == CL_EFATAL) |
cli_quit = 1; |
return; |
} |
/branches/dynload/uspace/app/bdsh/errors.h |
---|
0,0 → 1,22 |
#ifndef ERRORS_H |
#define ERRORS_H |
/* Various error levels */ |
#define CL_EFATAL -1 |
#define CL_EOK 0 |
#define CL_EFAIL 1 |
#define CL_EBUSY 2 |
#define CL_ENOENT 3 |
#define CL_ENOMEM 4 |
#define CL_EPERM 5 |
#define CL_ENOTSUP 6 |
#define CL_EEXEC 7 |
#define CL_EEXISTS 8 |
#define CL_ETOOBIG 9 |
/* Just like 'errno' */ |
extern volatile int cli_errno; |
extern void cli_error(int, const char *, ...); |
#endif |
/branches/dynload/uspace/app/bdsh/errstr.h |
---|
0,0 → 1,23 |
#ifndef ERRSTR_H |
#define ERRSTR_H |
/* Simple array to translate error codes to meaningful strings */ |
static char *cl_errors[] = { |
"Success", |
"Failure", |
"Busy", |
"No Such Entry", |
"Not Enough Memory", |
"Permission Denied", |
"Method Not Supported", |
"Bad command or file name", |
"Entry already exists", |
"Object too large", |
NULL |
}; |
static char *err2str(int); |
#endif |
/branches/dynload/uspace/app/bdsh/TODO |
---|
0,0 → 1,57 |
This is a very brain dead shell. It needs some love, coffee or perhaps beer. |
Currently, you can't even really call it a shell, its more of a CLI that |
offers some shell like creature comforts. |
This was written in a hurry to provide some means of testing persistent file |
systems in HelenOS. It does its job, its nowhere near complete but it is |
actively developed. If your reading this, its likely that you're looking for |
some functionality that is not yet present. Prior to filing a bug report, |
please make sure that what you want is not on the list below. |
A list of things to do: |
----------------------- |
* rm: add support for recursively removing directories and files therein |
* Port an editor (vim?) |
* Finish cat / cp |
* Support basic redirection (i.e ls > foo.txt) |
* Expand wildcards (i.e. *.txt), don't worry about variables for now |
* Basic scripting |
* Hash previously found commands |
* Improve input, add history / etc (port libedit?) |
* Add wrappers for signal, sigaction to make ports to modules easier |
* Add 'echo' and 'printf' modules. |
Regarding POSIX: |
---------------- |
POSIX is a standard for Unix-like operating systems. HelenOS is (mostly) just |
a kernel at this point with a few userspace programs that facilitate testing |
of the kernel and file systems. |
HelenOS is not a Unix-like operating system. HelenOS is its own thing, a modern |
microkernel OS and many directions are not yet set. |
Please do not e-mail me to point out that modular implementations that resemble |
typical core utilities do not conform to some POSIX standard, these are temporary |
and serve the useful purpose of testing persistent file systems. |
Contributing: |
------------- |
If you feel like doing any of the above to-do items, I am echo@echoreply.us. Please |
e-mail me and let me know your working on something so that I do not unwittingly |
duplicate your efforts. You can also e-mail the HelenOS list directly: |
HelenOS development mailing list <helenos-devel@lists.modry.cz> |
Subscribe here if you like: http://lists.modry.cz/cgi-bin/listinfo/helenos-devel |
Cheers and happy hacking! |
--Tim |
/branches/dynload/uspace/app/bdsh/config.h |
---|
0,0 → 1,33 |
/* Various things that are used in many files |
* Various temporary port work-arounds are addressed in __HELENOS__ , this |
* serves as a convenience and later as a guide to make "phony.h" for future |
* ports */ |
/* Specific port work-arounds : */ |
#define PATH_MAX 255 |
#define EXIT_SUCCESS 0 |
#define EXIT_FAILURE 0 |
/* Work around for getenv() */ |
#define PATH "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin" |
#define PATH_DELIM ":" |
/* Used in many places */ |
#define SMALL_BUFLEN 256 |
#define LARGE_BUFLEN 1024 |
/* How many words (arguments) are permitted, how big can a whole |
* sentence be? Similar to ARG_MAX */ |
#define WORD_MAX 255 |
#define INPUT_MAX 1024 |
/* Leftovers from Autoconf */ |
#define PACKAGE_MAINTAINER "Tim Post" |
#define PACKAGE_BUGREPORT "echo@echoreply.us" |
#define PACKAGE_NAME "bdsh" |
#define PACKAGE_STRING "The brain dead shell" |
#define PACKAGE_TARNAME "scli" |
#define PACKAGE_VERSION "0.0.1" |
/branches/dynload/uspace/app/bdsh/AUTHORS |
---|
0,0 → 1,17 |
Written by Tim Post <echo@echoreply.us> to serve as a primitive shell |
for HelenOS, or as a template to make a command line interface that |
offers shell like creature comforts. |
This program was mostly written from scratch, some existing code was |
used from other various free software projects: |
* Based on the HelenOS testing sub-system written by Martin Decky |
* cli_strtok() and cli_strtok_r() (util.c) were adapted from the FreeBSD |
strtok() and strtok_r() functions written by Wes Peters. |
* read_line() (input.c) was written by Jiri Svoboda |
Individual author copyrights are listed in the headers of each file. |
/branches/dynload/uspace/app/bdsh/LICENSE |
---|
0,0 → 1,28 |
Copyright (c) 2008, Tim Post <tinkertim@gmail.com> |
All rights reserved. |
Redistribution and use in source and binary forms, with or without |
modification, are permitted provided that the following conditions are met: |
Redistributions of source code must retain the above copyright notice, this |
list of conditions and the following disclaimer. |
Redistributions in binary form must reproduce the above copyright notice, |
this list of conditions and the following disclaimer in the documentation |
and/or other materials provided with the distribution. |
Neither the name of the original program's authors nor the names of its |
contributors may be used to endorse or promote products derived from this |
software without specific prior written permission. |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
POSSIBILITY OF SUCH DAMAGE. |
/branches/dynload/uspace/app/init/init.c |
---|
55,13 → 55,13 |
usleep(50000); // FIXME |
} |
static bool mount_tmpfs(void) |
static bool mount_fs(const char *fstype) |
{ |
int rc = -1; |
while (rc < 0) { |
rc = mount("tmpfs", "/", "initrd"); |
rc = mount(fstype, "/", "initrd"); |
switch (rc) { |
case EOK: |
printf(NAME ": Root filesystem mounted\n"); |
72,6 → 72,9 |
case ELIMIT: |
printf(NAME ": Unable to mount root filesystem\n"); |
return false; |
case ENOENT: |
printf(NAME ": Unknown filesystem type (%s)\n", fstype); |
return false; |
default: |
sleep(5); // FIXME |
} |
100,7 → 103,7 |
info_print(); |
sleep(5); // FIXME |
if (!mount_tmpfs()) { |
if (!mount_fs("tmpfs") && !mount_fs("fat")) { |
printf(NAME ": Exiting\n"); |
return -1; |
} |
115,11 → 118,7 |
console_wait(); |
version_print(); |
spawn("/sbin/fat"); |
spawn("/sbin/tetris"); |
spawn("/sbin/cli"); |
// FIXME: spawn("/sbin/tester"); |
spawn("/sbin/klog"); |
spawn("/sbin/bdsh"); |
free(buf); |
return 0; |
/branches/dynload/uspace/app/tetris/input.c |
---|
96,6 → 96,7 |
struct timeval starttv, endtv, *s; |
static ipc_call_t charcall; |
ipcarg_t rc; |
int cons_phone; |
/* |
* Someday, select() will do this for us. |
110,8 → 111,11 |
s = NULL; |
if (!lastchar) { |
if (!getchar_inprog) |
getchar_inprog = async_send_2(1,CONSOLE_GETCHAR,0,0,&charcall); |
if (!getchar_inprog) { |
cons_phone = get_cons_phone(); |
getchar_inprog = async_send_2(cons_phone, |
CONSOLE_GETCHAR, 0, 0, &charcall); |
} |
if (!s) |
async_wait_for(getchar_inprog, &rc); |
else if (async_wait_timeout(getchar_inprog, &rc, s->tv_usec) == ETIMEOUT) { |
/branches/dynload/uspace/lib/libfs/libfs.c |
---|
36,6 → 36,7 |
#include "libfs.h" |
#include "../../srv/vfs/vfs.h" |
#include "../../srv/rd/rd.h" |
#include <errno.h> |
#include <async.h> |
#include <ipc/ipc.h> |
330,5 → 331,62 |
ops->node_put(tmp); |
} |
/** Read data from a block device. |
* |
* @param phone Phone to be used to communicate with the device. |
* @param buffer Communication buffer shared with the device. |
* @param bufpos Pointer to the first unread valid offset within the |
* communication buffer. |
* @param buflen Pointer to the number of unread bytes that are ready in |
* the communication buffer. |
* @param pos Device position to be read. |
* @param dst Destination buffer. |
* @param size Size of the destination buffer. |
* @param block_size Block size to be used for the transfer. |
* |
* @return True on success, false on failure. |
*/ |
bool libfs_blockread(int phone, void *buffer, off_t *bufpos, size_t *buflen, |
off_t *pos, void *dst, size_t size, size_t block_size) |
{ |
off_t offset = 0; |
size_t left = size; |
while (left > 0) { |
size_t rd; |
if (*bufpos + left < *buflen) |
rd = left; |
else |
rd = *buflen - *bufpos; |
if (rd > 0) { |
/* |
* Copy the contents of the communication buffer to the |
* destination buffer. |
*/ |
memcpy(dst + offset, buffer + *bufpos, rd); |
offset += rd; |
*bufpos += rd; |
*pos += rd; |
left -= rd; |
} |
if (*bufpos == *buflen) { |
/* Refill the communication buffer with a new block. */ |
ipcarg_t retval; |
int rc = async_req_2_1(phone, RD_READ_BLOCK, |
*pos / block_size, block_size, &retval); |
if ((rc != EOK) || (retval != EOK)) |
return false; |
*bufpos = 0; |
*buflen = block_size; |
} |
} |
return true; |
} |
/** @} |
*/ |
/branches/dynload/uspace/lib/libfs/libfs.h |
---|
69,6 → 69,9 |
extern void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *); |
extern bool libfs_blockread(int, void *, off_t *, size_t *, off_t *, void *, |
size_t, size_t); |
#endif |
/** @} |
/branches/dynload/uspace/lib/libc/include/getopt.h |
---|
0,0 → 1,71 |
/* $NetBSD: getopt.h,v 1.10.6.1 2008/05/18 12:30:09 yamt Exp $ */ |
/*- |
* Copyright (c) 2000 The NetBSD Foundation, Inc. |
* All rights reserved. |
* |
* This code is derived from software contributed to The NetBSD Foundation |
* by Dieter Baron and Thomas Klausner. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* |
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
/* Ported to HelenOS August 2008 by Tim Post <echo@echoreply.us> */ |
#ifndef _GETOPT_H_ |
#define _GETOPT_H_ |
#include <unistd.h> |
/* |
* Gnu like getopt_long() and BSD4.4 getsubopt()/optreset extensions |
*/ |
#define no_argument 0 |
#define required_argument 1 |
#define optional_argument 2 |
struct option { |
/* name of long option */ |
const char *name; |
/* |
* one of no_argument, required_argument, and optional_argument: |
* whether option takes an argument |
*/ |
int has_arg; |
/* if not NULL, set *flag to val when option found */ |
int *flag; |
/* if flag not NULL, value to set *flag to; else return value */ |
int val; |
}; |
/* HelenOS Port - These need to be exposed for legacy getopt() */ |
extern char *optarg; |
extern int optind, opterr, optopt; |
extern int optreset; |
int getopt_long(int, char * const *, const char *, |
const struct option *, int *); |
/* HelenOS Port : Expose legacy getopt() */ |
int getopt(int, char * const [], const char *); |
#endif /* !_GETOPT_H_ */ |
/branches/dynload/uspace/lib/libc/include/string.h |
---|
47,6 → 47,7 |
extern int strcmp(const char *, const char *); |
extern int strncmp(const char *, const char *, size_t); |
extern int stricmp(const char *, const char *); |
extern char *strcpy(char *, const char *); |
extern char *strncpy(char *, const char *, size_t); |
55,6 → 56,8 |
extern size_t strlen(const char *); |
extern char *strdup(const char *); |
extern char *strchr(const char *, int); |
extern char *strrchr(const char *, int); |
/branches/dynload/uspace/lib/libc/include/vfs/vfs.h |
---|
35,6 → 35,10 |
#ifndef LIBC_VFS_H_ |
#define LIBC_VFS_H_ |
#include <sys/types.h> |
extern char *absolutize(const char *, size_t *); |
extern int mount(const char *, const char *, const char *); |
#endif |
/branches/dynload/uspace/lib/libc/include/stdio.h |
---|
54,16 → 54,17 |
extern int getchar(void); |
extern int puts(const char * str); |
extern int putchar(int c); |
extern int puts(const char *); |
extern int putchar(int); |
extern int printf(const char *fmt, ...); |
extern int sprintf(char *str, const char *fmt, ...); |
extern int snprintf(char *str, size_t size, const char *fmt, ...); |
extern int printf(const char *, ...); |
extern int asprintf(char **, const char *, ...); |
extern int sprintf(char *, const char *fmt, ...); |
extern int snprintf(char *, size_t , const char *, ...); |
extern int vprintf(const char *fmt, va_list ap); |
extern int vsprintf(char *str, const char *fmt, va_list ap); |
extern int vsnprintf(char *str, size_t size, const char *fmt, va_list ap); |
extern int vprintf(const char *, va_list); |
extern int vsprintf(char *, const char *, va_list); |
extern int vsnprintf(char *, size_t, const char *, va_list); |
#define fprintf(f, fmt, ...) printf(fmt, ##__VA_ARGS__) |
/branches/dynload/uspace/lib/libc/include/ctype.h |
---|
76,6 → 76,14 |
} |
} |
static inline int tolower(int c) |
{ |
if (isupper(c)) |
return (c + ('a' - 'A' > 0 ? 'a' - 'A' : 'A' - 'a')); |
else |
return c; |
} |
#endif |
/** @} |
/branches/dynload/uspace/lib/libc/generic/task.c |
---|
41,6 → 41,7 |
#include <stdlib.h> |
#include <async.h> |
#include <errno.h> |
#include <vfs/vfs.h> |
task_id_t task_get_id(void) |
{ |
130,9 → 131,17 |
int rc; |
ipcarg_t retval; |
char *pa; |
size_t pa_len; |
pa = absolutize(path, &pa_len); |
if (!pa) |
return 0; |
/* Spawn a program loader */ |
phone_id = task_spawn_loader(); |
if (phone_id < 0) return 0; |
if (phone_id < 0) |
return 0; |
/* |
* Say hello so that the loader knows the incoming connection's |
139,11 → 148,12 |
* phone hash. |
*/ |
rc = async_req_0_0(phone_id, LOADER_HELLO); |
if (rc != EOK) return 0; |
if (rc != EOK) |
return 0; |
/* Send program pathname */ |
req = async_send_0(phone_id, LOADER_SET_PATHNAME, &answer); |
rc = ipc_data_write_start(phone_id, (void *)path, strlen(path)); |
rc = ipc_data_write_start(phone_id, (void *)pa, pa_len); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
return 1; |
150,15 → 160,18 |
} |
async_wait_for(req, &retval); |
if (retval != EOK) goto error; |
if (retval != EOK) |
goto error; |
/* Send arguments */ |
rc = loader_set_args(phone_id, argv); |
if (rc != EOK) goto error; |
if (rc != EOK) |
goto error; |
/* Request loader to start the program */ |
rc = async_req_0_0(phone_id, LOADER_RUN); |
if (rc != EOK) goto error; |
if (rc != EOK) |
goto error; |
/* Success */ |
ipc_hangup(phone_id); |
/branches/dynload/uspace/lib/libc/generic/getopt.c |
---|
0,0 → 1,478 |
/* $NetBSD: getopt_long.c,v 1.21.4.1 2008/01/09 01:34:14 matt Exp $ */ |
/*- |
* Copyright (c) 2000 The NetBSD Foundation, Inc. |
* All rights reserved. |
* |
* This code is derived from software contributed to The NetBSD Foundation |
* by Dieter Baron and Thomas Klausner. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* |
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
/* Ported to HelenOS August 2008 by Tim Post <echo@echoreply.us> */ |
#include <assert.h> |
#include <stdarg.h> |
#include <err.h> |
#include <errno.h> |
#include <getopt.h> |
#include <stdlib.h> |
#include <string.h> |
/* HelenOS Port : We're incorporating only the modern getopt_long with wrappers |
* to keep legacy getopt() usage from breaking. All references to REPLACE_GETOPT |
* are dropped, we just include the code */ |
int opterr = 1; /* if error message should be printed */ |
int optind = 1; /* index into parent argv vector */ |
int optopt = '?'; /* character checked for validity */ |
int optreset; /* reset getopt */ |
char *optarg; /* argument associated with option */ |
#define IGNORE_FIRST (*options == '-' || *options == '+') |
#define PRINT_ERROR ((opterr) && ((*options != ':') \ |
|| (IGNORE_FIRST && options[1] != ':'))) |
/*HelenOS Port - POSIXLY_CORRECT is always false */ |
#define IS_POSIXLY_CORRECT 0 |
#define PERMUTE (!IS_POSIXLY_CORRECT && !IGNORE_FIRST) |
/* XXX: GNU ignores PC if *options == '-' */ |
#define IN_ORDER (!IS_POSIXLY_CORRECT && *options == '-') |
/* return values */ |
#define BADCH (int)'?' |
#define BADARG ((IGNORE_FIRST && options[1] == ':') \ |
|| (*options == ':') ? (int)':' : (int)'?') |
#define INORDER (int)1 |
#define EMSG "" |
static int getopt_internal(int, char **, const char *); |
static int gcd(int, int); |
static void permute_args(int, int, int, char **); |
static const char *place = EMSG; /* option letter processing */ |
/* XXX: set optreset to 1 rather than these two */ |
static int nonopt_start = -1; /* first non option argument (for permute) */ |
static int nonopt_end = -1; /* first option after non options (for permute) */ |
/* Error messages */ |
/* HelenOS Port: Calls to warnx() were eliminated (as we have no stderr that |
* may be redirected) and replaced with printf. As such, error messages now |
* end in a newline */ |
static const char recargchar[] = "option requires an argument -- %c\n"; |
static const char recargstring[] = "option requires an argument -- %s\n"; |
static const char ambig[] = "ambiguous option -- %.*s\n"; |
static const char noarg[] = "option doesn't take an argument -- %.*s\n"; |
static const char illoptchar[] = "unknown option -- %c\n"; |
static const char illoptstring[] = "unknown option -- %s\n"; |
/* |
* Compute the greatest common divisor of a and b. |
*/ |
static int |
gcd(a, b) |
int a; |
int b; |
{ |
int c; |
c = a % b; |
while (c != 0) { |
a = b; |
b = c; |
c = a % b; |
} |
return b; |
} |
/* |
* Exchange the block from nonopt_start to nonopt_end with the block |
* from nonopt_end to opt_end (keeping the same order of arguments |
* in each block). |
*/ |
static void |
permute_args(panonopt_start, panonopt_end, opt_end, nargv) |
int panonopt_start; |
int panonopt_end; |
int opt_end; |
char **nargv; |
{ |
int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; |
char *swap; |
assert(nargv != NULL); |
/* |
* compute lengths of blocks and number and size of cycles |
*/ |
nnonopts = panonopt_end - panonopt_start; |
nopts = opt_end - panonopt_end; |
ncycle = gcd(nnonopts, nopts); |
cyclelen = (opt_end - panonopt_start) / ncycle; |
for (i = 0; i < ncycle; i++) { |
cstart = panonopt_end+i; |
pos = cstart; |
for (j = 0; j < cyclelen; j++) { |
if (pos >= panonopt_end) |
pos -= nnonopts; |
else |
pos += nopts; |
swap = nargv[pos]; |
nargv[pos] = nargv[cstart]; |
nargv[cstart] = swap; |
} |
} |
} |
/* |
* getopt_internal -- |
* Parse argc/argv argument vector. Called by user level routines. |
* Returns -2 if -- is found (can be long option or end of options marker). |
*/ |
static int |
getopt_internal(nargc, nargv, options) |
int nargc; |
char **nargv; |
const char *options; |
{ |
char *oli; /* option letter list index */ |
int optchar; |
assert(nargv != NULL); |
assert(options != NULL); |
optarg = NULL; |
/* |
* XXX Some programs (like rsyncd) expect to be able to |
* XXX re-initialize optind to 0 and have getopt_long(3) |
* XXX properly function again. Work around this braindamage. |
*/ |
if (optind == 0) |
optind = 1; |
if (optreset) |
nonopt_start = nonopt_end = -1; |
start: |
if (optreset || !*place) { /* update scanning pointer */ |
optreset = 0; |
if (optind >= nargc) { /* end of argument vector */ |
place = EMSG; |
if (nonopt_end != -1) { |
/* do permutation, if we have to */ |
permute_args(nonopt_start, nonopt_end, |
optind, nargv); |
optind -= nonopt_end - nonopt_start; |
} |
else if (nonopt_start != -1) { |
/* |
* If we skipped non-options, set optind |
* to the first of them. |
*/ |
optind = nonopt_start; |
} |
nonopt_start = nonopt_end = -1; |
return -1; |
} |
if ((*(place = nargv[optind]) != '-') |
|| (place[1] == '\0')) { /* found non-option */ |
place = EMSG; |
if (IN_ORDER) { |
/* |
* GNU extension: |
* return non-option as argument to option 1 |
*/ |
optarg = nargv[optind++]; |
return INORDER; |
} |
if (!PERMUTE) { |
/* |
* if no permutation wanted, stop parsing |
* at first non-option |
*/ |
return -1; |
} |
/* do permutation */ |
if (nonopt_start == -1) |
nonopt_start = optind; |
else if (nonopt_end != -1) { |
permute_args(nonopt_start, nonopt_end, |
optind, nargv); |
nonopt_start = optind - |
(nonopt_end - nonopt_start); |
nonopt_end = -1; |
} |
optind++; |
/* process next argument */ |
goto start; |
} |
if (nonopt_start != -1 && nonopt_end == -1) |
nonopt_end = optind; |
if (place[1] && *++place == '-') { /* found "--" */ |
place++; |
return -2; |
} |
} |
if ((optchar = (int)*place++) == (int)':' || |
(oli = strchr(options + (IGNORE_FIRST ? 1 : 0), optchar)) == NULL) { |
/* option letter unknown or ':' */ |
if (!*place) |
++optind; |
if (PRINT_ERROR) |
printf(illoptchar, optchar); |
optopt = optchar; |
return BADCH; |
} |
if (optchar == 'W' && oli[1] == ';') { /* -W long-option */ |
/* XXX: what if no long options provided (called by getopt)? */ |
if (*place) |
return -2; |
if (++optind >= nargc) { /* no arg */ |
place = EMSG; |
if (PRINT_ERROR) |
printf(recargchar, optchar); |
optopt = optchar; |
return BADARG; |
} else /* white space */ |
place = nargv[optind]; |
/* |
* Handle -W arg the same as --arg (which causes getopt to |
* stop parsing). |
*/ |
return -2; |
} |
if (*++oli != ':') { /* doesn't take argument */ |
if (!*place) |
++optind; |
} else { /* takes (optional) argument */ |
optarg = NULL; |
if (*place) /* no white space */ |
optarg = *place; |
/* XXX: disable test for :: if PC? (GNU doesn't) */ |
else if (oli[1] != ':') { /* arg not optional */ |
if (++optind >= nargc) { /* no arg */ |
place = EMSG; |
if (PRINT_ERROR) |
printf(recargchar, optchar); |
optopt = optchar; |
return BADARG; |
} else |
optarg = nargv[optind]; |
} |
place = EMSG; |
++optind; |
} |
/* dump back option letter */ |
return optchar; |
} |
/* |
* getopt -- |
* Parse argc/argv argument vector. |
*/ |
int |
getopt(nargc, nargv, options) |
int nargc; |
char * const *nargv; |
const char *options; |
{ |
int retval; |
assert(nargv != NULL); |
assert(options != NULL); |
retval = getopt_internal(nargc, (char **)nargv, options); |
if (retval == -2) { |
++optind; |
/* |
* We found an option (--), so if we skipped non-options, |
* we have to permute. |
*/ |
if (nonopt_end != -1) { |
permute_args(nonopt_start, nonopt_end, optind, |
(char **)nargv); |
optind -= nonopt_end - nonopt_start; |
} |
nonopt_start = nonopt_end = -1; |
retval = -1; |
} |
return retval; |
} |
/* |
* getopt_long -- |
* Parse argc/argv argument vector. |
*/ |
int |
getopt_long(nargc, nargv, options, long_options, idx) |
int nargc; |
char * const *nargv; |
const char *options; |
const struct option *long_options; |
int *idx; |
{ |
int retval; |
#define IDENTICAL_INTERPRETATION(_x, _y) \ |
(long_options[(_x)].has_arg == long_options[(_y)].has_arg && \ |
long_options[(_x)].flag == long_options[(_y)].flag && \ |
long_options[(_x)].val == long_options[(_y)].val) |
assert(nargv != NULL); |
assert(options != NULL); |
assert(long_options != NULL); |
/* idx may be NULL */ |
retval = getopt_internal(nargc, (char **)nargv, options); |
if (retval == -2) { |
char *current_argv, *has_equal; |
size_t current_argv_len; |
int i, ambiguous, match; |
current_argv = (char *)place; |
match = -1; |
ambiguous = 0; |
optind++; |
place = EMSG; |
if (*current_argv == '\0') { /* found "--" */ |
/* |
* We found an option (--), so if we skipped |
* non-options, we have to permute. |
*/ |
if (nonopt_end != -1) { |
permute_args(nonopt_start, nonopt_end, |
optind, (char **)nargv); |
optind -= nonopt_end - nonopt_start; |
} |
nonopt_start = nonopt_end = -1; |
return -1; |
} |
if ((has_equal = strchr(current_argv, '=')) != NULL) { |
/* argument found (--option=arg) */ |
current_argv_len = has_equal - current_argv; |
has_equal++; |
} else |
current_argv_len = strlen(current_argv); |
for (i = 0; long_options[i].name; i++) { |
/* find matching long option */ |
if (strncmp(current_argv, long_options[i].name, |
current_argv_len)) |
continue; |
if (strlen(long_options[i].name) == |
(unsigned)current_argv_len) { |
/* exact match */ |
match = i; |
ambiguous = 0; |
break; |
} |
if (match == -1) /* partial match */ |
match = i; |
else if (!IDENTICAL_INTERPRETATION(i, match)) |
ambiguous = 1; |
} |
if (ambiguous) { |
/* ambiguous abbreviation */ |
if (PRINT_ERROR) |
printf(ambig, (int)current_argv_len, |
current_argv); |
optopt = 0; |
return BADCH; |
} |
if (match != -1) { /* option found */ |
if (long_options[match].has_arg == no_argument |
&& has_equal) { |
if (PRINT_ERROR) |
printf(noarg, (int)current_argv_len, |
current_argv); |
/* |
* XXX: GNU sets optopt to val regardless of |
* flag |
*/ |
if (long_options[match].flag == NULL) |
optopt = long_options[match].val; |
else |
optopt = 0; |
return BADARG; |
} |
if (long_options[match].has_arg == required_argument || |
long_options[match].has_arg == optional_argument) { |
if (has_equal) |
optarg = has_equal; |
else if (long_options[match].has_arg == |
required_argument) { |
/* |
* optional argument doesn't use |
* next nargv |
*/ |
optarg = nargv[optind++]; |
} |
} |
if ((long_options[match].has_arg == required_argument) |
&& (optarg == NULL)) { |
/* |
* Missing argument; leading ':' |
* indicates no error should be generated |
*/ |
if (PRINT_ERROR) |
printf(recargstring, current_argv); |
/* |
* XXX: GNU sets optopt to val regardless |
* of flag |
*/ |
if (long_options[match].flag == NULL) |
optopt = long_options[match].val; |
else |
optopt = 0; |
--optind; |
return BADARG; |
} |
} else { /* unknown option */ |
if (PRINT_ERROR) |
printf(illoptstring, current_argv); |
optopt = 0; |
return BADCH; |
} |
if (long_options[match].flag) { |
*long_options[match].flag = long_options[match].val; |
retval = 0; |
} else |
retval = long_options[match].val; |
if (idx) |
*idx = match; |
} |
return retval; |
#undef IDENTICAL_INTERPRETATION |
} |
/branches/dynload/uspace/lib/libc/generic/string.c |
---|
38,8 → 38,8 |
#include <limits.h> |
#include <align.h> |
#include <sys/types.h> |
#include <malloc.h> |
/* Dummy implementation of mem/ functions */ |
void *memset(void *s, int c, size_t n) |
66,9 → 66,10 |
adst[i].n = asrc[i].n; |
for (j = 0; j < n % sizeof(unsigned long); j++) |
((unsigned char *) (((unsigned long *) dst) + i))[j] = ((unsigned char *) (((unsigned long *) src) + i))[j]; |
((unsigned char *) (((unsigned long *) dst) + i))[j] = |
((unsigned char *) (((unsigned long *) src) + i))[j]; |
return (char *) src; |
return (char *) dst; |
} |
void *memcpy(void *dst, const void *src, size_t n) |
75,7 → 76,8 |
{ |
int i, j; |
if (((long) dst & (sizeof(long) - 1)) || ((long) src & (sizeof(long) - 1))) |
if (((long) dst & (sizeof(long) - 1)) || |
((long) src & (sizeof(long) - 1))) |
return unaligned_memcpy(dst, src, n); |
for (i = 0; i < n / sizeof(unsigned long); i++) |
82,9 → 84,10 |
((unsigned long *) dst)[i] = ((unsigned long *) src)[i]; |
for (j = 0; j < n % sizeof(unsigned long); j++) |
((unsigned char *) (((unsigned long *) dst) + i))[j] = ((unsigned char *) (((unsigned long *) src) + i))[j]; |
((unsigned char *) (((unsigned long *) dst) + i))[j] = |
((unsigned char *) (((unsigned long *) src) + i))[j]; |
return (char *) src; |
return (char *) dst; |
} |
void *memmove(void *dst, const void *src, size_t n) |
95,22 → 98,23 |
return memcpy(dst, src, n); |
for (j = (n % sizeof(unsigned long)) - 1; j >= 0; j--) |
((unsigned char *) ((unsigned long *) dst))[j] = ((unsigned char *) ((unsigned long *) src))[j]; |
((unsigned char *) ((unsigned long *) dst))[j] = |
((unsigned char *) ((unsigned long *) src))[j]; |
for (i = n / sizeof(unsigned long) - 1; i >=0 ; i--) |
((unsigned long *) dst)[i] = ((unsigned long *) src)[i]; |
return (char *) src; |
return (char *) dst; |
} |
/** Compare two memory areas. |
* |
* @param s1 Pointer to the first area to compare. |
* @param s2 Pointer to the second area to compare. |
* @param len Size of the first area in bytes. Both areas must have the same |
* length. |
* @return If len is 0, return zero. If the areas match, return zero. |
* Otherwise return non-zero. |
* @param s1 Pointer to the first area to compare. |
* @param s2 Pointer to the second area to compare. |
* @param len Size of the first area in bytes. Both areas must have |
* the same length. |
* @return If len is 0, return zero. If the areas match, return |
* zero. Otherwise return non-zero. |
*/ |
int bcmp(const char *s1, const char *s2, size_t len) |
{ |
120,8 → 124,9 |
} |
/** Count the number of characters in the string, not including terminating 0. |
* @param str string |
* @return number of characters in string. |
* |
* @param str String. |
* @return Number of characters in string. |
*/ |
size_t strlen(const char *str) |
{ |
141,7 → 146,6 |
c++; |
return (a[c] - b[c]); |
} |
int strncmp(const char *a, const char *b, size_t n) |
155,10 → 159,22 |
} |
/** Return pointer to the first occurence of character c in string |
* @param str scanned string |
* @param c searched character (taken as one byte) |
* @return pointer to the matched character or NULL if it is not found in given string. |
int stricmp(const char *a, const char *b) |
{ |
int c = 0; |
while (a[c] && b[c] && (!(tolower(a[c]) - tolower(b[c])))) |
c++; |
return (tolower(a[c]) - tolower(b[c])); |
} |
/** Return pointer to the first occurence of character c in string. |
* |
* @param str Scanned string. |
* @param c Searched character (taken as one byte). |
* @return Pointer to the matched character or NULL if it is not |
* found in given string. |
*/ |
char *strchr(const char *str, int c) |
{ |
171,10 → 187,12 |
return NULL; |
} |
/** Return pointer to the last occurence of character c in string |
* @param str scanned string |
* @param c searched character (taken as one byte) |
* @return pointer to the matched character or NULL if it is not found in given string. |
/** Return pointer to the last occurence of character c in string. |
* |
* @param str Scanned string. |
* @param c Searched character (taken as one byte). |
* @return Pointer to the matched character or NULL if it is not |
* found in given string. |
*/ |
char *strrchr(const char *str, int c) |
{ |
191,13 → 209,16 |
/** Convert string to a number. |
* Core of strtol and strtoul functions. |
* @param nptr pointer to string |
* @param endptr if not NULL, function stores here pointer to the first invalid character |
* @param base zero or number between 2 and 36 inclusive |
* @param sgn its set to 1 if minus found |
* @return result of conversion. |
* |
* @param nptr Pointer to string. |
* @param endptr If not NULL, function stores here pointer to the first |
* invalid character. |
* @param base Zero or number between 2 and 36 inclusive. |
* @param sgn It's set to 1 if minus found. |
* @return Result of conversion. |
*/ |
static unsigned long _strtoul(const char *nptr, char **endptr, int base, char *sgn) |
static unsigned long |
_strtoul(const char *nptr, char **endptr, int base, char *sgn) |
{ |
unsigned char c; |
unsigned long result = 0; |
219,7 → 240,8 |
/* FIXME: set errno to EINVAL */ |
return 0; |
} |
if ((base == 16) && (*str == '0') && ((str[1] == 'x') || (str[1] == 'X'))) { |
if ((base == 16) && (*str == '0') && ((str[1] == 'x') || |
(str[1] == 'X'))) { |
str += 2; |
} |
} else { |
238,7 → 260,8 |
while (*str) { |
c = *str; |
c = (c >= 'a' ? c - 'a' + 10 : (c >= 'A' ? c - 'A' + 10 : (c <= '9' ? c - '0' : 0xff))); |
c = (c >= 'a' ? c - 'a' + 10 : (c >= 'A' ? c - 'A' + 10 : |
(c <= '9' ? c - '0' : 0xff))); |
if (c > base) { |
break; |
} |
257,7 → 280,10 |
} |
if (str == tmpptr) { |
/* no number was found => first invalid character is the first character of the string */ |
/* |
* No number was found => first invalid character is the first |
* character of the string. |
*/ |
/* FIXME: set errno to EINVAL */ |
str = nptr; |
result = 0; |
275,14 → 301,17 |
} |
/** Convert initial part of string to long int according to given base. |
* The number may begin with an arbitrary number of whitespaces followed by optional sign (`+' or `-'). |
* If the base is 0 or 16, the prefix `0x' may be inserted and the number will be taken as hexadecimal one. |
* If the base is 0 and the number begin with a zero, number will be taken as octal one (as with base 8). |
* Otherwise the base 0 is taken as decimal. |
* @param nptr pointer to string |
* @param endptr if not NULL, function stores here pointer to the first invalid character |
* @param base zero or number between 2 and 36 inclusive |
* @return result of conversion. |
* The number may begin with an arbitrary number of whitespaces followed by |
* optional sign (`+' or `-'). If the base is 0 or 16, the prefix `0x' may be |
* inserted and the number will be taken as hexadecimal one. If the base is 0 |
* and the number begin with a zero, number will be taken as octal one (as with |
* base 8). Otherwise the base 0 is taken as decimal. |
* |
* @param nptr Pointer to string. |
* @param endptr If not NULL, function stores here pointer to the first |
* invalid character. |
* @param base Zero or number between 2 and 36 inclusive. |
* @return Result of conversion. |
*/ |
long int strtol(const char *nptr, char **endptr, int base) |
{ |
305,14 → 334,17 |
/** Convert initial part of string to unsigned long according to given base. |
* The number may begin with an arbitrary number of whitespaces followed by optional sign (`+' or `-'). |
* If the base is 0 or 16, the prefix `0x' may be inserted and the number will be taken as hexadecimal one. |
* If the base is 0 and the number begin with a zero, number will be taken as octal one (as with base 8). |
* Otherwise the base 0 is taken as decimal. |
* @param nptr pointer to string |
* @param endptr if not NULL, function stores here pointer to the first invalid character |
* @param base zero or number between 2 and 36 inclusive |
* @return result of conversion. |
* The number may begin with an arbitrary number of whitespaces followed by |
* optional sign (`+' or `-'). If the base is 0 or 16, the prefix `0x' may be |
* inserted and the number will be taken as hexadecimal one. If the base is 0 |
* and the number begin with a zero, number will be taken as octal one (as with |
* base 8). Otherwise the base 0 is taken as decimal. |
* |
* @param nptr Pointer to string. |
* @param endptr If not NULL, function stores here pointer to the first |
* invalid character |
* @param base Zero or number between 2 and 36 inclusive. |
* @return Result of conversion. |
*/ |
unsigned long strtoul(const char *nptr, char **endptr, int base) |
{ |
353,5 → 385,16 |
return orig; |
} |
char * strdup(const char *s1) |
{ |
size_t len = strlen(s1) + 1; |
void *ret = malloc(len); |
if (ret == NULL) |
return (char *) NULL; |
return (char *) memcpy(ret, s1, len); |
} |
/** @} |
*/ |
/branches/dynload/uspace/lib/libc/generic/ipc.c |
---|
682,7 → 682,7 |
{ |
int res; |
sysarg_t tmp_flags; |
res = ipc_call_sync_3_2(phoneid, IPC_M_SHARE_IN, (ipcarg_t) dst, |
res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (ipcarg_t) dst, |
(ipcarg_t) size, arg, NULL, &tmp_flags); |
if (flags) |
*flags = tmp_flags; |
742,7 → 742,7 |
*/ |
int ipc_share_out_start(int phoneid, void *src, int flags) |
{ |
return ipc_call_sync_3_0(phoneid, IPC_M_SHARE_OUT, (ipcarg_t) src, 0, |
return async_req_3_0(phoneid, IPC_M_SHARE_OUT, (ipcarg_t) src, 0, |
(ipcarg_t) flags); |
} |
803,7 → 803,7 |
*/ |
int ipc_data_read_start(int phoneid, void *dst, size_t size) |
{ |
return ipc_call_sync_2_0(phoneid, IPC_M_DATA_READ, (ipcarg_t) dst, |
return async_req_2_0(phoneid, IPC_M_DATA_READ, (ipcarg_t) dst, |
(ipcarg_t) size); |
} |
862,7 → 862,7 |
*/ |
int ipc_data_write_start(int phoneid, void *src, size_t size) |
{ |
return ipc_call_sync_2_0(phoneid, IPC_M_DATA_WRITE, (ipcarg_t) src, |
return async_req_2_0(phoneid, IPC_M_DATA_WRITE, (ipcarg_t) src, |
(ipcarg_t) size); |
} |
/branches/dynload/uspace/lib/libc/generic/vfs/vfs.c |
---|
59,9 → 59,10 |
char *cwd_path = NULL; |
size_t cwd_len = 0; |
static char *absolutize(const char *path, size_t *retlen) |
char *absolutize(const char *path, size_t *retlen) |
{ |
char *ncwd_path; |
char *ncwd_path_nc; |
futex_down(&cwd_futex); |
size_t len = strlen(path); |
70,28 → 71,40 |
futex_up(&cwd_futex); |
return NULL; |
} |
ncwd_path = malloc(len + cwd_len + 1); |
if (!ncwd_path) { |
ncwd_path_nc = malloc(cwd_len + 1 + len + 1); |
if (!ncwd_path_nc) { |
futex_up(&cwd_futex); |
return NULL; |
} |
strcpy(ncwd_path, cwd_path); |
ncwd_path[cwd_len] = '/'; |
ncwd_path[cwd_len + 1] = '\0'; |
strcpy(ncwd_path_nc, cwd_path); |
ncwd_path_nc[cwd_len] = '/'; |
ncwd_path_nc[cwd_len + 1] = '\0'; |
} else { |
ncwd_path = malloc(len + 1); |
if (!ncwd_path) { |
ncwd_path_nc = malloc(len + 1); |
if (!ncwd_path_nc) { |
futex_up(&cwd_futex); |
return NULL; |
} |
ncwd_path[0] = '\0'; |
ncwd_path_nc[0] = '\0'; |
} |
strcat(ncwd_path, path); |
if (!canonify(ncwd_path, retlen)) { |
strcat(ncwd_path_nc, path); |
ncwd_path = canonify(ncwd_path_nc, retlen); |
if (!ncwd_path) { |
futex_up(&cwd_futex); |
free(ncwd_path); |
free(ncwd_path_nc); |
return NULL; |
} |
/* |
* We need to clone ncwd_path because canonify() works in-place and thus |
* the address in ncwd_path need not be the same as ncwd_path_nc, even |
* though they both point into the same dynamically allocated buffer. |
*/ |
ncwd_path = strdup(ncwd_path); |
free(ncwd_path_nc); |
if (!ncwd_path) { |
futex_up(&cwd_futex); |
return NULL; |
} |
futex_up(&cwd_futex); |
return ncwd_path; |
} |
105,7 → 118,8 |
static int device_get_handle(char *name, dev_handle_t *handle) |
{ |
int phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, DEVMAP_CLIENT, 0); |
int phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, DEVMAP_CLIENT, |
0); |
if (phone < 0) |
return phone; |
171,6 → 185,15 |
free(mpa); |
return (int) rc; |
} |
/* Ask VFS whether it likes fs_name. */ |
rc = async_req_0_0(vfs_phone, IPC_M_PING); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(mpa); |
return (int) rc; |
} |
rc = ipc_data_write_start(vfs_phone, (void *)mpa, mpa_len); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
223,7 → 246,8 |
futex_up(&vfs_phone_futex); |
free(pa); |
if (rc != EOK) return (int) rc; |
if (rc != EOK) |
return (int) rc; |
return (int) IPC_GET_ARG1(answer); |
} |
287,7 → 311,7 |
if (rc == EOK) |
return (ssize_t) IPC_GET_ARG1(answer); |
else |
return -1; |
return rc; |
} |
ssize_t write(int fildes, const void *buf, size_t nbyte) |
/branches/dynload/uspace/lib/libc/generic/vfs/canonify.c |
---|
125,6 → 125,7 |
static void set_first_slash(token_t *t, token_t *tfsl, token_t *tlcomp) |
{ |
*tfsl = *t; |
*tlcomp = *t; |
} |
static void save_component(token_t *t, token_t *tfsl, token_t *tlcomp) |
{ |
/branches/dynload/uspace/lib/libc/generic/io/sprintf.c |
---|
48,7 → 48,6 |
va_start(args, fmt); |
ret = vsprintf(str, fmt, args); |
va_end(args); |
return ret; |
/branches/dynload/uspace/lib/libc/generic/io/asprintf.c |
---|
0,0 → 1,79 |
/* |
* Copyright (c) 2006 Josef Cejka |
* Copyright (c) 2008 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libc |
* @{ |
*/ |
/** @file |
*/ |
#include <stdarg.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <io/printf_core.h> |
static int asprintf_prewrite(const char *str, size_t count, void *unused) |
{ |
return count; |
} |
/** Allocate and print to string. |
* |
* @param strp Address of the pointer where to store the address of |
* the newly allocated string. |
* @fmt Format strin. |
* |
* @return Number of characters printed or a negative error code. |
*/ |
int asprintf(char **strp, const char *fmt, ...) |
{ |
struct printf_spec ps = { |
asprintf_prewrite, |
NULL |
}; |
int ret; |
va_list args; |
va_start(args, fmt); |
ret = printf_core(fmt, &ps, args); |
va_end(args); |
if (ret > 0) { |
*strp = malloc(ret + 20); |
if (!*strp) |
return -1; |
va_start(args, fmt); |
vsprintf(*strp, fmt, args); |
va_end(args); |
} |
return ret; |
} |
/** @} |
*/ |
/branches/dynload/uspace/lib/libc/generic/io/vsnprintf.c |
---|
38,22 → 38,27 |
#include <io/printf_core.h> |
struct vsnprintf_data { |
size_t size; /* total space for string */ |
size_t len; /* count of currently used characters */ |
char *string; /* destination string */ |
size_t size; /* total space for string */ |
size_t len; /* count of currently used characters */ |
char *string; /* destination string */ |
}; |
/** Write string to given buffer. |
* Write at most data->size characters including trailing zero. According to C99 has snprintf to return number |
* of characters that would have been written if enough space had been available. Hence the return value is not |
* number of really printed characters but size of input string. Number of really used characters |
* is stored in data->len. |
* @param str source string to print |
* @param count size of source string |
* @param data structure with destination string, counter of used space and total string size. |
* @return number of characters to print (not characters really printed!) |
* Write at most data->size characters including trailing zero. According to C99 |
* has snprintf to return number of characters that would have been written if |
* enough space had been available. Hence the return value is not number of |
* really printed characters but size of input string. Number of really used |
* characters is stored in data->len. |
* |
* @param str Source string to print. |
* @param count Size of the source string. |
* @param data Structure with destination string, counter of used space |
* and total string size. |
* @return Number of characters to print (not characters really |
* printed!) |
*/ |
static int vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data) |
static int |
vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data) |
{ |
size_t i; |
i = data->size - data->len; |
63,7 → 68,10 |
} |
if (i == 1) { |
/* We have only one free byte left in buffer => write there trailing zero */ |
/* |
* We have only one free byte left in buffer => write there |
* trailing zero. |
*/ |
data->string[data->size - 1] = 0; |
data->len = data->size; |
return count; |
70,17 → 78,23 |
} |
if (i <= count) { |
/* We have not enought space for whole string with the trailing zero => print only a part of string */ |
memcpy((void *)(data->string + data->len), (void *)str, i - 1); |
data->string[data->size - 1] = 0; |
data->len = data->size; |
return count; |
/* |
* We have not enought space for whole string with the trailing |
* zero => print only a part of string. |
*/ |
memcpy((void *)(data->string + data->len), (void *)str, i - 1); |
data->string[data->size - 1] = 0; |
data->len = data->size; |
return count; |
} |
/* Buffer is big enought to print whole string */ |
memcpy((void *)(data->string + data->len), (void *)str, count); |
data->len += count; |
/* Put trailing zero at end, but not count it into data->len so it could be rewritten next time */ |
/* |
* Put trailing zero at end, but not count it into data->len so it could |
* be rewritten next time. |
*/ |
data->string[data->len] = 0; |
return count; |
87,17 → 101,22 |
} |
/** Print formatted to the given buffer with limited size. |
* @param str buffer |
* @param size buffer size |
* @param fmt format string |
* @param str Buffer. |
* @param size Bffer size. |
* @param fmt Format string. |
* \see For more details about format string see printf_core. |
*/ |
int vsnprintf(char *str, size_t size, const char *fmt, va_list ap) |
{ |
struct vsnprintf_data data = {size, 0, str}; |
struct printf_spec ps = {(int(*)(void *, size_t, void *)) vsnprintf_write, &data}; |
struct printf_spec ps = { |
(int(*)(void *, size_t, void *)) vsnprintf_write, |
&data |
}; |
/* Print 0 at end of string - fix the case that nothing will be printed */ |
/* |
* Print 0 at end of string - fix the case that nothing will be printed. |
*/ |
if (size > 0) |
str[0] = 0; |
/branches/dynload/uspace/lib/libc/generic/io/printf_core.c |
---|
94,12 → 94,9 |
if (str == NULL) |
return printf_putnchars("(NULL)", 6, ps); |
for (count = 0; str[count] != 0; count++); |
count = strlen(str); |
if (ps->write((void *) str, count, ps->data) == count) |
return 0; |
return EOF; |
return ps->write((void *) str, count, ps->data); |
} |
/** Print one character to output |
/branches/dynload/uspace/lib/libc/Makefile |
---|
59,6 → 59,7 |
generic/tls.c \ |
generic/task.c \ |
generic/futex.c \ |
generic/io/asprintf.c \ |
generic/io/io.c \ |
generic/io/printf.c \ |
generic/io/stream.c \ |
72,6 → 73,7 |
generic/sysinfo.c \ |
generic/ipc.c \ |
generic/async.c \ |
generic/getopt.c \ |
generic/libadt/list.o \ |
generic/libadt/hash_table.o \ |
generic/time.c \ |
/branches/dynload/uspace/lib/libc/arch/sparc64/include/config.h |
---|
37,7 → 37,6 |
#define PAGE_WIDTH 14 |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#define PAGE_COLOR_BITS 0 /**< Only one page color. */ |
#endif |
/branches/dynload/uspace/lib/libc/arch/sparc64/Makefile.inc |
---|
29,8 → 29,12 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = sparc64-linux-gnu |
TOOLCHAIN_DIR = /usr/local/sparc64/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/sparc64/bin |
ARCH_SOURCES += arch/$(ARCH)/src/fibril.S \ |
arch/$(ARCH)/src/tls.c |
/branches/dynload/uspace/lib/libc/arch/ia64/include/config.h |
---|
36,8 → 36,7 |
#define LIBC_ia64_CONFIG_H_ |
#define PAGE_WIDTH 14 |
#define PAGE_SIZE (1<<PAGE_WIDTH) |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#endif |
/branches/dynload/uspace/lib/libc/arch/ia64/Makefile.inc |
---|
29,8 → 29,12 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = ia64-pc-linux-gnu |
TOOLCHAIN_DIR = /usr/local/ia64/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ia64/bin |
CFLAGS += -fno-unwind-tables -DMALLOC_ALIGNMENT_16 |
LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a |
AFLAGS += |
/branches/dynload/uspace/lib/libc/arch/arm32/include/config.h |
---|
38,7 → 38,6 |
#define PAGE_WIDTH 12 |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#endif |
/branches/dynload/uspace/lib/libc/arch/arm32/Makefile.inc |
---|
30,8 → 30,12 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = arm-linux-gnu |
TOOLCHAIN_DIR = /usr/local/arm/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm/bin |
CFLAGS += -ffixed-r9 -mtp=soft |
LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a |
AFLAGS += |
/branches/dynload/uspace/lib/libc/arch/mips32eb/Makefile.inc |
---|
29,8 → 29,12 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = mips-sgi-irix5 |
TOOLCHAIN_DIR = /usr/local/mips/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips/bin |
CFLAGS += -mips3 |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \ |
/branches/dynload/uspace/lib/libc/arch/ppc32/include/config.h |
---|
36,8 → 36,7 |
#define LIBC_ppc32_CONFIG_H_ |
#define PAGE_WIDTH 12 |
#define PAGE_SIZE (1<<PAGE_WIDTH) |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#endif |
/branches/dynload/uspace/lib/libc/arch/ppc32/Makefile.inc |
---|
29,8 → 29,12 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = ppc-linux-gnu |
TOOLCHAIN_DIR = /usr/local/ppc/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc/bin |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \ |
arch/$(ARCH)/src/fibril.S \ |
/branches/dynload/uspace/lib/libc/arch/amd64/include/config.h |
---|
36,8 → 36,7 |
#define LIBC_amd64_CONFIG_H_ |
#define PAGE_WIDTH 12 |
#define PAGE_SIZE (1<<PAGE_WIDTH) |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#endif |
/branches/dynload/uspace/lib/libc/arch/amd64/Makefile.inc |
---|
29,8 → 29,12 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = amd64-linux-gnu |
TOOLCHAIN_DIR = /usr/local/amd64/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/amd64/bin |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.S \ |
arch/$(ARCH)/src/fibril.S \ |
/branches/dynload/uspace/lib/libc/arch/ppc64/include/config.h |
---|
36,8 → 36,7 |
#define LIBC_ppc64_CONFIG_H_ |
#define PAGE_WIDTH 12 |
#define PAGE_SIZE (1<<PAGE_WIDTH) |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#endif |
/branches/dynload/uspace/lib/libc/arch/ppc64/Makefile.inc |
---|
29,8 → 29,12 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = ppc64-linux-gnu |
TOOLCHAIN_DIR = /usr/local/ppc64/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc64/bin |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \ |
arch/$(ARCH)/src/fibril.S \ |
/branches/dynload/uspace/lib/libc/arch/mips32/include/config.h |
---|
36,8 → 36,7 |
#define LIBC_mips32_CONFIG_H_ |
#define PAGE_WIDTH 14 |
#define PAGE_SIZE (1<<PAGE_WIDTH) |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#endif |
/branches/dynload/uspace/lib/libc/arch/mips32/Makefile.inc |
---|
29,8 → 29,12 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = mipsel-linux-gnu |
TOOLCHAIN_DIR = /usr/local/mipsel/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mipsel/bin |
CFLAGS += -mips3 |
-include ../../Makefile.config |
/branches/dynload/uspace/lib/libc/arch/ia32/include/config.h |
---|
37,7 → 37,6 |
#define PAGE_WIDTH 12 |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#endif |
/branches/dynload/uspace/lib/libc/arch/ia32/Makefile.inc |
---|
29,8 → 29,12 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = i686-pc-linux-gnu |
TOOLCHAIN_DIR = /usr/local/i686/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/i686/bin |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.S \ |
arch/$(ARCH)/src/fibril.S \ |
/branches/dynload/uspace/srv/rd/rd.c |
---|
81,46 → 81,24 |
ipc_call_t call; |
int retval; |
void *fs_va = NULL; |
ipcarg_t offset; |
off_t offset; |
size_t block_size; |
size_t maxblock_size; |
/* |
* We allocate VA for communication per connection. |
* This allows us to potentionally have more clients and work |
* concurrently. |
* Answer the first IPC_M_CONNECT_ME_TO call. |
*/ |
fs_va = as_get_mappable_page(ALIGN_UP(BLOCK_SIZE, PAGE_SIZE)); |
if (!fs_va) { |
/* |
* Hang up the phone if we cannot proceed any further. |
* This is the answer to the call that opened the connection. |
*/ |
ipc_answer_0(iid, EHANGUP); |
return; |
} else { |
/* |
* Answer the first IPC_M_CONNECT_ME_TO call. |
* Return supported block size as ARG1. |
*/ |
ipc_answer_1(iid, EOK, BLOCK_SIZE); |
} |
ipc_answer_0(iid, EOK); |
/* |
* Now we wait for the client to send us its communication as_area. |
*/ |
size_t size; |
int flags; |
if (ipc_share_out_receive(&callid, &size, &flags)) { |
if (size >= BLOCK_SIZE) { |
/* |
* The client sends an as_area that can absorb the whole |
* block. |
*/ |
if (ipc_share_out_receive(&callid, &maxblock_size, &flags)) { |
fs_va = as_get_mappable_page(maxblock_size); |
if (fs_va) { |
(void) ipc_share_out_finalize(callid, fs_va); |
} else { |
/* |
* The client offered as_area too small. |
* Close the connection. |
*/ |
ipc_answer_0(callid, EHANGUP); |
return; |
} |
146,8 → 124,16 |
return; |
case RD_READ_BLOCK: |
offset = IPC_GET_ARG1(call); |
if (offset * BLOCK_SIZE > rd_size - BLOCK_SIZE) { |
block_size = IPC_GET_ARG2(call); |
if (block_size > maxblock_size) { |
/* |
* Maximum block size exceeded. |
*/ |
retval = ELIMIT; |
break; |
} |
if (offset * block_size > rd_size - block_size) { |
/* |
* Reading past the end of the device. |
*/ |
retval = ELIMIT; |
154,14 → 140,22 |
break; |
} |
futex_down(&rd_futex); |
memcpy(fs_va, rd_addr + offset * BLOCK_SIZE, BLOCK_SIZE); |
memcpy(fs_va, rd_addr + offset * block_size, block_size); |
futex_up(&rd_futex); |
retval = EOK; |
break; |
case RD_WRITE_BLOCK: |
offset = IPC_GET_ARG1(call); |
if (offset * BLOCK_SIZE > rd_size - BLOCK_SIZE) { |
block_size = IPC_GET_ARG2(call); |
if (block_size > maxblock_size) { |
/* |
* Maximum block size exceeded. |
*/ |
retval = ELIMIT; |
break; |
} |
if (offset * block_size > rd_size - block_size) { |
/* |
* Writing past the end of the device. |
*/ |
retval = ELIMIT; |
168,7 → 162,7 |
break; |
} |
futex_up(&rd_futex); |
memcpy(rd_addr + offset * BLOCK_SIZE, fs_va, BLOCK_SIZE); |
memcpy(rd_addr + offset * block_size, fs_va, block_size); |
futex_down(&rd_futex); |
retval = EOK; |
break; |
/branches/dynload/uspace/srv/rd/rd.h |
---|
43,8 → 43,6 |
#ifndef RD_RD_H_ |
#define RD_RD_H_ |
#define BLOCK_SIZE 1024 /**< Working block size */ |
#define RD_BASE 1024 |
#define RD_READ_BLOCK (RD_BASE + 1) /**< Method for reading block. */ |
#define RD_WRITE_BLOCK (RD_BASE + 2) /**< Method for writing block. */ |
/branches/dynload/uspace/srv/loader/elf_load.c |
---|
71,6 → 71,19 |
static int section_header(elf_ld_t *elf, elf_section_header_t *entry); |
static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry); |
/** Read until the buffer is read in its entirety. */ |
static int my_read(int fd, char *buf, size_t len) |
{ |
int cnt = 0; |
do { |
buf += cnt; |
len -= cnt; |
cnt = read(fd, buf, len); |
} while ((cnt > 0) && ((len - cnt) > 0)); |
return cnt; |
} |
/** Load ELF binary from a file. |
* |
* Load an ELF binary from the specified file. If the file is |
156,7 → 169,7 |
elf_header_t *header = &header_buf; |
int i, rc; |
rc = read(elf->fd, header, sizeof(elf_header_t)); |
rc = my_read(elf->fd, header, sizeof(elf_header_t)); |
if (rc < 0) { |
printf("read error\n"); |
return EE_INVALID; |
223,8 → 236,12 |
lseek(elf->fd, header->e_phoff |
+ i * sizeof(elf_segment_header_t), SEEK_SET); |
rc = read(elf->fd, &segment_hdr, sizeof(elf_segment_header_t)); |
if (rc < 0) { printf("read error\n"); return EE_INVALID; } |
rc = my_read(elf->fd, &segment_hdr, |
sizeof(elf_segment_header_t)); |
if (rc < 0) { |
printf("read error\n"); |
return EE_INVALID; |
} |
rc = segment_header(elf, &segment_hdr); |
if (rc != EE_OK) |
241,8 → 258,12 |
lseek(elf->fd, header->e_shoff |
+ i * sizeof(elf_section_header_t), SEEK_SET); |
rc = read(elf->fd, §ion_hdr, sizeof(elf_section_header_t)); |
if (rc < 0) { printf("read error\n"); return EE_INVALID; } |
rc = my_read(elf->fd, §ion_hdr, |
sizeof(elf_section_header_t)); |
if (rc < 0) { |
printf("read error\n"); |
return EE_INVALID; |
} |
rc = section_header(elf, §ion_hdr); |
if (rc != EE_OK) |
326,9 → 347,10 |
if (entry->p_align > 1) { |
if ((entry->p_offset % entry->p_align) != |
(entry->p_vaddr % entry->p_align)) { |
printf("align check 1 failed offset%%align=%d, vaddr%%align=%d\n", |
entry->p_offset % entry->p_align, |
entry->p_vaddr % entry->p_align |
printf("align check 1 failed offset%%align=%d, " |
"vaddr%%align=%d\n", |
entry->p_offset % entry->p_align, |
entry->p_vaddr % entry->p_align |
); |
return EE_INVALID; |
} |
354,8 → 376,8 |
* For the course of loading, the area needs to be readable |
* and writeable. |
*/ |
a = as_area_create((uint8_t *)base + bias, |
mem_sz, AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE); |
a = as_area_create((uint8_t *)base + bias, mem_sz, |
AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE); |
if (a == (void *)(-1)) { |
printf("memory mapping failed\n"); |
return EE_MEMORY; |
369,7 → 391,10 |
*/ |
// printf("seek to %d\n", entry->p_offset); |
rc = lseek(elf->fd, entry->p_offset, SEEK_SET); |
if (rc < 0) { printf("seek error\n"); return EE_INVALID; } |
if (rc < 0) { |
printf("seek error\n"); |
return EE_INVALID; |
} |
// printf("read 0x%x bytes to address 0x%x\n", entry->p_filesz, entry->p_vaddr+bias); |
/* rc = read(fd, (void *)(entry->p_vaddr + bias), entry->p_filesz); |
388,10 → 413,13 |
if (now > left) now = left; |
// printf("read %d...", now); |
rc = read(elf->fd, dp, now); |
rc = my_read(elf->fd, dp, now); |
// printf("->%d\n", rc); |
if (rc < 0) { printf("read error\n"); return EE_INVALID; } |
if (rc < 0) { |
printf("read error\n"); |
return EE_INVALID; |
} |
left -= now; |
dp += now; |
/branches/dynload/uspace/srv/fb/main.c |
---|
37,6 → 37,7 |
#include "fb.h" |
#include "ega.h" |
#include "msim.h" |
#include "main.h" |
#define NAME "fb" |
58,20 → 59,26 |
printf(NAME ": HelenOS Framebuffer service\n"); |
ipcarg_t phonead; |
int initialized = 0; |
bool initialized = false; |
#ifdef FB_ENABLED |
if (sysinfo_value("fb.kind") == 1) { |
if (fb_init() == 0) |
initialized = 1; |
initialized = true; |
} |
#endif |
#ifdef EGA_ENABLED |
if (!initialized && sysinfo_value("fb.kind") == 2) { |
if ((!initialized) && (sysinfo_value("fb.kind") == 2)) { |
if (ega_init() == 0) |
initialized = 1; |
initialized = true; |
} |
#endif |
#ifdef MSIM_ENABLED |
if ((!initialized) && (sysinfo_value("fb.kind") == 3)) { |
if (msim_init() == 0) |
initialized = true; |
} |
#endif |
if (!initialized) |
return -1; |
/branches/dynload/uspace/srv/fb/msim.c |
---|
0,0 → 1,227 |
/* |
* Copyright (c) 2006 Ondrej Palkovsky |
* Copyright (c) 2008 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @defgroup msimfb MSIM text console |
* @brief HelenOS MSIM text console. |
* @ingroup fbs |
* @{ |
*/ |
/** @file |
*/ |
#include <async.h> |
#include <ipc/fb.h> |
#include <ipc/ipc.h> |
#include <libc.h> |
#include <errno.h> |
#include <string.h> |
#include <libc.h> |
#include <stdio.h> |
#include <ipc/fb.h> |
#include <sysinfo.h> |
#include <as.h> |
#include <align.h> |
#include <ddi.h> |
#include "msim.h" |
#define WIDTH 80 |
#define HEIGHT 25 |
#define MAX_CONTROL 20 |
/* Allow only 1 connection */ |
static int client_connected = 0; |
static char *virt_addr; |
static void msim_putc(const char c) |
{ |
*virt_addr = c; |
} |
static void msim_puts(char *str) |
{ |
while (*str) |
*virt_addr = *(str++); |
} |
static void msim_clrscr(void) |
{ |
msim_puts("\033[2J"); |
} |
static void msim_goto(const unsigned int row, const unsigned int col) |
{ |
if ((row > HEIGHT) || (col > WIDTH)) |
return; |
char control[MAX_CONTROL]; |
snprintf(control, MAX_CONTROL, "\033[%u;%uf", row + 1, col + 1); |
msim_puts(control); |
} |
static void msim_set_style(const unsigned int mode) |
{ |
char control[MAX_CONTROL]; |
snprintf(control, MAX_CONTROL, "\033[%um", mode); |
msim_puts(control); |
} |
static void msim_cursor_disable(void) |
{ |
msim_puts("\033[?25l"); |
} |
static void msim_cursor_enable(void) |
{ |
msim_puts("\033[?25h"); |
} |
static void msim_scroll(int i) |
{ |
if (i > 0) { |
msim_goto(HEIGHT - 1, 0); |
while (i--) |
msim_puts("\033D"); |
} else if (i < 0) { |
msim_goto(0, 0); |
while (i++) |
msim_puts("\033M"); |
} |
} |
static void msim_client_connection(ipc_callid_t iid, ipc_call_t *icall) |
{ |
int retval; |
ipc_callid_t callid; |
ipc_call_t call; |
char c; |
int lastcol = 0; |
int lastrow = 0; |
int newcol; |
int newrow; |
int fgcolor; |
int bgcolor; |
int i; |
if (client_connected) { |
ipc_answer_0(iid, ELIMIT); |
return; |
} |
client_connected = 1; |
ipc_answer_0(iid, EOK); |
/* Clear the terminal, set scrolling region |
to 0 - 25 lines */ |
msim_clrscr(); |
msim_goto(0, 0); |
msim_puts("\033[0;25r"); |
while (true) { |
callid = async_get_call(&call); |
switch (IPC_GET_METHOD(call)) { |
case IPC_M_PHONE_HUNGUP: |
client_connected = 0; |
ipc_answer_0(callid, EOK); |
return; |
case FB_PUTCHAR: |
c = IPC_GET_ARG1(call); |
newrow = IPC_GET_ARG2(call); |
newcol = IPC_GET_ARG3(call); |
if ((lastcol != newcol) || (lastrow != newrow)) |
msim_goto(newrow, newcol); |
lastcol = newcol + 1; |
lastrow = newrow; |
msim_putc(c); |
retval = 0; |
break; |
case FB_CURSOR_GOTO: |
newrow = IPC_GET_ARG1(call); |
newcol = IPC_GET_ARG2(call); |
msim_goto(newrow, newcol); |
lastrow = newrow; |
lastcol = newcol; |
retval = 0; |
break; |
case FB_GET_CSIZE: |
ipc_answer_2(callid, EOK, HEIGHT, WIDTH); |
continue; |
case FB_CLEAR: |
msim_clrscr(); |
retval = 0; |
break; |
case FB_SET_STYLE: |
fgcolor = IPC_GET_ARG1(call); |
bgcolor = IPC_GET_ARG2(call); |
if (fgcolor < bgcolor) |
msim_set_style(0); |
else |
msim_set_style(7); |
retval = 0; |
break; |
case FB_SCROLL: |
i = IPC_GET_ARG1(call); |
if ((i > HEIGHT) || (i < -HEIGHT)) { |
retval = EINVAL; |
break; |
} |
msim_scroll(i); |
msim_goto(lastrow, lastcol); |
retval = 0; |
break; |
case FB_CURSOR_VISIBILITY: |
if(IPC_GET_ARG1(call)) |
msim_cursor_enable(); |
else |
msim_cursor_disable(); |
retval = 0; |
break; |
default: |
retval = ENOENT; |
} |
ipc_answer_0(callid, retval); |
} |
} |
int msim_init(void) |
{ |
void *phys_addr = (void *) sysinfo_value("fb.address.physical"); |
virt_addr = (char *) as_get_mappable_page(1); |
physmem_map(phys_addr, virt_addr, 1, AS_AREA_READ | AS_AREA_WRITE); |
async_set_client_connection(msim_client_connection); |
return 0; |
} |
/** |
* @} |
*/ |
/branches/dynload/uspace/srv/fb/msim.h |
---|
0,0 → 1,47 |
/* |
* Copyright (c) 2006 Ondrej Palkovsky |
* Copyright (c) 2008 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup msimfb |
* @brief HelenOS MSIM text console. |
* @ingroup fbs |
* @{ |
*/ |
/** @file |
*/ |
#ifndef FB_MSIM_H_ |
#define FB_MSIM_H_ |
extern int msim_init(void); |
#endif |
/** @} |
*/ |
/branches/dynload/uspace/srv/fb/Makefile |
---|
50,7 → 50,6 |
font-8x16.c |
CFLAGS += -DFB_ENABLED |
endif |
ifeq ($(ARCH), ia32) |
SOURCES += ega.c |
CFLAGS += -DEGA_ENABLED |
60,7 → 59,8 |
CFLAGS += -DEGA_ENABLED |
endif |
ifeq ($(ARCH), mips32) |
CFLAGS += -DFB_INVERT_ENDIAN |
SOURCES += msim.c |
CFLAGS += -DMSIM_ENABLED -DFB_INVERT_ENDIAN |
endif |
CFLAGS += -D$(ARCH) |
/branches/dynload/uspace/srv/fs/tmpfs/tmpfs.h |
---|
44,6 → 44,12 |
#define dprintf(...) printf(__VA_ARGS__) |
#endif |
typedef enum { |
TMPFS_NONE, |
TMPFS_FILE, |
TMPFS_DIRECTORY |
} tmpfs_dentry_type_t; |
typedef struct tmpfs_dentry { |
fs_index_t index; /**< TMPFS node index. */ |
link_t dh_link; /**< Dentries hash table link. */ |
50,11 → 56,7 |
struct tmpfs_dentry *sibling; |
struct tmpfs_dentry *child; |
hash_table_t names; /**< All names linking to this TMPFS node. */ |
enum { |
TMPFS_NONE, |
TMPFS_FILE, |
TMPFS_DIRECTORY |
} type; |
tmpfs_dentry_type_t type; |
unsigned lnkcnt; /**< Link count. */ |
size_t size; /**< File size if type is TMPFS_FILE. */ |
void *data; /**< File content's if type is TMPFS_FILE. */ |
/branches/dynload/uspace/srv/fs/tmpfs/tmpfs_dump.c |
---|
39,6 → 39,7 |
#include "tmpfs.h" |
#include "../../vfs/vfs.h" |
#include <ipc/ipc.h> |
#include <async.h> |
#include <errno.h> |
#include <stdlib.h> |
#include <string.h> |
50,9 → 51,7 |
#include <sys/mman.h> |
#include <byteorder.h> |
#define BLOCK_SIZE 1024 // FIXME |
#define RD_BASE 1024 // FIXME |
#define RD_READ_BLOCK (RD_BASE + 1) |
#define TMPFS_BLOCK_SIZE 1024 |
struct rdentry { |
uint8_t type; |
59,48 → 58,9 |
uint32_t len; |
} __attribute__((packed)); |
static bool |
tmpfs_blockread(int phone, void *buffer, size_t *bufpos, size_t *buflen, |
size_t *pos, void *dst, size_t size) |
{ |
size_t offset = 0; |
size_t left = size; |
while (left > 0) { |
size_t rd; |
if (*bufpos + left < *buflen) |
rd = left; |
else |
rd = *buflen - *bufpos; |
if (rd > 0) { |
memcpy(dst + offset, buffer + *bufpos, rd); |
offset += rd; |
*bufpos += rd; |
*pos += rd; |
left -= rd; |
} |
if (*bufpos == *buflen) { |
ipcarg_t retval; |
int rc = ipc_call_sync_2_1(phone, RD_READ_BLOCK, |
*pos / BLOCK_SIZE, BLOCK_SIZE, |
&retval); |
if ((rc != EOK) || (retval != EOK)) |
return false; |
*bufpos = 0; |
*buflen = BLOCK_SIZE; |
} |
} |
return true; |
} |
static bool |
tmpfs_restore_recursion(int phone, void *block, size_t *bufpos, size_t *buflen, |
size_t *pos, tmpfs_dentry_t *parent) |
tmpfs_restore_recursion(int phone, void *block, off_t *bufpos, size_t *buflen, |
off_t *pos, tmpfs_dentry_t *parent) |
{ |
struct rdentry entry; |
libfs_ops_t *ops = &tmpfs_libfs_ops; |
110,16 → 70,16 |
tmpfs_dentry_t *node; |
uint32_t size; |
if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, &entry, |
sizeof(entry))) |
if (!libfs_blockread(phone, block, bufpos, buflen, pos, &entry, |
sizeof(entry), TMPFS_BLOCK_SIZE)) |
return false; |
entry.len = uint32_t_le2host(entry.len); |
switch (entry.type) { |
case 0: |
case TMPFS_NONE: |
break; |
case 1: |
case TMPFS_FILE: |
fname = malloc(entry.len + 1); |
if (fname == NULL) |
return false; |
130,8 → 90,8 |
return false; |
} |
if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, |
fname, entry.len)) { |
if (!libfs_blockread(phone, block, bufpos, buflen, pos, |
fname, entry.len, TMPFS_BLOCK_SIZE)) { |
ops->destroy((void *) node); |
free(fname); |
return false; |
145,8 → 105,8 |
} |
free(fname); |
if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, |
&size, sizeof(size))) |
if (!libfs_blockread(phone, block, bufpos, buflen, pos, |
&size, sizeof(size), TMPFS_BLOCK_SIZE)) |
return false; |
size = uint32_t_le2host(size); |
156,12 → 116,12 |
return false; |
node->size = size; |
if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, |
node->data, size)) |
if (!libfs_blockread(phone, block, bufpos, buflen, pos, |
node->data, size, TMPFS_BLOCK_SIZE)) |
return false; |
break; |
case 2: |
case TMPFS_DIRECTORY: |
fname = malloc(entry.len + 1); |
if (fname == NULL) |
return false; |
172,8 → 132,8 |
return false; |
} |
if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, |
fname, entry.len)) { |
if (!libfs_blockread(phone, block, bufpos, buflen, pos, |
fname, entry.len, TMPFS_BLOCK_SIZE)) { |
ops->destroy((void *) node); |
free(fname); |
return false; |
195,7 → 155,7 |
default: |
return false; |
} |
} while (entry.type != 0); |
} while (entry.type != TMPFS_NONE); |
return true; |
} |
204,7 → 164,7 |
{ |
libfs_ops_t *ops = &tmpfs_libfs_ops; |
void *block = mmap(NULL, BLOCK_SIZE, |
void *block = mmap(NULL, TMPFS_BLOCK_SIZE, |
PROTO_READ | PROTO_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); |
if (block == NULL) |
214,7 → 174,7 |
DEVMAP_CONNECT_TO_DEVICE, dev); |
if (phone < 0) { |
munmap(block, BLOCK_SIZE); |
munmap(block, TMPFS_BLOCK_SIZE); |
return false; |
} |
222,12 → 182,13 |
EOK) |
goto error; |
size_t bufpos = 0; |
off_t bufpos = 0; |
size_t buflen = 0; |
size_t pos = 0; |
off_t pos = 0; |
char tag[6]; |
if (!tmpfs_blockread(phone, block, &bufpos, &buflen, &pos, tag, 5)) |
if (!libfs_blockread(phone, block, &bufpos, &buflen, &pos, tag, 5, |
TMPFS_BLOCK_SIZE)) |
goto error; |
tag[5] = 0; |
239,12 → 200,12 |
goto error; |
ipc_hangup(phone); |
munmap(block, BLOCK_SIZE); |
munmap(block, TMPFS_BLOCK_SIZE); |
return true; |
error: |
ipc_hangup(phone); |
munmap(block, BLOCK_SIZE); |
munmap(block, TMPFS_BLOCK_SIZE); |
return false; |
} |
/branches/dynload/uspace/srv/fs/tmpfs/tmpfs_ops.c |
---|
233,7 → 233,7 |
hash_table_destroy(&dentries); |
return false; |
} |
root->lnkcnt = 1; |
root->lnkcnt = 0; /* FS root is not linked */ |
return true; |
} |
405,11 → 405,12 |
if (dev_handle >= 0) { |
if (tmpfs_restore(dev_handle)) |
ipc_answer_0(rid, EOK); |
ipc_answer_3(rid, EOK, root->index, root->size, |
root->lnkcnt); |
else |
ipc_answer_0(rid, ELIMIT); |
} else { |
ipc_answer_0(rid, EOK); |
ipc_answer_3(rid, EOK, root->index, root->size, root->lnkcnt); |
} |
} |
/branches/dynload/uspace/srv/fs/fat/fat.h |
---|
222,6 → 222,7 |
extern void fat_mounted(ipc_callid_t, ipc_call_t *); |
extern void fat_mount(ipc_callid_t, ipc_call_t *); |
extern void fat_lookup(ipc_callid_t, ipc_call_t *); |
extern void fat_read(ipc_callid_t, ipc_call_t *); |
extern fat_idx_t *fat_idx_get_by_pos(dev_handle_t, fat_cluster_t, unsigned); |
extern fat_idx_t *fat_idx_get_by_index(dev_handle_t, fs_index_t); |
/branches/dynload/uspace/srv/fs/fat/fat.c |
---|
107,6 → 107,9 |
case VFS_LOOKUP: |
fat_lookup(callid, &call); |
break; |
case VFS_READ: |
fat_read(callid, &call); |
break; |
default: |
ipc_answer_0(callid, ENOTSUP); |
break; |
/branches/dynload/uspace/srv/fs/fat/fat_ops.c |
---|
39,6 → 39,8 |
#include "../../vfs/vfs.h" |
#include <libfs.h> |
#include <ipc/ipc.h> |
#include <ipc/services.h> |
#include <ipc/devmap.h> |
#include <async.h> |
#include <errno.h> |
#include <string.h> |
47,8 → 49,10 |
#include <libadt/list.h> |
#include <assert.h> |
#include <futex.h> |
#include <sys/mman.h> |
#define BS_BLOCK 0 |
#define BS_SIZE 512 |
/** Futex protecting the list of cached free FAT nodes. */ |
static futex_t ffn_futex = FUTEX_INITIALIZER; |
66,15 → 70,15 |
#define FAT_DENTRY_DOT 0x2e |
#define FAT_DENTRY_ERASED 0xe5 |
#define min(a, b) ((a) < (b) ? (a) : (b)) |
static void dentry_name_canonify(fat_dentry_t *d, char *buf) |
{ |
int i; |
for (i = 0; i < FAT_NAME_LEN; i++) { |
if (d->name[i] == FAT_PAD) { |
buf++; |
if (d->name[i] == FAT_PAD) |
break; |
} |
if (d->name[i] == FAT_DENTRY_E5_ESC) |
*buf++ = 0xe5; |
else |
92,21 → 96,55 |
else |
*buf++ = d->ext[i]; |
} |
*buf = '\0'; |
} |
static int dev_phone = -1; /* FIXME */ |
static void *dev_buffer = NULL; /* FIXME */ |
/* TODO move somewhere else */ |
typedef struct { |
void *data; |
size_t size; |
} block_t; |
static block_t *block_get(dev_handle_t dev_handle, off_t offset) |
static block_t *block_get(dev_handle_t dev_handle, off_t offset, size_t bs) |
{ |
return NULL; /* TODO */ |
/* FIXME */ |
block_t *b; |
off_t bufpos = 0; |
size_t buflen = 0; |
off_t pos = offset * bs; |
assert(dev_phone != -1); |
assert(dev_buffer); |
b = malloc(sizeof(block_t)); |
if (!b) |
return NULL; |
b->data = malloc(bs); |
if (!b->data) { |
free(b); |
return NULL; |
} |
b->size = bs; |
if (!libfs_blockread(dev_phone, dev_buffer, &bufpos, &buflen, &pos, |
b->data, bs, bs)) { |
free(b->data); |
free(b); |
return NULL; |
} |
return b; |
} |
static void block_put(block_t *block) |
{ |
/* TODO */ |
/* FIXME */ |
free(block->data); |
free(block); |
} |
#define FAT_BS(b) ((fat_bs_t *)((b)->data)) |
143,7 → 181,7 |
fat_cluster_t clst = firstc; |
unsigned i; |
bb = block_get(dev_handle, BS_BLOCK); |
bb = block_get(dev_handle, BS_BLOCK, BS_SIZE); |
bps = uint16_t_le2host(FAT_BS(bb)->bps); |
spc = FAT_BS(bb)->spc; |
rscnt = uint16_t_le2host(FAT_BS(bb)->rscnt); |
159,7 → 197,7 |
if (firstc == FAT_CLST_ROOT) { |
/* root directory special case */ |
assert(offset < rds); |
b = block_get(dev_handle, rscnt + fatcnt * sf + offset); |
b = block_get(dev_handle, rscnt + fatcnt * sf + offset, bps); |
return b; |
} |
172,7 → 210,7 |
fsec = (clst * sizeof(fat_cluster_t)) / bps; |
fidx = clst % (bps / sizeof(fat_cluster_t)); |
/* read FAT1 */ |
b = block_get(dev_handle, rscnt + fsec); |
b = block_get(dev_handle, rscnt + fsec, bps); |
clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]); |
assert(clst != FAT_CLST_BAD); |
assert(clst < FAT_CLST_LAST1); |
180,11 → 218,58 |
} |
b = block_get(dev_handle, ssa + (clst - FAT_CLST_FIRST) * spc + |
offset % spc); |
offset % spc, bps); |
return b; |
} |
/** Return number of blocks allocated to a file. |
* |
* @param dev_handle Device handle of the device with the file. |
* @param firstc First cluster of the file. |
* |
* @return Number of blocks allocated to the file. |
*/ |
static uint16_t |
_fat_blcks_get(dev_handle_t dev_handle, fat_cluster_t firstc) |
{ |
block_t *bb; |
block_t *b; |
unsigned bps; |
unsigned spc; |
unsigned rscnt; /* block address of the first FAT */ |
unsigned clusters = 0; |
fat_cluster_t clst = firstc; |
bb = block_get(dev_handle, BS_BLOCK, BS_SIZE); |
bps = uint16_t_le2host(FAT_BS(bb)->bps); |
spc = FAT_BS(bb)->spc; |
rscnt = uint16_t_le2host(FAT_BS(bb)->rscnt); |
block_put(bb); |
if (firstc == FAT_CLST_RES0) { |
/* No space allocated to the file. */ |
return 0; |
} |
while (clst < FAT_CLST_LAST1) { |
unsigned fsec; /* sector offset relative to FAT1 */ |
unsigned fidx; /* FAT1 entry index */ |
assert(clst >= FAT_CLST_FIRST); |
fsec = (clst * sizeof(fat_cluster_t)) / bps; |
fidx = clst % (bps / sizeof(fat_cluster_t)); |
/* read FAT1 */ |
b = block_get(dev_handle, rscnt + fsec, bps); |
clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]); |
assert(clst != FAT_CLST_BAD); |
block_put(b); |
clusters++; |
} |
return clusters * spc; |
} |
static void fat_node_initialize(fat_node_t *node) |
{ |
futex_initialize(&node->lock, 1); |
202,7 → 287,7 |
block_t *bb; |
uint16_t bps; |
bb = block_get(dev_handle, BS_BLOCK); |
bb = block_get(dev_handle, BS_BLOCK, BS_SIZE); |
assert(bb != NULL); |
bps = uint16_t_le2host(FAT_BS(bb)->bps); |
block_put(bb); |
253,7 → 338,7 |
{ |
block_t *b; |
fat_dentry_t *d; |
fat_node_t *nodep; |
fat_node_t *nodep = NULL; |
unsigned bps; |
unsigned dps; |
264,7 → 349,7 |
*/ |
futex_down(&idxp->nodep->lock); |
if (!idxp->nodep->refcnt++) |
list_remove(&nodep->ffn_link); |
list_remove(&idxp->nodep->ffn_link); |
futex_up(&idxp->nodep->lock); |
return idxp->nodep; |
} |
320,11 → 405,18 |
* and initialized elsewhere. |
*/ |
nodep->type = FAT_DIRECTORY; |
/* |
* Unfortunately, the 'size' field of the FAT dentry is not |
* defined for the directory entry type. We must determine the |
* size of the directory by walking the FAT. |
*/ |
nodep->size = bps * _fat_blcks_get(idxp->dev_handle, |
uint16_t_le2host(d->firstc)); |
} else { |
nodep->type = FAT_FILE; |
nodep->size = uint32_t_le2host(d->size); |
} |
nodep->firstc = uint16_t_le2host(d->firstc); |
nodep->size = uint32_t_le2host(d->size); |
nodep->lnkcnt = 1; |
nodep->refcnt = 1; |
421,7 → 513,7 |
dentry_name_canonify(d, name); |
break; |
} |
if (strcmp(name, component) == 0) { |
if (stricmp(name, component) == 0) { |
/* hit */ |
void *node; |
/* |
567,16 → 659,56 |
{ |
dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); |
block_t *bb; |
uint16_t bps; |
uint16_t rde; |
int rc; |
/* |
* For now, we don't bother to remember dev_handle, dev_phone or |
* dev_buffer in some data structure. We use global variables because we |
* know there will be at most one mount on this file system. |
* Of course, this is a huge TODO item. |
*/ |
dev_buffer = mmap(NULL, BS_SIZE, PROTO_READ | PROTO_WRITE, |
MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); |
if (!dev_buffer) { |
ipc_answer_0(rid, ENOMEM); |
return; |
} |
dev_phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, |
DEVMAP_CONNECT_TO_DEVICE, dev_handle); |
if (dev_phone < 0) { |
munmap(dev_buffer, BS_SIZE); |
ipc_answer_0(rid, dev_phone); |
return; |
} |
rc = ipc_share_out_start(dev_phone, dev_buffer, |
AS_AREA_READ | AS_AREA_WRITE); |
if (rc != EOK) { |
munmap(dev_buffer, BS_SIZE); |
ipc_answer_0(rid, rc); |
return; |
} |
/* Read the number of root directory entries. */ |
bb = block_get(dev_handle, BS_BLOCK); |
bb = block_get(dev_handle, BS_BLOCK, BS_SIZE); |
bps = uint16_t_le2host(FAT_BS(bb)->bps); |
rde = uint16_t_le2host(FAT_BS(bb)->root_ent_max); |
block_put(bb); |
if (bps != BS_SIZE) { |
munmap(dev_buffer, BS_SIZE); |
ipc_answer_0(rid, ENOTSUP); |
return; |
} |
rc = fat_idx_init_by_dev_handle(dev_handle); |
if (rc != EOK) { |
munmap(dev_buffer, BS_SIZE); |
ipc_answer_0(rid, rc); |
return; |
} |
584,6 → 716,7 |
/* Initialize the root node. */ |
fat_node_t *rootp = (fat_node_t *)malloc(sizeof(fat_node_t)); |
if (!rootp) { |
munmap(dev_buffer, BS_SIZE); |
fat_idx_fini_by_dev_handle(dev_handle); |
ipc_answer_0(rid, ENOMEM); |
return; |
592,6 → 725,7 |
fat_idx_t *ridxp = fat_idx_get_by_pos(dev_handle, FAT_CLST_ROOTPAR, 0); |
if (!ridxp) { |
munmap(dev_buffer, BS_SIZE); |
free(rootp); |
fat_idx_fini_by_dev_handle(dev_handle); |
ipc_answer_0(rid, ENOMEM); |
603,6 → 737,7 |
rootp->type = FAT_DIRECTORY; |
rootp->firstc = FAT_CLST_ROOT; |
rootp->refcnt = 1; |
rootp->lnkcnt = 0; /* FS root is not linked */ |
rootp->size = rde * sizeof(fat_dentry_t); |
rootp->idx = ridxp; |
ridxp->nodep = rootp; |
609,7 → 744,7 |
futex_up(&ridxp->lock); |
ipc_answer_0(rid, EOK); |
ipc_answer_3(rid, EOK, ridxp->index, rootp->size, rootp->lnkcnt); |
} |
void fat_mount(ipc_callid_t rid, ipc_call_t *request) |
622,6 → 757,96 |
libfs_lookup(&fat_libfs_ops, fat_reg.fs_handle, rid, request); |
} |
void fat_read(ipc_callid_t rid, ipc_call_t *request) |
{ |
dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request); |
fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); |
off_t pos = (off_t)IPC_GET_ARG3(*request); |
fat_node_t *nodep = (fat_node_t *)fat_node_get(dev_handle, index); |
uint16_t bps = fat_bps_get(dev_handle); |
size_t bytes; |
block_t *b; |
if (!nodep) { |
ipc_answer_0(rid, ENOENT); |
return; |
} |
ipc_callid_t callid; |
size_t len; |
if (!ipc_data_read_receive(&callid, &len)) { |
fat_node_put(nodep); |
ipc_answer_0(callid, EINVAL); |
ipc_answer_0(rid, EINVAL); |
return; |
} |
if (nodep->type == FAT_FILE) { |
/* |
* Our strategy for regular file reads is to read one block at |
* most and make use of the possibility to return less data than |
* requested. This keeps the code very simple. |
*/ |
bytes = min(len, bps - pos % bps); |
b = fat_block_get(nodep, pos / bps); |
(void) ipc_data_read_finalize(callid, b->data + pos % bps, |
bytes); |
block_put(b); |
} else { |
unsigned bnum; |
off_t spos = pos; |
char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1]; |
fat_dentry_t *d; |
assert(nodep->type == FAT_DIRECTORY); |
assert(nodep->size % bps == 0); |
assert(bps % sizeof(fat_dentry_t) == 0); |
/* |
* Our strategy for readdir() is to use the position pointer as |
* an index into the array of all dentries. On entry, it points |
* to the first unread dentry. If we skip any dentries, we bump |
* the position pointer accordingly. |
*/ |
bnum = (pos * sizeof(fat_dentry_t)) / bps; |
while (bnum < nodep->size / bps) { |
off_t o; |
b = fat_block_get(nodep, bnum); |
for (o = pos % (bps / sizeof(fat_dentry_t)); |
o < bps / sizeof(fat_dentry_t); |
o++, pos++) { |
d = ((fat_dentry_t *)b->data) + o; |
switch (fat_classify_dentry(d)) { |
case FAT_DENTRY_SKIP: |
continue; |
case FAT_DENTRY_LAST: |
block_put(b); |
goto miss; |
default: |
case FAT_DENTRY_VALID: |
dentry_name_canonify(d, name); |
block_put(b); |
goto hit; |
} |
} |
block_put(b); |
bnum++; |
} |
miss: |
fat_node_put(nodep); |
ipc_answer_0(callid, ENOENT); |
ipc_answer_1(rid, ENOENT, 0); |
return; |
hit: |
(void) ipc_data_read_finalize(callid, name, strlen(name) + 1); |
bytes = (pos - spos) + 1; |
} |
fat_node_put(nodep); |
ipc_answer_1(rid, EOK, (ipcarg_t)bytes); |
} |
/** |
* @} |
*/ |
/branches/dynload/uspace/srv/vfs/vfs_ops.c |
---|
71,8 → 71,11 |
{ |
dev_handle_t dev_handle; |
vfs_node_t *mp_node = NULL; |
ipc_callid_t callid; |
ipc_call_t data; |
int rc; |
int phone; |
size_t size; |
/* |
* We expect the library to do the device-name to device-handle |
86,9 → 89,6 |
* carry mount options in the future. |
*/ |
ipc_callid_t callid; |
size_t size; |
/* |
* Now, we expect the client to send us data with the name of the file |
* system. |
115,15 → 115,30 |
fs_name[size] = '\0'; |
/* |
* Wait for IPC_M_PING so that we can return an error if we don't know |
* fs_name. |
*/ |
callid = async_get_call(&data); |
if (IPC_GET_METHOD(data) != IPC_M_PING) { |
ipc_answer_0(callid, ENOTSUP); |
ipc_answer_0(rid, ENOTSUP); |
return; |
} |
/* |
* Check if we know a file system with the same name as is in fs_name. |
* This will also give us its file system handle. |
*/ |
fs_handle_t fs_handle = fs_name_to_handle(fs_name, true); |
if (!fs_handle) { |
ipc_answer_0(callid, ENOENT); |
ipc_answer_0(rid, ENOENT); |
return; |
} |
/* Acknowledge that we know fs_name. */ |
ipc_answer_0(callid, EOK); |
/* Now, we want the client to send us the mount point. */ |
if (!ipc_data_write_receive(&callid, &size)) { |
ipc_answer_0(callid, EINVAL); |
190,6 → 205,12 |
} else { |
/* We still don't have the root file system mounted. */ |
if ((size == 1) && (buf[0] == '/')) { |
vfs_lookup_res_t mr_res; |
vfs_node_t *mr_node; |
ipcarg_t rindex; |
ipcarg_t rsize; |
ipcarg_t rlnkcnt; |
/* |
* For this simple, but important case, |
* we are almost done. |
198,16 → 219,30 |
/* Tell the mountee that it is being mounted. */ |
phone = vfs_grab_phone(fs_handle); |
rc = async_req_1_0(phone, VFS_MOUNTED, |
(ipcarg_t) dev_handle); |
rc = async_req_1_3(phone, VFS_MOUNTED, |
(ipcarg_t) dev_handle, &rindex, &rsize, &rlnkcnt); |
vfs_release_phone(phone); |
if (rc == EOK) { |
rootfs.fs_handle = fs_handle; |
rootfs.dev_handle = dev_handle; |
if (rc != EOK) { |
futex_up(&rootfs_futex); |
ipc_answer_0(rid, rc); |
return; |
} |
mr_res.triplet.fs_handle = fs_handle; |
mr_res.triplet.dev_handle = dev_handle; |
mr_res.triplet.index = (fs_index_t) rindex; |
mr_res.size = (size_t) rsize; |
mr_res.lnkcnt = (unsigned) rlnkcnt; |
rootfs.fs_handle = fs_handle; |
rootfs.dev_handle = dev_handle; |
futex_up(&rootfs_futex); |
/* Add reference to the mounted root. */ |
mr_node = vfs_node_get(&mr_res); |
assert(mr_node); |
ipc_answer_0(rid, rc); |
return; |
} else { |
/branches/dynload/uspace/Makefile |
---|
50,10 → 50,10 |
srv/devmap \ |
app/tetris \ |
app/tester \ |
app/cli \ |
app/dltest \ |
app/klog \ |
app/init |
app/init \ |
app/bdsh |
ifeq ($(ARCH), amd64) |
DIRS += srv/pci |
/branches/dynload/HelenOS.config |
---|
45,7 → 45,6 |
@ "simics" Simics |
@ "bgxemul" GXEmul big endian |
@ "lgxemul" GXEmul little endian |
@ "indy" Sgi Indy |
! [PLATFORM=mips32] MACHINE (choice) |
# Machine type |
/branches/dynload/boot/tools/ia64/vmaxlma.c |
---|
File deleted |
/branches/dynload/boot/boot.config |
---|
78,3 → 78,7 |
@ "ecoff" Ecoff image (GXEmul) |
! [ARCH=mips32] IMAGE (choice) |
# Ramdisk format |
@ "tmpfs" TMPFS image |
@ "fat" FAT16 image |
! RDFMT (choice) |
/branches/dynload/boot/arch/sparc64/Makefile.inc |
---|
36,6 → 36,8 |
cat arch/$(ARCH)/silo/silo.tar.gz | (cd $(TMP)/boot; tar xvfz -) |
cp arch/$(ARCH)/silo/README arch/$(ARCH)/silo/COPYING arch/$(ARCH)/silo/silo.conf $(TMP)/boot |
cp arch/$(ARCH)/loader/image.boot $(TMP)/HelenOS/image.boot |
gzip -f $(TMP)/HelenOS/image.boot |
cp arch/$(ARCH)/loader/initrd.img $(TMP)/HelenOS/initrd.img |
mkisofs -f -G $(TMP)/boot/isofs.b -B ... -r -o $(BASE)/image.iso $(TMP)/ |
depend: |
/branches/dynload/boot/arch/sparc64/loader/asm.S |
---|
30,6 → 30,9 |
#include <stack.h> |
#include <register.h> |
.register %g2, #scratch |
.register %g3, #scratch |
.text |
.global halt |
41,8 → 44,7 |
nop |
memcpy: |
.register %g2, #scratch |
.register %g3, #scratch |
mov %o0, %o3 ! save dst |
add %o1, 7, %g1 |
and %g1, -8, %g1 |
cmp %o1, %g1 |
61,7 → 63,7 |
mov %g2, %g3 |
2: |
jmp %o7 + 8 ! exit point |
mov %o1, %o0 |
mov %o3, %o0 |
3: |
and %g1, -8, %g1 |
cmp %o0, %g1 |
95,7 → 97,7 |
mov %g2, %g3 |
jmp %o7 + 8 ! exit point |
mov %o1, %o0 |
mov %o3, %o0 |
jump_to_kernel: |
/* |
/branches/dynload/boot/arch/sparc64/loader/boot.S |
---|
53,6 → 53,15 |
.ascii "HdrS" |
.word 0 |
.half 0 |
.half 0 |
.half 0 |
.half 0 |
.global silo_ramdisk_image |
silo_ramdisk_image: |
.word 0 |
.global silo_ramdisk_size |
silo_ramdisk_size: |
.word 0 |
.align 8 |
1: |
/branches/dynload/boot/arch/sparc64/loader/main.c |
---|
57,11 → 57,18 |
/** Print version information. */ |
static void version_print(void) |
{ |
printf("HelenOS SPARC64 Bootloader\nRelease %s%s%s\nCopyright (c) 2006 HelenOS project\n", release, revision, timestamp); |
printf("HelenOS SPARC64 Bootloader\nRelease %s%s%s\n" |
"Copyright (c) 2006 HelenOS project\n", |
release, revision, timestamp); |
} |
void bootstrap(void) |
{ |
void *base = (void *) KERNEL_VIRTUAL_ADDRESS; |
void *balloc_base; |
unsigned int top = 0; |
int i, j; |
version_print(); |
init_components(components); |
80,29 → 87,99 |
printf("Error: no memory detected, halting.\n"); |
halt(); |
} |
/* |
* SILO for some reason adds 0x400000 and subtracts |
* bootinfo.physmem_start to/from silo_ramdisk_image. |
* We just need plain physical address so we fix it up. |
*/ |
if (silo_ramdisk_image) { |
silo_ramdisk_image += bootinfo.physmem_start; |
silo_ramdisk_image -= 0x400000; |
/* Install 1:1 mapping for the ramdisk. */ |
if (ofw_map((void *)((uintptr_t)silo_ramdisk_image), |
(void *)((uintptr_t)silo_ramdisk_image), |
silo_ramdisk_size, -1) != 0) { |
printf("Failed to map ramdisk.\n"); |
halt(); |
} |
} |
printf("\nSystem info\n"); |
printf(" memory: %dM starting at %P\n", |
bootinfo.memmap.total >> 20, bootinfo.physmem_start); |
bootinfo.memmap.total >> 20, bootinfo.physmem_start); |
printf("\nMemory statistics\n"); |
printf(" kernel entry point at %P\n", KERNEL_VIRTUAL_ADDRESS); |
printf(" %P: boot info structure\n", &bootinfo); |
unsigned int i; |
for (i = 0; i < COMPONENTS; i++) |
/* |
* Figure out destination address for each component. |
* In this phase, we don't copy the components yet because we want to |
* to be careful not to overwrite anything, especially the components |
* which haven't been copied yet. |
*/ |
bootinfo.taskmap.count = 0; |
for (i = 0; i < COMPONENTS; i++) { |
printf(" %P: %s image (size %d bytes)\n", components[i].start, |
components[i].name, components[i].size); |
top = ALIGN_UP(top, PAGE_SIZE); |
if (i > 0) { |
if (bootinfo.taskmap.count == TASKMAP_MAX_RECORDS) { |
printf("Skipping superfluous components.\n"); |
break; |
} |
bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr = |
base + top; |
bootinfo.taskmap.tasks[bootinfo.taskmap.count].size = |
components[i].size; |
bootinfo.taskmap.count++; |
} |
top += components[i].size; |
} |
void * base = (void *) KERNEL_VIRTUAL_ADDRESS; |
unsigned int top = 0; |
j = bootinfo.taskmap.count - 1; /* do not consider ramdisk */ |
printf("\nCopying components\n"); |
bootinfo.taskmap.count = 0; |
for (i = 0; i < COMPONENTS; i++) { |
printf(" %s...", components[i].name); |
if (silo_ramdisk_image) { |
/* Treat the ramdisk as the last bootinfo task. */ |
if (bootinfo.taskmap.count == TASKMAP_MAX_RECORDS) { |
printf("Skipping ramdisk.\n"); |
goto skip_ramdisk; |
} |
top = ALIGN_UP(top, PAGE_SIZE); |
bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr = |
base + top; |
bootinfo.taskmap.tasks[bootinfo.taskmap.count].size = |
silo_ramdisk_size; |
bootinfo.taskmap.count++; |
printf("\nCopying ramdisk..."); |
/* |
* Claim and map the whole ramdisk as it may exceed the area |
* given to us by SILO. |
*/ |
(void) ofw_claim_phys(base + top, silo_ramdisk_size); |
(void) ofw_map(base + top, base + top, silo_ramdisk_size, -1); |
/* |
* FIXME If the source and destination overlap, it may be |
* desirable to copy in reverse order, depending on how the two |
* regions overlap. |
*/ |
memcpy(base + top, (void *)((uintptr_t)silo_ramdisk_image), |
silo_ramdisk_size); |
printf("done.\n"); |
top += silo_ramdisk_size; |
} |
skip_ramdisk: |
/* |
* Now we can proceed to copy the components. We do it in reverse order |
* so that we don't overwrite anything even if the components overlap |
* with base. |
*/ |
printf("\nCopying bootinfo tasks\n"); |
for (i = COMPONENTS - 1; i > 0; i--, j--) { |
printf(" %s...", components[i].name); |
/* |
* At this point, we claim the physical memory that we are |
* going to use. We should be safe in case of the virtual |
110,30 → 187,34 |
* SPARC binding, should restrict its use of virtual memory |
* to addresses from [0xffd00000; 0xffefffff] and |
* [0xfe000000; 0xfeffffff]. |
* |
* XXX We don't map this piece of memory. We simply rely on |
* SILO to have it done for us already in this case. |
*/ |
(void) ofw_claim_phys(bootinfo.physmem_start + base + top, |
(void) ofw_claim_phys(bootinfo.physmem_start + |
bootinfo.taskmap.tasks[j].addr, |
ALIGN_UP(components[i].size, PAGE_SIZE)); |
memcpy(base + top, components[i].start, components[i].size); |
if (i > 0) { |
bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr = |
base + top; |
bootinfo.taskmap.tasks[bootinfo.taskmap.count].size = |
components[i].size; |
bootinfo.taskmap.count++; |
} |
top += components[i].size; |
memcpy((void *)bootinfo.taskmap.tasks[j].addr, |
components[i].start, components[i].size); |
printf("done.\n"); |
} |
printf("\nCopying kernel..."); |
(void) ofw_claim_phys(bootinfo.physmem_start + base, |
ALIGN_UP(components[0].size, PAGE_SIZE)); |
memcpy(base, components[0].start, components[0].size); |
printf("done.\n"); |
/* |
* Claim the physical memory for the boot allocator. |
* Claim and map the physical memory for the boot allocator. |
* Initialize the boot allocator. |
*/ |
(void) ofw_claim_phys(bootinfo.physmem_start + |
base + ALIGN_UP(top, PAGE_SIZE), BALLOC_MAX_SIZE); |
balloc_init(&bootinfo.ballocs, ALIGN_UP(((uintptr_t) base) + top, |
PAGE_SIZE)); |
balloc_base = base + ALIGN_UP(top, PAGE_SIZE); |
(void) ofw_claim_phys(bootinfo.physmem_start + balloc_base, |
BALLOC_MAX_SIZE); |
(void) ofw_map(balloc_base, balloc_base, BALLOC_MAX_SIZE, -1); |
balloc_init(&bootinfo.ballocs, (uintptr_t)balloc_base); |
printf("\nCanonizing OpenFirmware device tree..."); |
bootinfo.ofw_root = ofw_tree_build(); |
/branches/dynload/boot/arch/sparc64/loader/main.h |
---|
59,6 → 59,9 |
ofw_tree_node_t *ofw_root; |
} bootinfo_t; |
extern uint32_t silo_ramdisk_image; |
extern uint32_t silo_ramdisk_size; |
extern bootinfo_t bootinfo; |
extern void start(void); |
/branches/dynload/boot/arch/sparc64/loader/Makefile |
---|
32,10 → 32,14 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf64-sparc |
BFD_ARCH = sparc |
TARGET = sparc64-linux-gnu |
TOOLCHAIN_DIR = /usr/local/sparc64/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/sparc64/bin |
ifeq ($(COMPILER),gcc_native) |
CC = gcc |
82,17 → 86,23 |
$(USPACEDIR)/srv/loader/loader \ |
$(USPACEDIR)/srv/devmap/devmap \ |
$(USPACEDIR)/srv/rd/rd \ |
$(USPACEDIR)/srv/vfs/vfs \ |
$(USPACEDIR)/srv/fs/tmpfs/tmpfs |
$(USPACEDIR)/srv/vfs/vfs |
ifeq ($(RDFMT),tmpfs) |
COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs |
endif |
ifeq ($(RDFMT),fat) |
COMPONENTS += $(USPACEDIR)/srv/fs/fat/fat |
endif |
RD_TASKS = \ |
$(USPACEDIR)/srv/fb/fb \ |
$(USPACEDIR)/srv/kbd/kbd \ |
$(USPACEDIR)/srv/console/console \ |
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \ |
$(USPACEDIR)/srv/fs/fat/fat \ |
$(USPACEDIR)/app/tetris/tetris \ |
$(USPACEDIR)/app/tester/tester \ |
$(USPACEDIR)/app/cli/cli \ |
$(USPACEDIR)/app/bdsh/bdsh \ |
$(USPACEDIR)/app/klog/klog |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
104,8 → 114,8 |
-include Makefile.depend |
image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) |
$(LD) -Map image.map -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) -o $@ |
image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) |
$(LD) -Map image.map -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) -o $@ |
depend: |
-makedepend $(DEFS) $(CFLAGS) -f - $(SOURCES) > Makefile.depend 2> /dev/null |
114,14 → 124,21 |
-for task in $(RD_TASKS) ; do \ |
rm -f $(USPACEDIR)/dist/sbin/`basename $$task` ; \ |
done |
-rm -f _components.h _components.c _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) initrd.img image.boot image.map image.disasm Makefile.depend |
-rm -f _components.h _components.c _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) initrd.img image.boot image.map image.disasm Makefile.depend |
_components.h _components.c _link.ld $(COMPONENT_OBJECTS) initrd.o: $(COMPONENTS) $(RD_TASKS) _link.ld.in |
for task in $(RD_TASKS) ; do \ |
cp $$task $(USPACEDIR)/dist/sbin/ ; \ |
done |
../../../../tools/mktmpfs.py 16384 $(USPACEDIR)/dist/ initrd.img |
../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 1 "unsigned long" $(COMPONENTS) ./initrd.img |
ifeq ($(RDFMT),tmpfs) |
../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ initrd.fs |
endif |
ifeq ($(RDFMT),fat) |
../../../../tools/mkfat.sh $(USPACEDIR)/dist/ initrd.fs |
endif |
../../../../tools/mkhord.py 16384 initrd.fs initrd.img |
rm initrd.fs |
../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 1 "unsigned long" $(COMPONENTS) |
%.o: %.S |
$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dynload/boot/arch/sparc64/silo/silo.conf |
---|
1,3 → 1,4 |
timeout = 0 |
image = /HelenOS/image.boot |
image = /HelenOS/image.boot.gz |
label = HelenOS |
initrd = /HelenOS/initrd.img |
/branches/dynload/boot/arch/ia64/Makefile.inc |
---|
28,23 → 28,6 |
#ifeq ($(MACHINE),ski) |
#VMAXLMA_SRC = tools/ia64/vmaxlma.c |
#build: $(BASE)/kernel.bin |
#echo Building SKI |
#$(BASE)/kernel.bin: $(KERNELDIR)/kernel.bin vmaxlma |
# cp $(KERNELDIR)/kernel.bin $(BASE)/kernel.bin |
# ./vmaxlma $(BASE)/kernel.bin |
#vmaxlma: $(VMAXLMA_SRC) |
# $(CC) $(VMAXLMA_SRC) -o $@ |
#clean: |
# -rm -f $(BASE)/kernel.bin vmaxlma |
#else |
build: $(BASE)/image.boot |
$(BASE)/image.boot: depend arch/$(ARCH)/loader/image.boot |
60,5 → 43,5 |
make -C arch/$(ARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) "DEFS=$(DEFS)" |
-rm -f $(BASE)/image.boot |
#endif |
#endif |
/branches/dynload/boot/arch/ia64/loader/Makefile |
---|
32,10 → 32,14 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf64-ia64-little |
BFD_ARCH = ia64 |
TARGET = ia64-pc-linux-gnu |
TOOLCHAIN_DIR = /usr/local/ia64/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ia64/bin |
ifeq ($(COMPILER),gcc_native) |
CC = gcc |
/branches/dynload/boot/arch/arm32/loader/asm.S |
---|
35,7 → 35,8 |
add r3, r1, #3 |
bic r3, r3, #3 |
cmp r1, r3 |
stmdb sp!, {r4, lr} |
stmdb sp!, {r4, r5, lr} |
mov r5, r0 |
beq 4f |
1: |
cmp r2, #0 |
48,8 → 49,8 |
cmp ip, r2 |
bne 2b |
3: |
mov r0, r1 |
ldmia sp!, {r4, pc} |
mov r0, r5 |
ldmia sp!, {r4, r5, pc} |
4: |
add r3, r0, #3 |
bic r3, r3, #3 |
/branches/dynload/boot/arch/arm32/loader/Makefile |
---|
32,10 → 32,14 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf32-littlearm |
BFD_ARCH = arm |
TARGET = arm-linux-gnu |
TOOLCHAIN_DIR = /usr/local/arm/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm/bin |
ifeq ($(COMPILER),gcc_native) |
CC = gcc |
84,18 → 88,24 |
$(USPACEDIR)/app/init/init \ |
$(USPACEDIR)/srv/devmap/devmap \ |
$(USPACEDIR)/srv/rd/rd \ |
$(USPACEDIR)/srv/vfs/vfs \ |
$(USPACEDIR)/srv/fs/tmpfs/tmpfs |
$(USPACEDIR)/srv/vfs/vfs |
ifeq ($(RDFMT),tmpfs) |
COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs |
endif |
ifeq ($(RDFMT),fat) |
COMPONENTS += $(USPACEDIR)/srv/fs/fat/fat |
endif |
RD_TASKS = \ |
$(USPACEDIR)/srv/fb/fb \ |
$(USPACEDIR)/srv/kbd/kbd \ |
$(USPACEDIR)/srv/console/console \ |
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \ |
$(USPACEDIR)/srv/fs/fat/fat \ |
$(USPACEDIR)/app/tetris/tetris \ |
$(USPACEDIR)/app/tester/tester \ |
$(USPACEDIR)/app/klog/klog \ |
$(USPACEDIR)/app/cli/cli |
$(USPACEDIR)/app/bdsh/bdsh |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
COMPONENT_OBJECTS := $(addsuffix .o,$(basename $(notdir $(COMPONENTS)))) |
122,7 → 132,14 |
for task in $(RD_TASKS) ; do \ |
cp $$task $(USPACEDIR)/dist/sbin/ ; \ |
done |
../../../../tools/mktmpfs.py 4096 $(USPACEDIR)/dist/ initrd.img |
ifeq ($(RDFMT),tmpfs) |
../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ initrd.fs |
endif |
ifeq ($(RDFMT),fat) |
../../../../tools/mkfat.sh $(USPACEDIR)/dist/ initrd.fs |
endif |
../../../../tools/mkhord.py 4096 initrd.fs initrd.img |
rm initrd.fs |
../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 4096 "unsigned int" $(COMPONENTS) ./initrd.img |
%.o: %.S |
/branches/dynload/boot/arch/ppc32/loader/main.c |
---|
116,15 → 116,11 |
halt(); |
} |
if (!ofw_screen(&bootinfo.screen)) { |
printf("Error: unable to get screen properties, halting.\n"); |
halt(); |
} |
if (!ofw_screen(&bootinfo.screen)) |
printf("Warning: unable to get screen properties.\n"); |
if (!ofw_keyboard(&bootinfo.keyboard)) { |
printf("Error: unable to get keyboard properties, halting.\n"); |
halt(); |
} |
if (!ofw_keyboard(&bootinfo.keyboard)) |
printf("Warning: unable to get keyboard properties.\n"); |
printf("\nDevice statistics\n"); |
printf(" screen at %L, resolution %dx%d, %d bpp (scanline %d bytes)\n", bootinfo.screen.addr, bootinfo.screen.width, bootinfo.screen.height, bootinfo.screen.bpp, bootinfo.screen.scanline); |
/branches/dynload/boot/arch/ppc32/loader/ofwarch.c |
---|
39,7 → 39,13 |
void write(const char *str, const int len) |
{ |
ofw_write(str, len); |
int i; |
for (i = 0; i < len; i++) { |
if (str[i] == '\n') |
ofw_write("\r", 1); |
ofw_write(&str[i], 1); |
} |
} |
int ofw_keyboard(keyboard_t *keyboard) |
/branches/dynload/boot/arch/ppc32/loader/Makefile |
---|
32,10 → 32,14 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf32-powerpc |
BFD_ARCH = powerpc:common |
TARGET = ppc-linux-gnu |
TOOLCHAIN_DIR = /usr/local/ppc/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc/bin |
ifeq ($(COMPILER),gcc_native) |
CC = gcc |
79,19 → 83,25 |
$(USPACEDIR)/app/init/init \ |
$(USPACEDIR)/srv/devmap/devmap \ |
$(USPACEDIR)/srv/rd/rd \ |
$(USPACEDIR)/srv/vfs/vfs \ |
$(USPACEDIR)/srv/fs/tmpfs/tmpfs |
$(USPACEDIR)/srv/vfs/vfs |
ifeq ($(RDFMT),tmpfs) |
COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs |
endif |
ifeq ($(RDFMT),fat) |
COMPONENTS += $(USPACEDIR)/srv/fs/fat/fat |
endif |
RD_TASKS = \ |
$(USPACEDIR)/srv/fb/fb \ |
$(USPACEDIR)/srv/kbd/kbd \ |
$(USPACEDIR)/srv/console/console \ |
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \ |
$(USPACEDIR)/srv/fs/fat/fat \ |
$(USPACEDIR)/app/tetris/tetris \ |
$(USPACEDIR)/app/tester/tester \ |
$(USPACEDIR)/app/cli/cli \ |
$(USPACEDIR)/app/dltest/dltest \ |
$(USPACEDIR)/app/klog/klog |
$(USPACEDIR)/app/klog/klog \ |
$(USPACEDIR)/app/bdsh/bdsh |
RD_LIBS = \ |
$(USPACEDIR)/lib/rtld/rtld.so \ |
128,7 → 138,14 |
for lib in $(RD_LIBS) ; do \ |
cp $$lib $(USPACEDIR)/dist/lib/ ; \ |
done |
../../../../tools/mktmpfs.py 4096 $(USPACEDIR)/dist/ initrd.img |
ifeq ($(RDFMT),tmpfs) |
../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ initrd.fs |
endif |
ifeq ($(RDFMT),fat) |
../../../../tools/mkfat.sh $(USPACEDIR)/dist/ initrd.fs |
endif |
../../../../tools/mkhord.py 4096 initrd.fs initrd.img |
rm initrd.fs |
../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 4096 "unsigned int" $(COMPONENTS) ./initrd.img |
%.o: %.S |
/branches/dynload/boot/arch/amd64/grub/menu.lst |
---|
10,5 → 10,6 |
module /boot/rd |
module /boot/vfs |
module /boot/tmpfs |
module /boot/fat |
module /boot/loader |
module /boot/initrd.img |
/branches/dynload/boot/arch/amd64/Makefile.inc |
---|
32,8 → 32,13 |
$(USPACEDIR)/app/init/init \ |
$(USPACEDIR)/srv/devmap/devmap \ |
$(USPACEDIR)/srv/rd/rd \ |
$(USPACEDIR)/srv/vfs/vfs \ |
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \ |
$(USPACEDIR)/srv/vfs/vfs |
ifeq ($(RDFMT),tmpfs) |
INIT_TASKS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs |
endif |
ifeq ($(RDFMT),fat) |
INIT_TASKS += $(USPACEDIR)/srv/fs/fat/fat |
endif |
RD_TASKS = \ |
$(USPACEDIR)/srv/pci/pci \ |
40,11 → 45,12 |
$(USPACEDIR)/srv/fb/fb \ |
$(USPACEDIR)/srv/kbd/kbd \ |
$(USPACEDIR)/srv/console/console \ |
$(USPACEDIR)/srv/fs/fat/fat \ |
$(USPACEDIR)/app/tetris/tetris \ |
$(USPACEDIR)/app/tester/tester \ |
$(USPACEDIR)/app/klog/klog \ |
$(USPACEDIR)/app/cli/cli |
$(USPACEDIR)/app/bdsh/bdsh \ |
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \ |
$(USPACEDIR)/srv/fs/fat/fat |
build: $(BASE)/image.iso |
51,7 → 57,12 |
$(BASE)/image.iso: arch/$(ARCH)/grub/stage2_eltorito arch/$(ARCH)/grub/menu.lst $(KERNELDIR)/kernel.bin $(INIT_TASKS) $(RD_TASKS) |
mkdir -p arch/$(ARCH)/iso/boot/grub |
cp arch/$(ARCH)/grub/stage2_eltorito arch/$(ARCH)/iso/boot/grub/ |
cp arch/$(ARCH)/grub/menu.lst arch/$(ARCH)/iso/boot/grub/ |
ifneq ($(RDFMT),tmpfs) |
cat arch/$(ARCH)/grub/menu.lst | grep -v "tmpfs" >arch/$(ARCH)/iso/boot/grub/menu.lst |
endif |
ifneq ($(RDFMT),fat) |
cat arch/$(ARCH)/grub/menu.lst | grep -v "fat" >arch/$(ARCH)/iso/boot/grub/menu.lst |
endif |
cp $(KERNELDIR)/kernel.bin arch/$(ARCH)/iso/boot/ |
for task in $(INIT_TASKS) ; do \ |
cp $$task arch/$(ARCH)/iso/boot/ ; \ |
59,7 → 70,14 |
for task in $(RD_TASKS) ; do \ |
cp $$task $(USPACEDIR)/dist/sbin/ ; \ |
done |
$(BASE)/tools/mktmpfs.py 4096 $(USPACEDIR)/dist/ arch/$(ARCH)/iso/boot/initrd.img |
ifeq ($(RDFMT),tmpfs) |
$(BASE)/tools/mktmpfs.py $(USPACEDIR)/dist/ arch/$(ARCH)/iso/boot/initrd.fs |
endif |
ifeq ($(RDFMT),fat) |
$(BASE)/tools/mkfat.sh $(USPACEDIR)/dist/ arch/$(ARCH)/iso/boot/initrd.fs |
endif |
$(BASE)/tools/mkhord.py 4096 arch/$(ARCH)/iso/boot/initrd.fs arch/$(ARCH)/iso/boot/initrd.img |
rm arch/$(ARCH)/iso/boot/initrd.fs |
mkisofs -J -r -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o $(BASE)/image.iso arch/$(ARCH)/iso/ |
clean: |
/branches/dynload/boot/arch/ppc64/loader/Makefile |
---|
32,10 → 32,14 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf64-powerpc |
BFD_ARCH = powerpc:common64 |
TARGET = ppc64-linux-gnu |
TOOLCHAIN_DIR = /usr/local/ppc64/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc64/bin |
ifeq ($(COMPILER),gcc_native) |
CC = gcc |
/branches/dynload/boot/arch/mips32/loader/asm.S |
---|
48,6 → 48,7 |
and $v0,$v0,$v1 |
beq $a1,$v0,3f |
move $t0,$a0 |
move $t2,$a0 # save dst |
0: |
beq $a2,$zero,2f |
63,7 → 64,7 |
2: |
jr $ra |
move $v0,$a1 |
move $v0,$t2 |
3: |
addiu $v0,$a0,3 |
103,7 → 104,7 |
sb $a0,0($v1) |
jr $ra |
move $v0,$a1 |
move $v0,$t2 |
jump_to_kernel: |
# |
/branches/dynload/boot/arch/mips32/loader/Makefile |
---|
32,6 → 32,10 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
ifeq ($(IMAGE),binary) |
LD_IN = binary |
endif |
41,7 → 45,7 |
BFD_NAME = elf32-tradlittlemips |
BFD_ARCH = mips |
TARGET = mipsel-linux-gnu |
TOOLCHAIN_DIR = /usr/local/mipsel/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mipsel/bin |
ifeq ($(COMPILER),gcc_native) |
CC = gcc |
84,17 → 88,23 |
$(USPACEDIR)/app/init/init \ |
$(USPACEDIR)/srv/devmap/devmap \ |
$(USPACEDIR)/srv/rd/rd \ |
$(USPACEDIR)/srv/vfs/vfs \ |
$(USPACEDIR)/srv/fs/tmpfs/tmpfs |
$(USPACEDIR)/srv/vfs/vfs |
ifeq ($(RDFMT),tmpfs) |
COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs |
endif |
ifeq ($(RDFMT),fat) |
COMPONENTS += $(USPACEDIR)/srv/fs/fat/fat |
endif |
RD_TASKS = \ |
$(USPACEDIR)/srv/fb/fb \ |
$(USPACEDIR)/srv/kbd/kbd \ |
$(USPACEDIR)/srv/console/console \ |
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \ |
$(USPACEDIR)/srv/fs/fat/fat \ |
$(USPACEDIR)/app/tetris/tetris \ |
$(USPACEDIR)/app/tester/tester \ |
$(USPACEDIR)/app/cli/cli \ |
$(USPACEDIR)/app/bdsh/bdsh \ |
$(USPACEDIR)/app/klog/klog |
123,7 → 133,14 |
for task in $(RD_TASKS) ; do \ |
cp $$task $(USPACEDIR)/dist/sbin/ ; \ |
done |
../../../../tools/mktmpfs.py 16384 $(USPACEDIR)/dist/ initrd.img |
ifeq ($(RDFMT),tmpfs) |
../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ initrd.fs |
endif |
ifeq ($(RDFMT),fat) |
../../../../tools/mkfat.sh $(USPACEDIR)/dist/ initrd.fs |
endif |
../../../../tools/mkhord.py 16384 initrd.fs initrd.img |
rm initrd.fs |
../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 16384 "unsigned int" $(COMPONENTS) ./initrd.img |
_link.ld.in: _link.ld.in.$(LD_IN) |
/branches/dynload/boot/arch/ia32/grub/menu.lst |
---|
10,5 → 10,6 |
module /boot/rd |
module /boot/vfs |
module /boot/tmpfs |
module /boot/fat |
module /boot/loader |
module /boot/initrd.img |
/branches/dynload/boot/arch/ia32/Makefile.inc |
---|
32,8 → 32,13 |
$(USPACEDIR)/app/init/init \ |
$(USPACEDIR)/srv/devmap/devmap \ |
$(USPACEDIR)/srv/rd/rd \ |
$(USPACEDIR)/srv/vfs/vfs \ |
$(USPACEDIR)/srv/fs/tmpfs/tmpfs |
$(USPACEDIR)/srv/vfs/vfs |
ifeq ($(RDFMT),tmpfs) |
INIT_TASKS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs |
endif |
ifeq ($(RDFMT),fat) |
INIT_TASKS += $(USPACEDIR)/srv/fs/fat/fat |
endif |
RD_TASKS = \ |
$(USPACEDIR)/srv/pci/pci \ |
43,9 → 48,9 |
$(USPACEDIR)/srv/fs/fat/fat \ |
$(USPACEDIR)/app/tetris/tetris \ |
$(USPACEDIR)/app/tester/tester \ |
$(USPACEDIR)/app/cli/cli \ |
$(USPACEDIR)/app/dltest/dltest \ |
$(USPACEDIR)/app/klog/klog |
$(USPACEDIR)/app/klog/klog \ |
$(USPACEDIR)/app/bdsh/bdsh |
RD_LIBS = \ |
$(USPACEDIR)/lib/rtld/rtld.so \ |
56,7 → 61,12 |
$(BASE)/image.iso: arch/$(ARCH)/grub/stage2_eltorito arch/$(ARCH)/grub/menu.lst $(KERNELDIR)/kernel.bin $(INIT_TASKS) $(RD_TASKS) $(RD_LIBS) |
mkdir -p arch/$(ARCH)/iso/boot/grub |
cp arch/$(ARCH)/grub/stage2_eltorito arch/$(ARCH)/iso/boot/grub/ |
cp arch/$(ARCH)/grub/menu.lst arch/$(ARCH)/iso/boot/grub/ |
ifneq ($(RDFMT),tmpfs) |
cat arch/$(ARCH)/grub/menu.lst | grep -v "tmpfs" >arch/$(ARCH)/iso/boot/grub/menu.lst |
endif |
ifneq ($(RDFMT),fat) |
cat arch/$(ARCH)/grub/menu.lst | grep -v "fat" >arch/$(ARCH)/iso/boot/grub/menu.lst |
endif |
cp $(KERNELDIR)/kernel.bin arch/$(ARCH)/iso/boot/ |
for task in $(INIT_TASKS) ; do \ |
cp $$task arch/$(ARCH)/iso/boot/ ; \ |
64,10 → 74,17 |
for task in $(RD_TASKS) ; do \ |
cp $$task $(USPACEDIR)/dist/sbin/ ; \ |
done |
for task in $(RD_LIBS) ; do \ |
cp $$task $(USPACEDIR)/dist/lib/ ; \ |
for lib in $(RD_LIBS) ; do \ |
cp $$lib $(USPACEDIR)/dist/lib/ ; \ |
done |
$(BASE)/tools/mktmpfs.py 4096 $(USPACEDIR)/dist/ arch/$(ARCH)/iso/boot/initrd.img |
ifeq ($(RDFMT),tmpfs) |
$(BASE)/tools/mktmpfs.py $(USPACEDIR)/dist/ arch/$(ARCH)/iso/boot/initrd.fs |
endif |
ifeq ($(RDFMT),fat) |
$(BASE)/tools/mkfat.sh $(USPACEDIR)/dist/ arch/$(ARCH)/iso/boot/initrd.fs |
endif |
$(BASE)/tools/mkhord.py 4096 arch/$(ARCH)/iso/boot/initrd.fs arch/$(ARCH)/iso/boot/initrd.img |
rm arch/$(ARCH)/iso/boot/initrd.fs |
mkisofs -J -r -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o $(BASE)/image.iso arch/$(ARCH)/iso/ |
clean: |
/branches/dynload/Makefile |
---|
82,11 → 82,6 |
UARCH = mips32 |
IMAGE = ecoff |
endif |
ifeq ($(MACHINE),indy) |
UARCH = mips32eb |
IMAGE = ecoff |
endif |
endif |
ifeq ($(PLATFORM),ppc32) |
139,7 → 134,7 |
-$(MAKE) -C kernel distclean |
-$(MAKE) -C uspace distclean |
-$(MAKE) -C boot distclean |
-rm Makefile.config |
rm -f Makefile.config tools/*.pyc |
clean: |
-$(MAKE) -C kernel clean |
147,6 → 142,6 |
-$(MAKE) -C boot clean |
cscope: |
-rm cscope.out |
-find kernel boot uspace -regex '^.*\.[chsS]$$' -print >srclist |
-cscope -bi srclist |
find kernel boot uspace -regex '^.*\.[chsS]$$' -print > srclist |
rm -f cscope.out |
cscope -bi srclist |