/branches/dynload/kernel/generic/include/stdarg.h |
---|
45,7 → 45,7 |
#define va_start(ap, last) __builtin_va_start(ap, last) |
#define va_arg(ap, type) __builtin_va_arg(ap, type) |
#define va_end(ap) __builtin_va_end(ap) |
#define va_copy(dst,src) __builtin_va_copy(dst,src) |
#define va_copy(dst, src) __builtin_va_copy(dst, src) |
#endif |
/branches/dynload/kernel/generic/src/ipc/kbox.c |
---|
45,6 → 45,7 |
void ipc_kbox_cleanup(void) |
{ |
ipl_t ipl; |
bool have_kb_thread; |
/* Only hold kb_cleanup_lock while setting kb_finished - this is enough */ |
63,6 → 64,17 |
* wake up and terminate. |
*/ |
ipc_answerbox_slam_phones(&TASK->kernel_box, have_kb_thread); |
/* |
* If the task was being debugged, clean up debugging session. |
* This is necessarry as slamming the phones won't force |
* kbox thread to clean it up since sender != debugger. |
*/ |
ipl = interrupts_disable(); |
spinlock_lock(&TASK->lock); |
udebug_task_cleanup(TASK); |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
if (have_kb_thread) { |
LOG("join kb_thread..\n"); |
79,13 → 91,75 |
spinlock_unlock(&TASK->kernel_box.lock); |
} |
/** Handle hangup message in kbox. |
* |
* @param call The IPC_M_PHONE_HUNGUP call structure. |
* @param last Output, the function stores @c true here if |
* this was the last phone, @c false otherwise. |
**/ |
static void kbox_proc_phone_hungup(call_t *call, bool *last) |
{ |
ipl_t ipl; |
LOG("kbox_proc_phone_hungup()\n"); |
/* Was it our debugger, who hung up? */ |
if (call->sender == TASK->udebug.debugger) { |
/* Terminate debugging session (if any) */ |
LOG("kbox: terminate debug session\n"); |
ipl = interrupts_disable(); |
spinlock_lock(&TASK->lock); |
udebug_task_cleanup(TASK); |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
} else { |
LOG("kbox: was not debugger\n"); |
} |
LOG("kbox: continue with hangup message\n"); |
IPC_SET_RETVAL(call->data, 0); |
ipc_answer(&TASK->kernel_box, call); |
ipl = interrupts_disable(); |
spinlock_lock(&TASK->lock); |
spinlock_lock(&TASK->answerbox.lock); |
if (list_empty(&TASK->answerbox.connected_phones)) { |
/* |
* Last phone has been disconnected. Detach this thread so it |
* gets freed and signal to the caller. |
*/ |
/* Only detach kbox thread unless already terminating. */ |
mutex_lock(&TASK->kb_cleanup_lock); |
if (&TASK->kb_finished == false) { |
/* Detach kbox thread so it gets freed from memory. */ |
thread_detach(TASK->kb_thread); |
TASK->kb_thread = NULL; |
} |
mutex_unlock(&TASK->kb_cleanup_lock); |
LOG("phone list is empty\n"); |
*last = true; |
} else { |
*last = false; |
} |
spinlock_unlock(&TASK->answerbox.lock); |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
} |
/** Implementing function for the kbox thread. |
* |
* This function listens for debug requests. It terminates |
* when all phones are disconnected from the kbox. |
* |
* @param arg Ignored. |
*/ |
static void kbox_thread_proc(void *arg) |
{ |
call_t *call; |
int method; |
bool done; |
ipl_t ipl; |
(void)arg; |
LOG("kbox_thread_proc()\n"); |
95,46 → 169,28 |
call = ipc_wait_for_call(&TASK->kernel_box, SYNCH_NO_TIMEOUT, |
SYNCH_FLAGS_NONE); |
if (call != NULL) { |
method = IPC_GET_METHOD(call->data); |
if (call == NULL) |
continue; /* Try again. */ |
if (method == IPC_M_DEBUG_ALL) { |
udebug_call_receive(call); |
} |
switch (IPC_GET_METHOD(call->data)) { |
if (method == IPC_M_PHONE_HUNGUP) { |
LOG("kbox: handle hangup message\n"); |
case IPC_M_DEBUG_ALL: |
/* Handle debug call. */ |
udebug_call_receive(call); |
break; |
/* Was it our debugger, who hung up? */ |
if (call->sender == TASK->udebug.debugger) { |
/* Terminate debugging session (if any) */ |
LOG("kbox: terminate debug session\n"); |
ipl = interrupts_disable(); |
spinlock_lock(&TASK->lock); |
udebug_task_cleanup(TASK); |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
} else { |
LOG("kbox: was not debugger\n"); |
} |
case IPC_M_PHONE_HUNGUP: |
/* |
* Process the hangup call. If this was the last |
* phone, done will be set to true and the |
* while loop will terminate. |
*/ |
kbox_proc_phone_hungup(call, &done); |
break; |
LOG("kbox: continue with hangup message\n"); |
IPC_SET_RETVAL(call->data, 0); |
ipc_answer(&TASK->kernel_box, call); |
ipl = interrupts_disable(); |
spinlock_lock(&TASK->lock); |
spinlock_lock(&TASK->answerbox.lock); |
if (list_empty(&TASK->answerbox.connected_phones)) { |
/* Last phone has been disconnected */ |
TASK->kb_thread = NULL; |
done = true; |
LOG("phone list is empty\n"); |
} |
spinlock_unlock(&TASK->answerbox.lock); |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
} |
default: |
/* Ignore */ |
break; |
} |
} |
/branches/dynload/kernel/generic/src/ipc/sysipc.c |
---|
822,12 → 822,16 |
ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC)); |
if (!(call->flags & IPC_CALL_DISCARD_ANSWER)) |
atomic_dec(&TASK->active_calls); |
if (call->flags & IPC_CALL_DISCARD_ANSWER) { |
ipc_call_free(call); |
goto restart; |
} else { |
/* |
* Decrement the counter of active calls only if the |
* call is not an answer to IPC_M_PHONE_HUNGUP, |
* which doesn't contribute to the counter. |
*/ |
atomic_dec(&TASK->active_calls); |
} |
STRUCT_TO_USPACE(&calldata->args, &call->data.args); |
/branches/dynload/kernel/generic/src/ipc/ipc.c |
---|
508,7 → 508,8 |
interrupts_restore(ipl); |
/* Free unused call */ |
if (call) ipc_call_free(call); |
if (call) |
ipc_call_free(call); |
} |
/** Cleans up all IPC communication of the current task. |
573,6 → 574,11 |
(call->flags & IPC_CALL_NOTIF)); |
ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC)); |
/* |
* Record the receipt of this call in the current task's counter |
* of active calls. IPC_M_PHONE_HUNGUP calls do not contribute |
* to this counter so do not record answers to them either. |
*/ |
if (!(call->flags & IPC_CALL_DISCARD_ANSWER)) |
atomic_dec(&TASK->active_calls); |
ipc_call_free(call); |
/branches/dynload/kernel/Makefile |
---|
44,7 → 44,7 |
GCC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) \ |
-fno-builtin -Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes -Werror \ |
-nostdlib -nostdinc |
-nostdlib -nostdinc -pipe |
ICC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) \ |
-fno-builtin -Wall -Wmissing-prototypes -Werror \ |
365,7 → 365,7 |
ln -sfn ../../genarch/include/ generic/include/genarch |
depend: archlinks |
-makedepend $(DEFS) $(CFLAGS) -f - $(ARCH_SOURCES) $(GENARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null |
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(ARCH_SOURCES) $(GENARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null |
arch/$(ARCH)/_link.ld: arch/$(ARCH)/_link.ld.in |
$(GCC) $(DEFS) $(GCC_CFLAGS) -D__ASM__ -D__LINKER__ -E -x c $< | grep -v "^\#" > $@ |
/branches/dynload/kernel/arch/sparc64/include/trap/regwin.h |
---|
39,6 → 39,7 |
#include <arch/stack.h> |
#include <arch/arch.h> |
#include <align.h> |
#define TT_CLEAN_WINDOW 0x24 |
#define TT_SPILL_0_NORMAL 0x80 /* kernel spills */ |
72,6 → 73,11 |
#define I6_OFFSET 112 |
#define I7_OFFSET 120 |
/* Uspace Window Buffer constants. */ |
#define UWB_SIZE ((NWINDOWS - 1) * STACK_WINDOW_SAVE_AREA_SIZE) |
#define UWB_ALIGNMENT 1024 |
#define UWB_ASIZE ALIGN_UP(UWB_SIZE, UWB_ALIGNMENT) |
#ifdef __ASM__ |
/* |
/branches/dynload/kernel/arch/sparc64/src/proc/thread.c |
---|
34,9 → 34,8 |
#include <proc/thread.h> |
#include <arch/proc/thread.h> |
#include <mm/frame.h> |
#include <mm/page.h> |
#include <arch/mm/page.h> |
#include <mm/slab.h> |
#include <arch/trap/regwin.h> |
#include <align.h> |
void thr_constructor_arch(thread_t *t) |
50,12 → 49,12 |
void thr_destructor_arch(thread_t *t) |
{ |
if (t->arch.uspace_window_buffer) { |
uintptr_t uw_buf = (uintptr_t) t->arch.uspace_window_buffer; |
/* |
* Mind the possible alignment of the userspace window buffer |
* belonging to a killed thread. |
*/ |
frame_free(KA2PA(ALIGN_DOWN((uintptr_t) |
t->arch.uspace_window_buffer, PAGE_SIZE))); |
free((uint8_t *) ALIGN_DOWN(uw_buf, UWB_ALIGNMENT)); |
} |
} |
67,7 → 66,7 |
* The thread needs userspace window buffer and the object |
* returned from the slab allocator doesn't have any. |
*/ |
t->arch.uspace_window_buffer = frame_alloc(ONE_FRAME, FRAME_KA); |
t->arch.uspace_window_buffer = malloc(UWB_ASIZE, 0); |
} else { |
uintptr_t uw_buf = (uintptr_t) t->arch.uspace_window_buffer; |
76,7 → 75,7 |
* belonging to a killed thread. |
*/ |
t->arch.uspace_window_buffer = (uint8_t *) ALIGN_DOWN(uw_buf, |
PAGE_SIZE); |
UWB_ASIZE); |
} |
} |
/branches/dynload/kernel/arch/sparc64/src/trap/trap_table.S |
---|
748,9 → 748,8 |
* Fill all windows stored in the buffer. |
*/ |
clr %g4 |
set PAGE_SIZE - 1, %g5 |
0: andcc %g7, %g5, %g0 ! PAGE_SIZE alignment check |
bz 0f ! %g7 is page-aligned, no more windows to refill |
0: andcc %g7, UWB_ALIGNMENT - 1, %g0 ! alignment check |
bz 0f ! %g7 is UWB_ALIGNMENT-aligned, no more windows to refill |
nop |
add %g7, -STACK_WINDOW_SAVE_AREA_SIZE, %g7 |
/branches/dynload/kernel/arch/ia64/include/asm.h |
---|
44,21 → 44,50 |
static inline void outb(uint64_t port,uint8_t v) |
{ |
*((char *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v; |
*((uint8_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v; |
asm volatile ("mf\n" ::: "memory"); |
} |
static inline void outw(uint64_t port,uint16_t v) |
{ |
*((uint16_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v; |
asm volatile ("mf\n" ::: "memory"); |
} |
static inline void outl(uint64_t port,uint32_t v) |
{ |
*((uint32_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v; |
asm volatile ("mf\n" ::: "memory"); |
} |
static inline uint8_t inb(uint64_t port) |
{ |
asm volatile ("mf\n" ::: "memory"); |
return *((char *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))); |
return *((uint8_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))); |
} |
static inline uint16_t inw(uint64_t port) |
{ |
asm volatile ("mf\n" ::: "memory"); |
return *((uint16_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xffE) | ( (port >> 2) << 12 )))); |
} |
static inline uint32_t inl(uint64_t port) |
{ |
asm volatile ("mf\n" ::: "memory"); |
return *((uint32_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))); |
} |
/** Return base address of current stack |
* |
* Return the base address of the current stack. |
/branches/dynload/kernel/arch/amd64/include/syscall.h |
---|
35,8 → 35,6 |
#ifndef KERN_amd64_SYSCALL_H_ |
#define KERN_amd64_SYSCALL_H_ |
#include <arch/types.h> |
extern void syscall_setup_cpu(void); |
#endif |
/branches/dynload/kernel/arch/ia32/include/syscall.h |
---|
0,0 → 1,0 |
link ../../amd64/include/syscall.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dynload/kernel/arch/ia32/include/asm.h |
---|
247,6 → 247,22 |
return v; |
} |
/** Write to MSR */ |
static inline void write_msr(uint32_t msr, uint64_t value) |
{ |
asm volatile ("wrmsr" : : "c" (msr), "a" ((uint32_t)(value)), |
"d" ((uint32_t)(value >> 32))); |
} |
static inline uint64_t read_msr(uint32_t msr) |
{ |
uint32_t ax, dx; |
asm volatile ("rdmsr" : "=a"(ax), "=d"(dx) : "c" (msr)); |
return ((uint64_t)dx << 32) | ax; |
} |
/** Return base address of current stack |
* |
* Return the base address of the current stack. |
/branches/dynload/kernel/arch/ia32/include/cpu.h |
---|
35,12 → 35,21 |
#ifndef KERN_ia32_CPU_H_ |
#define KERN_ia32_CPU_H_ |
#define EFLAGS_IF (1 << 9) |
#define EFLAGS_RF (1 << 16) |
#define CR4_OSFXSR_MASK (1<<9) |
/* Support for SYSENTER and SYSEXIT */ |
#define IA32_MSR_SYSENTER_CS 0x174 |
#define IA32_MSR_SYSENTER_ESP 0x175 |
#define IA32_MSR_SYSENTER_EIP 0x176 |
#ifndef __ASM__ |
#include <arch/pm.h> |
#include <arch/asm.h> |
#define EFLAGS_IF (1 << 9) |
#define EFLAGS_RF (1 << 16) |
typedef struct { |
int vendor; |
int family; |
51,9 → 60,8 |
count_t iomapver_copy; /** Copy of TASK's I/O Permission bitmap generation count. */ |
} cpu_arch_t; |
#endif |
#define CR4_OSFXSR_MASK (1<<9) |
#endif |
/** @} |
/branches/dynload/kernel/arch/ia32/Makefile.inc |
---|
160,4 → 160,5 |
arch/$(ARCH)/src/boot/boot.S \ |
arch/$(ARCH)/src/boot/memmap.c \ |
arch/$(ARCH)/src/fpu_context.c \ |
arch/$(ARCH)/src/debugger.c |
arch/$(ARCH)/src/debugger.c \ |
arch/$(ARCH)/src/syscall.c |
/branches/dynload/kernel/arch/ia32/src/asm.S |
---|
147,6 → 147,45 |
popfl |
.endm |
/* |
* The SYSENTER syscall mechanism can be used for syscalls with |
* four or fewer arguments. To pass these four arguments, we |
* use four registers: EDX, ECX, EBX, ESI. The syscall number |
* is passed in EAX. We use EDI to remember the return address |
* and EBP to remember the stack. The INT-based syscall mechanism |
* can actually handle six arguments plus the syscall number |
* entirely in registers. |
*/ |
.global sysenter_handler |
sysenter_handler: |
pushl %ebp # remember user stack |
pushl %edi # remember return user address |
pushl %gs # remember TLS |
pushl %eax # syscall number |
subl $8, %esp # unused sixth and fifth argument |
pushl %esi # fourth argument |
pushl %ebx # third argument |
pushl %ecx # second argument |
pushl %edx # first argument |
movw $16, %ax |
movw %ax, %ds |
movw %ax, %es |
cld |
call syscall_handler |
addl $28, %esp # remove arguments from stack |
pop %gs # restore TLS |
pop %edx # prepare return EIP for SYSEXIT |
pop %ecx # prepare userspace ESP for SYSEXIT |
sysexit # return to userspace |
## Declare interrupt handlers |
# |
# Declare interrupt handlers for n interrupt |
/branches/dynload/kernel/arch/ia32/src/cpu/cpu.c |
---|
42,6 → 42,7 |
#include <fpu_context.h> |
#include <arch/smp/apic.h> |
#include <arch/syscall.h> |
/* |
* Identification of CPUs. |
123,6 → 124,9 |
: "i" (CR4_OSFXSR_MASK|(1<<10)) |
); |
} |
/* Setup fast SYSENTER/SYSEXIT syscalls */ |
syscall_setup_cpu(); |
} |
void cpu_identify(void) |
/branches/dynload/kernel/arch/ia32/src/syscall.c |
---|
0,0 → 1,53 |
/* |
* 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 ia32 |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/syscall.h> |
#include <arch/cpu.h> |
#include <arch/asm.h> |
#include <arch/types.h> |
#include <arch/pm.h> |
/** Enable & setup support for SYSENTER/SYSEXIT */ |
void syscall_setup_cpu(void) |
{ |
extern void sysenter_handler(void); |
/* set kernel mode CS selector */ |
write_msr(IA32_MSR_SYSENTER_CS, selector(KTEXT_DES)); |
/* set kernel mode entry point */ |
write_msr(IA32_MSR_SYSENTER_EIP, (uint32_t) sysenter_handler); |
} |
/** @} |
*/ |
/branches/dynload/kernel/arch/ia32/src/proc/scheduler.c |
---|
58,8 → 58,14 |
*/ |
void before_thread_runs_arch(void) |
{ |
CPU->arch.tss->esp0 = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE - |
uintptr_t kstk = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE - |
SP_DELTA]; |
/* Set kernel stack for CP3 -> CPL0 switch via SYSENTER */ |
write_msr(IA32_MSR_SYSENTER_ESP, kstk); |
/* Set kernel stack for CPL3 -> CPL0 switch via interrupt */ |
CPU->arch.tss->esp0 = kstk; |
CPU->arch.tss->ss0 = selector(KDATA_DES); |
/* Set up TLS in GS register */ |
/branches/dynload/tools/mkfat.sh |
---|
File deleted |
Property changes: |
Deleted: svn:executable |
-* |
\ No newline at end of property |
/branches/dynload/tools/mkfat.py |
---|
34,7 → 34,273 |
import os |
import random |
import xstruct |
import array |
def align_up(size, alignment): |
"Return size aligned up to alignment" |
if (size % alignment == 0): |
return size |
return (((size / alignment) + 1) * alignment) |
def subtree_size(root, cluster_size, dirent_size): |
"Recursive directory walk and calculate size" |
size = 0 |
files = 2 |
for name in os.listdir(root): |
canon = os.path.join(root, name) |
if (os.path.isfile(canon)): |
size += align_up(os.path.getsize(canon), cluster_size) |
files += 1 |
if (os.path.isdir(canon)): |
size += subtree_size(canon, cluster_size, dirent_size) |
files += 1 |
return size + align_up(files * dirent_size, cluster_size) |
def root_entries(root): |
"Return number of root directory entries" |
return len(os.listdir(root)) |
def write_file(path, outf, cluster_size, data_start, fat, reserved_clusters): |
"Store the contents of a file" |
size = os.path.getsize(path) |
prev = -1 |
first = 0 |
inf = file(path, "r") |
rd = 0; |
while (rd < size): |
empty_cluster = fat.index(0) |
fat[empty_cluster] = 0xffff |
if (prev != -1): |
fat[prev] = empty_cluster |
else: |
first = empty_cluster |
prev = empty_cluster |
data = inf.read(cluster_size); |
outf.seek(data_start + (empty_cluster - reserved_clusters) * cluster_size) |
outf.write(data) |
rd += len(data) |
inf.close() |
return first, size |
def write_directory(directory, outf, cluster_size, data_start, fat, reserved_clusters, dirent_size, empty_cluster): |
"Store the contents of a directory" |
length = len(directory) |
size = length * dirent_size |
prev = -1 |
first = 0 |
i = 0 |
rd = 0; |
while (rd < size): |
if (prev != -1): |
empty_cluster = fat.index(0) |
fat[empty_cluster] = 0xffff |
fat[prev] = empty_cluster |
else: |
first = empty_cluster |
prev = empty_cluster |
data = '' |
data_len = 0 |
while ((i < length) and (data_len < cluster_size)): |
if (i == 0): |
directory[i].cluster = empty_cluster |
data += directory[i].pack() |
data_len += dirent_size |
i += 1 |
outf.seek(data_start + (empty_cluster - reserved_clusters) * cluster_size) |
outf.write(data) |
rd += len(data) |
return first, size |
DIR_ENTRY = """little: |
char name[8] /* file name */ |
char ext[3] /* file extension */ |
uint8_t attr /* file attributes */ |
padding[1] /* reserved for NT */ |
uint8_t ctime_fine /* create time (fine resolution) */ |
uint16_t ctime /* create time */ |
uint16_t cdate /* create date */ |
uint16_t adate /* access date */ |
padding[2] /* EA-index */ |
uint16_t mtime /* modification time */ |
uint16_t mdate /* modification date */ |
uint16_t cluster /* first cluster */ |
uint32_t size /* file size */ |
""" |
DOT_DIR_ENTRY = """little: |
uint8_t signature /* 0x2e signature */ |
char name[7] /* empty */ |
char ext[3] /* empty */ |
uint8_t attr /* file attributes */ |
padding[1] /* reserved for NT */ |
uint8_t ctime_fine /* create time (fine resolution) */ |
uint16_t ctime /* create time */ |
uint16_t cdate /* create date */ |
uint16_t adate /* access date */ |
padding[2] /* EA-index */ |
uint16_t mtime /* modification time */ |
uint16_t mdate /* modification date */ |
uint16_t cluster /* first cluster */ |
uint32_t size /* file size */ |
""" |
DOTDOT_DIR_ENTRY = """little: |
uint8_t signature[2] /* 0x2e signature */ |
char name[6] /* empty */ |
char ext[3] /* empty */ |
uint8_t attr /* file attributes */ |
padding[1] /* reserved for NT */ |
uint8_t ctime_fine /* create time (fine resolution) */ |
uint16_t ctime /* create time */ |
uint16_t cdate /* create date */ |
uint16_t adate /* access date */ |
padding[2] /* EA-index */ |
uint16_t mtime /* modification time */ |
uint16_t mdate /* modification date */ |
uint16_t cluster /* first cluster */ |
uint32_t size /* file size */ |
""" |
def mangle_fname(name): |
# FIXME: filter illegal characters |
parts = name.split('.') |
if (len(parts) > 0): |
fname = parts[0] |
else: |
fname = '' |
return (fname + ' ').upper()[0:8] |
def mangle_ext(name): |
# FIXME: filter illegal characters |
parts = name.split('.') |
if (len(parts) > 1): |
ext = parts[1] |
else: |
ext = '' |
return (ext + ' ').upper()[0:3] |
def create_dirent(name, directory, cluster, size): |
dir_entry = xstruct.create(DIR_ENTRY) |
dir_entry.name = mangle_fname(name) |
dir_entry.ext = mangle_ext(name) |
if (directory): |
dir_entry.attr = 0x30 |
else: |
dir_entry.attr = 0x20 |
dir_entry.ctime_fine = 0 # FIXME |
dir_entry.ctime = 0 # FIXME |
dir_entry.cdate = 0 # FIXME |
dir_entry.adate = 0 # FIXME |
dir_entry.mtime = 0 # FIXME |
dir_entry.mdate = 0 # FIXME |
dir_entry.cluster = cluster |
if (directory): |
dir_entry.size = 0 |
else: |
dir_entry.size = size |
return dir_entry |
def create_dot_dirent(empty_cluster): |
dir_entry = xstruct.create(DOT_DIR_ENTRY) |
dir_entry.signature = 0x2e |
dir_entry.name = ' ' |
dir_entry.ext = ' ' |
dir_entry.attr = 0x10 |
dir_entry.ctime_fine = 0 # FIXME |
dir_entry.ctime = 0 # FIXME |
dir_entry.cdate = 0 # FIXME |
dir_entry.adate = 0 # FIXME |
dir_entry.mtime = 0 # FIXME |
dir_entry.mdate = 0 # FIXME |
dir_entry.cluster = empty_cluster |
dir_entry.size = 0 |
return dir_entry |
def create_dotdot_dirent(parent_cluster): |
dir_entry = xstruct.create(DOTDOT_DIR_ENTRY) |
dir_entry.signature = [0x2e, 0x2e] |
dir_entry.name = ' ' |
dir_entry.ext = ' ' |
dir_entry.attr = 0x10 |
dir_entry.ctime_fine = 0 # FIXME |
dir_entry.ctime = 0 # FIXME |
dir_entry.cdate = 0 # FIXME |
dir_entry.adate = 0 # FIXME |
dir_entry.mtime = 0 # FIXME |
dir_entry.mdate = 0 # FIXME |
dir_entry.cluster = parent_cluster |
dir_entry.size = 0 |
return dir_entry |
def recursion(head, root, outf, cluster_size, root_start, data_start, fat, reserved_clusters, dirent_size, parent_cluster): |
"Recursive directory walk" |
directory = [] |
if (not head): |
# Directory cluster preallocation |
empty_cluster = fat.index(0) |
fat[empty_cluster] = 0xffff |
directory.append(create_dot_dirent(empty_cluster)) |
directory.append(create_dotdot_dirent(parent_cluster)) |
else: |
empty_cluster = 0 |
for name in os.listdir(root): |
canon = os.path.join(root, name) |
if (os.path.isfile(canon)): |
rv = write_file(canon, outf, cluster_size, data_start, fat, reserved_clusters) |
directory.append(create_dirent(name, False, rv[0], rv[1])) |
if (os.path.isdir(canon)): |
rv = recursion(False, canon, outf, cluster_size, root_start, data_start, fat, reserved_clusters, dirent_size, empty_cluster) |
directory.append(create_dirent(name, True, rv[0], rv[1])) |
if (head): |
outf.seek(root_start) |
for dir_entry in directory: |
outf.write(dir_entry.pack()) |
else: |
return write_directory(directory, outf, cluster_size, data_start, fat, reserved_clusters, dirent_size, empty_cluster) |
BOOT_SECTOR = """little: |
uint8_t jmp[3] /* jump instruction */ |
char oem[8] /* OEM string */ |
62,6 → 328,14 |
uint8_t boot_signature[2] /* boot signature */ |
""" |
EMPTY_SECTOR = """little: |
padding[512] /* empty sector data */ |
""" |
FAT_ENTRY = """little: |
uint16_t next /* FAT16 entry */ |
""" |
def usage(prname): |
"Print usage syntax" |
print prname + " <PATH> <IMAGE>" |
76,27 → 350,60 |
print "<PATH> must be a directory" |
return |
fat16_clusters = 4096 |
min_cluster_size = 1024 |
sector_size = 512 |
cluster_size = 4096 |
dirent_size = 32 |
fatent_size = 2 |
fat_count = 2 |
reserved_clusters = 2 |
# Make sure the filesystem is large enought for FAT16 |
size = subtree_size(path, cluster_size, dirent_size) + reserved_clusters * cluster_size |
while (size / cluster_size < fat16_clusters): |
if (cluster_size > min_cluster_size): |
cluster_size /= 2 |
size = subtree_size(path, cluster_size, dirent_size) + reserved_clusters * cluster_size |
else: |
size = fat16_clusters * cluster_size + reserved_clusters * cluster_size |
root_size = align_up(root_entries(path) * dirent_size, cluster_size) |
fat_size = align_up(align_up(size, cluster_size) / cluster_size * fatent_size, sector_size) |
sectors = (cluster_size + fat_count * fat_size + root_size + size) / sector_size |
root_start = cluster_size + fat_count * fat_size |
data_start = root_start + root_size |
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.sector = sector_size |
boot_sector.cluster = cluster_size / sector_size |
boot_sector.reserved = cluster_size / sector_size |
boot_sector.fats = fat_count |
boot_sector.rootdir = root_size / dirent_size |
if (sectors <= 65535): |
boot_sector.sectors = sectors |
else: |
boot_sector.sectors = 0 |
boot_sector.descriptor = 0xF8 |
boot_sector.fat_sectors = 0 # FIXME |
boot_sector.track_sectors = 0 # FIXME |
boot_sector.heads = 0 # FIXME |
boot_sector.fat_sectors = fat_size / sector_size |
boot_sector.track_sectors = 63 |
boot_sector.heads = 6 |
boot_sector.hidden = 0 |
boot_sector.sectors_big = 0 # FIXME |
if (sectors > 65535): |
boot_sector.sectors_big = sectors |
else: |
boot_sector.sectors_big = 0 |
boot_sector.drive = 0 |
boot_sector.drive = 0x80 |
boot_sector.extboot_signature = 0x29 |
boot_sector.serial = random.randint(0, 0xFFFFFFFF) |
boot_sector.serial = random.randint(0, 0x7fffffff) |
boot_sector.label = "HELENOS" |
boot_sector.fstype = "FAT16 " |
boot_sector.boot_signature = [0x55, 0xAA] |
103,6 → 410,39 |
outf.write(boot_sector.pack()) |
empty_sector = xstruct.create(EMPTY_SECTOR) |
# Reserved sectors |
for i in range(1, cluster_size / sector_size): |
outf.write(empty_sector.pack()) |
# FAT tables |
for i in range(0, fat_count): |
for j in range(0, fat_size / sector_size): |
outf.write(empty_sector.pack()) |
# Root directory |
for i in range(0, root_size / sector_size): |
outf.write(empty_sector.pack()) |
# Data |
for i in range(0, size / sector_size): |
outf.write(empty_sector.pack()) |
fat = array.array('L', [0] * (fat_size / fatent_size)) |
fat[0] = 0xfff8 |
fat[1] = 0xffff |
recursion(True, path, outf, cluster_size, root_start, data_start, fat, reserved_clusters, dirent_size, 0) |
# Store FAT |
fat_entry = xstruct.create(FAT_ENTRY) |
for i in range(0, fat_count): |
outf.seek(cluster_size + i * fat_size) |
for j in range(0, fat_size / fatent_size): |
fat_entry.next = fat[j] |
outf.write(fat_entry.pack()) |
outf.close() |
if __name__ == '__main__': |
/branches/dynload/uspace/app/bdsh/cmds/modules/cat/cat.c |
---|
103,13 → 103,11 |
} |
do { |
memset(buff, 0, sizeof(buff)); |
bytes = read(fd, buff, blen); |
if (bytes > 0) { |
count += bytes; |
if (bytes < blen) |
buff[bytes] = '\0'; |
printf(buff); |
buff[bytes] = '\0'; |
printf("%s", buff); |
reads++; |
} |
} while (bytes > 0); |
/branches/dynload/uspace/app/bdsh/util.c |
---|
70,125 → 70,6 |
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) |
{ |
273,10 → 154,7 |
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; |
} |
asprintf(&usr->prompt, "%s # ", usr->cwd); |
return 0; |
} |
/branches/dynload/uspace/app/bdsh/util.h |
---|
5,8 → 5,6 |
/* 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 *); |
/branches/dynload/uspace/app/bdsh/exec.c |
---|
117,7 → 117,7 |
tmp = cli_strdup(find_command(cmd)); |
free(found); |
tid = task_spawn((const char *)tmp, (const char **)argv); |
tid = task_spawn((const char *)tmp, argv); |
free(tmp); |
if (tid == 0) { |
/branches/dynload/uspace/app/tester/tester.c |
---|
147,6 → 147,8 |
} |
} |
return 0; |
} |
/** @} |
/branches/dynload/uspace/app/tester/ipc/send_sync.c |
---|
35,7 → 35,6 |
{ |
int phoneid; |
int res; |
static int msgid = 1; |
char c; |
printf("Select phoneid to send msg: 2-9 (q to skip)\n"); |
/branches/dynload/uspace/app/trace/trace.c |
---|
35,7 → 35,6 |
#include <stdio.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <syscall.h> |
#include <ipc/ipc.h> |
#include <fibril.h> |
#include <errno.h> |
44,6 → 43,8 |
#include <task.h> |
#include <loader/loader.h> |
#include <libc.h> |
// Temporary: service and method names |
#include "proto.h" |
#include <ipc/services.h> |
/branches/dynload/uspace/lib/libfs/libfs.c |
---|
36,7 → 36,6 |
#include "libfs.h" |
#include "../../srv/vfs/vfs.h" |
#include "../../srv/rd/rd.h" |
#include <errno.h> |
#include <async.h> |
#include <ipc/ipc.h> |
331,62 → 330,5 |
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,9 → 69,6 |
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/libfs/Makefile |
---|
57,7 → 57,7 |
find . -name '*.o' -follow -exec rm \{\} \; |
depend: |
-makedepend $(DEFS) $(CFLAGS) -f - $(SOURCES) > Makefile.depend 2> /dev/null |
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null |
libfs.a: depend $(OBJECTS) |
$(AR) rc libfs.a $(OBJECTS) |
/branches/dynload/uspace/lib/softfloat/Makefile |
---|
66,7 → 66,7 |
find generic/ -name '*.o' -follow -exec rm \{\} \; |
depend: |
-makedepend $(DEFS) $(CFLAGS) -f - $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null |
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null |
libsoftfloat.a: depend $(ARCH_OBJECTS) $(GENERIC_OBJECTS) |
$(AR) rc libsoftfloat.a $(ARCH_OBJECTS) $(GENERIC_OBJECTS) |
/branches/dynload/uspace/lib/libblock/libblock.c |
---|
0,0 → 1,298 |
/* |
* Copyright (c) 2008 Jakub Jermar |
* 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 libblock |
* @{ |
*/ |
/** |
* @file |
* @brief |
*/ |
#include "libblock.h" |
#include "../../srv/vfs/vfs.h" |
#include "../../srv/rd/rd.h" |
#include <ipc/devmap.h> |
#include <ipc/services.h> |
#include <errno.h> |
#include <sys/mman.h> |
#include <async.h> |
#include <ipc/ipc.h> |
#include <as.h> |
#include <assert.h> |
#include <futex.h> |
#include <libadt/list.h> |
/** Lock protecting the device connection list */ |
static futex_t dcl_lock = FUTEX_INITIALIZER; |
/** Device connection list head. */ |
static LIST_INITIALIZE(dcl_head); |
typedef struct { |
link_t link; |
int dev_handle; |
int dev_phone; |
void *com_area; |
size_t com_size; |
void *bb_buf; |
off_t bb_off; |
size_t bb_size; |
} devcon_t; |
static devcon_t *devcon_search(dev_handle_t dev_handle) |
{ |
link_t *cur; |
futex_down(&dcl_lock); |
for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) { |
devcon_t *devcon = list_get_instance(cur, devcon_t, link); |
if (devcon->dev_handle == dev_handle) { |
futex_up(&dcl_lock); |
return devcon; |
} |
} |
futex_up(&dcl_lock); |
return NULL; |
} |
static int devcon_add(dev_handle_t dev_handle, int dev_phone, void *com_area, |
size_t com_size, void *bb_buf, off_t bb_off, size_t bb_size) |
{ |
link_t *cur; |
devcon_t *devcon; |
devcon = malloc(sizeof(devcon_t)); |
if (!devcon) |
return ENOMEM; |
link_initialize(&devcon->link); |
devcon->dev_handle = dev_handle; |
devcon->dev_phone = dev_phone; |
devcon->com_area = com_area; |
devcon->com_size = com_size; |
devcon->bb_buf = bb_buf; |
devcon->bb_off = bb_off; |
devcon->bb_size = bb_size; |
futex_down(&dcl_lock); |
for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) { |
devcon_t *d = list_get_instance(cur, devcon_t, link); |
if (d->dev_handle == dev_handle) { |
futex_up(&dcl_lock); |
free(devcon); |
return EEXIST; |
} |
} |
list_append(&devcon->link, &dcl_head); |
futex_up(&dcl_lock); |
return EOK; |
} |
static void devcon_remove(devcon_t *devcon) |
{ |
futex_down(&dcl_lock); |
list_remove(&devcon->link); |
futex_up(&dcl_lock); |
} |
int |
block_init(dev_handle_t dev_handle, size_t com_size, off_t bb_off, |
size_t bb_size) |
{ |
int rc; |
int dev_phone; |
void *com_area; |
void *bb_buf; |
bb_buf = malloc(bb_size); |
if (!bb_buf) |
return ENOMEM; |
com_area = mmap(NULL, com_size, PROTO_READ | PROTO_WRITE, |
MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); |
if (!com_area) { |
free(bb_buf); |
return ENOMEM; |
} |
dev_phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, |
DEVMAP_CONNECT_TO_DEVICE, dev_handle); |
if (dev_phone < 0) { |
free(bb_buf); |
munmap(com_area, com_size); |
return dev_phone; |
} |
rc = ipc_share_out_start(dev_phone, com_area, |
AS_AREA_READ | AS_AREA_WRITE); |
if (rc != EOK) { |
free(bb_buf); |
munmap(com_area, com_size); |
ipc_hangup(dev_phone); |
return rc; |
} |
rc = devcon_add(dev_handle, dev_phone, com_area, com_size, bb_buf, |
bb_off, bb_size); |
if (rc != EOK) { |
free(bb_buf); |
munmap(com_area, com_size); |
ipc_hangup(dev_phone); |
return rc; |
} |
off_t bufpos = 0; |
size_t buflen = 0; |
if (!block_read(dev_handle, &bufpos, &buflen, &bb_off, |
bb_buf, bb_size, bb_size)) { |
block_fini(dev_handle); |
return EIO; /* XXX real error code */ |
} |
return EOK; |
} |
void block_fini(dev_handle_t dev_handle) |
{ |
devcon_t *devcon = devcon_search(dev_handle); |
assert(devcon); |
devcon_remove(devcon); |
free(devcon->bb_buf); |
munmap(devcon->com_area, devcon->com_size); |
ipc_hangup(devcon->dev_phone); |
free(devcon); |
} |
void *block_bb_get(dev_handle_t dev_handle) |
{ |
devcon_t *devcon = devcon_search(dev_handle); |
assert(devcon); |
return devcon->bb_buf; |
} |
/** Read data from a block device. |
* |
* @param dev_handle Device handle of the block 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 |
block_read(int dev_handle, 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; |
devcon_t *devcon = devcon_search(dev_handle); |
assert(devcon); |
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, devcon->com_area + *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(devcon->dev_phone, RD_READ_BLOCK, |
*pos / block_size, block_size, &retval); |
if ((rc != EOK) || (retval != EOK)) |
return false; |
*bufpos = 0; |
*buflen = block_size; |
} |
} |
return true; |
} |
block_t *block_get(dev_handle_t dev_handle, off_t offset, size_t bs) |
{ |
/* FIXME */ |
block_t *b; |
off_t bufpos = 0; |
size_t buflen = 0; |
off_t pos = offset * bs; |
b = malloc(sizeof(block_t)); |
if (!b) |
return NULL; |
b->data = malloc(bs); |
if (!b->data) { |
free(b); |
return NULL; |
} |
b->size = bs; |
if (!block_read(dev_handle, &bufpos, &buflen, &pos, b->data, |
bs, bs)) { |
free(b->data); |
free(b); |
return NULL; |
} |
return b; |
} |
void block_put(block_t *block) |
{ |
/* FIXME */ |
free(block->data); |
free(block); |
} |
/** @} |
*/ |
/branches/dynload/uspace/lib/libblock/libblock.h |
---|
0,0 → 1,83 |
/* |
* Copyright (c) 2008 Jakub Jermar |
* 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 libblock |
* @{ |
*/ |
/** |
* @file |
*/ |
#ifndef LIBBLOCK_LIBBLOCK_H_ |
#define LIBBLOCK_LIBBLOCK_H_ |
#include <stdint.h> |
#include "../../srv/vfs/vfs.h" |
#include <futex.h> |
#include <rwlock.h> |
#include <libadt/hash_table.h> |
#include <libadt/list.h> |
typedef struct block { |
/** Futex protecting the reference count. */ |
futex_t lock; |
/** Number of references to the block_t structure. */ |
unsigned refcnt; |
/** If true, the block needs to be written back to the block device. */ |
bool dirty; |
/** Readers / Writer lock protecting the contents of the block. */ |
rwlock_t contents_lock; |
/** Handle of the device where the block resides. */ |
dev_handle_t dev_handle; |
/** Block offset on the block device. Counted in 'size'-byte blocks. */ |
off_t boff; |
/** Size of the block. */ |
size_t size; |
/** Link for placing the block into the free block list. */ |
link_t free_link; |
/** Link for placing the block into the block hash table. */ |
link_t hash_link; |
/** Buffer with the block data. */ |
void *data; |
} block_t; |
extern int block_init(dev_handle_t, size_t, off_t, size_t); |
extern void block_fini(dev_handle_t); |
extern void *block_bb_get(dev_handle_t); |
extern block_t *block_get(dev_handle_t, off_t, size_t); |
extern void block_put(block_t *); |
extern bool block_read(int, off_t *, size_t *, off_t *, void *, size_t, size_t); |
#endif |
/** @} |
*/ |
/branches/dynload/uspace/lib/libblock/Makefile |
---|
0,0 → 1,66 |
# |
# Copyright (c) 2005 Martin Decky |
# Copyright (c) 2007 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. |
# |
## Common compiler flags |
# |
LIBC_PREFIX = ../libc |
## Setup toolchain |
# |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += -Iinclude |
## Sources |
# |
SOURCES = \ |
libblock.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
.PHONY: all clean depend |
all: libblock.a |
-include Makefile.depend |
clean: |
-rm -f libblock.a Makefile.depend |
find . -name '*.o' -follow -exec rm \{\} \; |
depend: |
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null |
libblock.a: depend $(OBJECTS) |
$(AR) rc libblock.a $(OBJECTS) |
%.o: %.c |
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@ |
/branches/dynload/uspace/lib/softint/Makefile |
---|
63,7 → 63,7 |
find generic/ \( -name '*.o' -o -name '*.pio' \) -follow -exec rm \{\} \; |
depend: |
-makedepend $(DEFS) $(CFLAGS) -f - $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null |
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null |
-makedepend $(DEFS) $(PIC_CFLAGS) -o.pio -f - $(GENERIC_SOURCES) >> Makefile.depend 2> /dev/null |
libsoftint.a: depend $(OBJECTS) |
/branches/dynload/uspace/lib/libc/include/align.h |
---|
35,21 → 35,28 |
#ifndef LIBC_ALIGN_H_ |
#define LIBC_ALIGN_H_ |
/** Align to the nearest lower address. |
/** Align to the nearest lower address which is a power of two. |
* |
* @param s Address or size to be aligned. |
* @param a Size of alignment, must be power of 2. |
* @param s Address or size to be aligned. |
* @param a Size of alignment, must be power of 2. |
*/ |
#define ALIGN_DOWN(s, a) ((s) & ~((a) - 1)) |
/** Align to the nearest higher address. |
/** Align to the nearest higher address which is a power of two. |
* |
* @param s Address or size to be aligned. |
* @param a Size of alignment, must be power of 2. |
* @param s Address or size to be aligned. |
* @param a Size of alignment, must be power of 2. |
*/ |
#define ALIGN_UP(s, a) ((long)((s) + ((a) - 1)) & ~((long) (a) - 1)) |
/** Round up to the nearest higher boundary. |
* |
* @param n Number to be aligned. |
* @param b Boundary, arbitrary unsigned number. |
*/ |
#define ROUND_UP(n, b) (((n) / (b) + ((n) % (b) != 0)) * (b)) |
#endif |
/** @} |
/branches/dynload/uspace/lib/libc/include/byteorder.h |
---|
52,6 → 52,14 |
#define uint32_t_be2host(n) (n) |
#define uint64_t_be2host(n) (n) |
#define host2uint16_t_le(n) uint16_t_byteorder_swap(n) |
#define host2uint32_t_le(n) uint32_t_byteorder_swap(n) |
#define host2uint64_t_le(n) uint64_t_byteorder_swap(n) |
#define host2uint16_t_be(n) (n) |
#define host2uint32_t_be(n) (n) |
#define host2uint64_t_be(n) (n) |
#else |
#define uint16_t_le2host(n) (n) |
62,6 → 70,14 |
#define uint32_t_be2host(n) uint32_t_byteorder_swap(n) |
#define uint64_t_be2host(n) uint64_t_byteorder_swap(n) |
#define host2uint16_t_le(n) (n) |
#define host2uint32_t_le(n) (n) |
#define host2uint64_t_le(n) (n) |
#define host2uint16_t_be(n) uint16_t_byteorder_swap(n) |
#define host2uint32_t_be(n) uint32_t_byteorder_swap(n) |
#define host2uint64_t_be(n) uint64_t_byteorder_swap(n) |
#endif |
static inline uint64_t uint64_t_byteorder_swap(uint64_t n) |
/branches/dynload/uspace/lib/libc/include/syscall.h |
---|
32,15 → 32,28 |
/** |
* @file |
* @brief Syscall function declaration for architectures that don't |
* inline syscalls. |
* inline syscalls or architectures that handle syscalls |
* according to the number of arguments. |
*/ |
#ifndef LIBC_SYSCALL_H_ |
#define LIBC_SYSCALL_H_ |
#ifndef LIBARCH_SYSCALL_GENERIC |
#error "You can't include this file directly." |
#endif |
#include <sys/types.h> |
#include <kernel/syscall/syscall.h> |
#define __syscall0 __syscall |
#define __syscall1 __syscall |
#define __syscall2 __syscall |
#define __syscall3 __syscall |
#define __syscall4 __syscall |
#define __syscall5 __syscall |
#define __syscall6 __syscall |
extern sysarg_t __syscall(const sysarg_t p1, const sysarg_t p2, |
const sysarg_t p3, const sysarg_t p4, const sysarg_t p5, const sysarg_t p6, |
const syscall_t id); |
/branches/dynload/uspace/lib/libc/include/libc.h |
---|
39,14 → 39,14 |
#include <kernel/syscall/syscall.h> |
#include <libarch/syscall.h> |
#define __SYSCALL0(id) __syscall(0, 0, 0, 0, 0, 0, id) |
#define __SYSCALL1(id, p1) __syscall(p1, 0, 0, 0, 0, 0, id) |
#define __SYSCALL2(id, p1, p2) __syscall(p1, p2, 0, 0, 0, 0, id) |
#define __SYSCALL3(id, p1, p2, p3) __syscall(p1, p2, p3, 0, 0, 0, id) |
#define __SYSCALL4(id, p1, p2, p3, p4) __syscall(p1, p2, p3, p4, 0, 0, id) |
#define __SYSCALL5(id, p1, p2, p3, p4, p5) __syscall(p1, p2, p3, p4, p5, 0, id) |
#define __SYSCALL0(id) __syscall0(0, 0, 0, 0, 0, 0, id) |
#define __SYSCALL1(id, p1) __syscall1(p1, 0, 0, 0, 0, 0, id) |
#define __SYSCALL2(id, p1, p2) __syscall2(p1, p2, 0, 0, 0, 0, id) |
#define __SYSCALL3(id, p1, p2, p3) __syscall3(p1, p2, p3, 0, 0, 0, id) |
#define __SYSCALL4(id, p1, p2, p3, p4) __syscall4(p1, p2, p3, p4, 0, 0, id) |
#define __SYSCALL5(id, p1, p2, p3, p4, p5) __syscall5(p1, p2, p3, p4, p5, 0, id) |
#define __SYSCALL6(id, p1, p2, p3, p4, p5, p6) \ |
__syscall(p1, p2, p3, p4, p5, p6,id) |
__syscall6(p1, p2, p3, p4, p5, p6, id) |
extern void __main(void *pcb_ptr); |
extern void __exit(void); |
/branches/dynload/uspace/lib/libc/include/loader/loader.h |
---|
36,6 → 36,8 |
#ifndef LIBC_LOADER_H_ |
#define LIBC_LOADER_H_ |
#include <task.h> |
/** Abstraction of a loader connection */ |
typedef struct { |
/** ID of the phone connected to the loader. */ |
/branches/dynload/uspace/lib/libc/include/ipc/ipc.h |
---|
283,8 → 283,9 |
extern int ipc_share_out_finalize(ipc_callid_t callid, void *dst); |
extern int ipc_data_read_start(int phoneid, void *dst, size_t size); |
extern int ipc_data_read_receive(ipc_callid_t *callid, size_t *size); |
extern int ipc_data_read_finalize(ipc_callid_t callid, void *src, size_t size); |
extern int ipc_data_write_start(int phoneid, void *src, size_t size); |
extern int ipc_data_read_finalize(ipc_callid_t callid, const void *src, |
size_t size); |
extern int ipc_data_write_start(int phoneid, const void *src, size_t size); |
extern int ipc_data_write_receive(ipc_callid_t *callid, size_t *size); |
extern int ipc_data_write_finalize(ipc_callid_t callid, void *dst, size_t size); |
/branches/dynload/uspace/lib/libc/include/errno.h |
---|
46,6 → 46,7 |
#define EBADF (-262) |
#define ERANGE (-263) |
#define EXDEV (-264) |
#define EIO (-265) |
#endif |
/branches/dynload/uspace/lib/libc/Makefile.toolchain |
---|
27,7 → 27,7 |
# |
DEFS = -DARCH=$(ARCH) |
CFLAGS = -fno-builtin -Wall -Werror-implicit-function-declaration -Wmissing-prototypes -O3 -nostdlib -nostdinc -I$(LIBC_PREFIX)/include |
CFLAGS = -fno-builtin -Wall -Werror-implicit-function-declaration -Wmissing-prototypes -O3 -nostdlib -nostdinc -I$(LIBC_PREFIX)/include -pipe |
LFLAGS = -M -N $(SOFTINT_PREFIX)/libsoftint.a |
AFLAGS = |
#-Werror |
/branches/dynload/uspace/lib/libc/generic/time.c |
---|
47,6 → 47,8 |
#include <as.h> |
#include <ddi.h> |
#include <time.h> |
/* Pointers to public variables with time */ |
struct { |
volatile sysarg_t seconds1; |
/branches/dynload/uspace/lib/libc/generic/tls.c |
---|
116,7 → 116,7 |
tcb_t *tcb; |
size = ALIGN_UP(size, &_tls_alignment); |
*data = memalign(&_tls_alignment, sizeof(tcb_t) + size); |
*data = memalign((uintptr_t) &_tls_alignment, sizeof(tcb_t) + size); |
tcb = (tcb_t *) (*data + size); |
tcb->self = tcb; |
/branches/dynload/uspace/lib/libc/generic/loader.c |
---|
35,6 → 35,7 |
#include <ipc/ipc.h> |
#include <ipc/loader.h> |
#include <libc.h> |
#include <task.h> |
#include <string.h> |
#include <stdlib.h> |
#include <async.h> |
93,7 → 94,7 |
/* Get task ID. */ |
req = async_send_0(ldr->phone_id, LOADER_GET_TASKID, &answer); |
rc = ipc_data_read_start(ldr->phone_id, task_id, sizeof(task_id)); |
rc = ipc_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t)); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
return rc; |
/branches/dynload/uspace/lib/libc/generic/ipc.c |
---|
847,7 → 847,7 |
* |
* @return Zero on success or a value from @ref errno.h on failure. |
*/ |
int ipc_data_read_finalize(ipc_callid_t callid, void *src, size_t size) |
int ipc_data_read_finalize(ipc_callid_t callid, const void *src, size_t size) |
{ |
return ipc_answer_2(callid, EOK, (ipcarg_t) src, (ipcarg_t) size); |
} |
860,7 → 860,7 |
* |
* @return Zero on success or a negative error code from errno.h. |
*/ |
int ipc_data_write_start(int phoneid, void *src, size_t size) |
int ipc_data_write_start(int phoneid, const void *src, size_t size) |
{ |
return async_req_2_0(phoneid, IPC_M_DATA_WRITE, (ipcarg_t) src, |
(ipcarg_t) size); |
/branches/dynload/uspace/lib/libc/generic/udebug.c |
---|
34,7 → 34,6 |
#include <udebug.h> |
#include <sys/types.h> |
#include <syscall.h> |
#include <ipc/ipc.h> |
#include <async.h> |
/branches/dynload/uspace/lib/libc/generic/vfs/vfs.c |
---|
116,7 → 116,7 |
return vfs_phone; |
} |
static int device_get_handle(char *name, dev_handle_t *handle) |
static int device_get_handle(const char *name, dev_handle_t *handle) |
{ |
int phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, DEVMAP_CLIENT, |
0); |
364,9 → 364,9 |
} |
} |
off_t newoffs; |
ipcarg_t newoffs; |
rc = async_req_3_1(vfs_phone, VFS_SEEK, fildes, offset, whence, |
(ipcarg_t)&newoffs); |
&newoffs); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
374,7 → 374,7 |
if (rc != EOK) |
return (off_t) -1; |
return newoffs; |
return (off_t) newoffs; |
} |
int ftruncate(int fildes, off_t length) |
/branches/dynload/uspace/lib/libc/generic/vfs/canonify.c |
---|
36,6 → 36,7 |
*/ |
#include <stdlib.h> |
#include <vfs/canonify.h> |
/** Token types used for tokenization of path. */ |
typedef enum { |
/branches/dynload/uspace/lib/libc/generic/smc.c |
---|
34,6 → 34,7 |
#include <libc.h> |
#include <sys/types.h> |
#include <smc.h> |
int smc_coherence(void *address, size_t size) |
{ |
/branches/dynload/uspace/lib/libc/Makefile |
---|
111,7 → 111,7 |
find . \( -name '*.o' -o -name '*.pio' \) -follow -exec rm \{\} \; |
depend: kerninc |
-makedepend $(DEFS) $(CFLAGS) -f - $(ARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null |
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(ARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null |
-makedepend $(DEFS) $(PIC_CFLAGS) -o.pio -f - $(ARCH_SOURCES) $(GENERIC_SOURCES) >> Makefile.depend 2> /dev/null |
libc.a: depend $(OBJECTS) |
/branches/dynload/uspace/lib/libc/arch/sparc64/include/syscall.h |
---|
38,6 → 38,14 |
#include <sys/types.h> |
#include <kernel/syscall/syscall.h> |
#define __syscall0 __syscall |
#define __syscall1 __syscall |
#define __syscall2 __syscall |
#define __syscall3 __syscall |
#define __syscall4 __syscall |
#define __syscall5 __syscall |
#define __syscall6 __syscall |
static inline sysarg_t |
__syscall(const sysarg_t p1, const sysarg_t p2, const sysarg_t p3, |
const sysarg_t p4, const sysarg_t p5, const sysarg_t p6, const syscall_t id) |
/branches/dynload/uspace/lib/libc/arch/ia64/include/syscall.h |
---|
36,6 → 36,8 |
#ifndef LIBC_ia64_SYSCALL_H_ |
#define LIBC_ia64_SYSCALL_H_ |
#define LIBARCH_SYSCALL_GENERIC |
#include <syscall.h> |
#endif |
/branches/dynload/uspace/lib/libc/arch/arm32/include/syscall.h |
---|
30,12 → 30,14 |
* @{ |
*/ |
/** @file |
* @brief Empty. |
* @brief |
*/ |
#ifndef LIBC_arm32_SYSCALL_H_ |
#define LIBC_arm32_SYSCALL_H_ |
#define LIBARCH_SYSCALL_GENERIC |
#include <syscall.h> |
#endif |
/branches/dynload/uspace/lib/libc/arch/ppc32/include/syscall.h |
---|
36,6 → 36,8 |
#ifndef LIBC_ppc32_SYSCALL_H_ |
#define LIBC_ppc32_SYSCALL_H_ |
#define LIBARCH_SYSCALL_GENERIC |
#include <syscall.h> |
#endif |
/branches/dynload/uspace/lib/libc/arch/amd64/include/syscall.h |
---|
36,6 → 36,8 |
#ifndef LIBC_amd64_SYSCALL_H_ |
#define LIBC_amd64_SYSCALL_H_ |
#define LIBARCH_SYSCALL_GENERIC |
#include <syscall.h> |
#endif |
/branches/dynload/uspace/lib/libc/arch/ppc64/include/syscall.h |
---|
36,6 → 36,8 |
#ifndef LIBC_ppc64_SYSCALL_H_ |
#define LIBC_ppc64_SYSCALL_H_ |
#define LIBARCH_SYSCALL_GENERIC |
#include <syscall.h> |
#endif |
/branches/dynload/uspace/lib/libc/arch/mips32/include/syscall.h |
---|
36,6 → 36,8 |
#ifndef LIBC_mips32_SYSCALL_H_ |
#define LIBC_mips32_SYSCALL_H_ |
#define LIBARCH_SYSCALL_GENERIC |
#include <syscall.h> |
#endif |
/branches/dynload/uspace/lib/libc/arch/ia32/include/syscall.h |
---|
36,8 → 36,25 |
#ifndef LIBC_ia32_SYSCALL_H_ |
#define LIBC_ia32_SYSCALL_H_ |
#include <syscall.h> |
#include <sys/types.h> |
#include <kernel/syscall/syscall.h> |
#define __syscall0 __syscall_sysenter |
#define __syscall1 __syscall_sysenter |
#define __syscall2 __syscall_sysenter |
#define __syscall3 __syscall_sysenter |
#define __syscall4 __syscall_sysenter |
#define __syscall5 __syscall_int |
#define __syscall6 __syscall_int |
extern sysarg_t |
__syscall_sysenter(const sysarg_t, const sysarg_t, const sysarg_t, const sysarg_t, |
const sysarg_t, const sysarg_t, const syscall_t); |
extern sysarg_t |
__syscall_int(const sysarg_t, const sysarg_t, const sysarg_t, const sysarg_t, |
const sysarg_t, const sysarg_t, const syscall_t); |
#endif |
/** @} |
/branches/dynload/uspace/lib/libc/arch/ia32/src/syscall.S |
---|
28,14 → 28,14 |
.text |
/** Syscall wrapper. |
/** Syscall wrapper - INT $0x30 version. |
* |
* Mind the order of arguments. First two arguments and the syscall number go to |
* scratch registers. An optimized version of this wrapper for fewer arguments |
* could benefit from this and not save unused registers on the stack. |
*/ |
.global __syscall |
__syscall: |
.global __syscall_int |
__syscall_int: |
pushl %ebx |
pushl %esi |
pushl %edi |
53,3 → 53,38 |
popl %esi |
popl %ebx |
ret |
/** Syscall wrapper - SYSENTER version. |
* |
* This is an optimized version of syscall for four or less arguments. Note |
* that EBP and EDI are used to remember user stack address and the return |
* address. The kernel part doesn't save DS, ES and FS so the handler restores |
* these to the selector immediately following CS (it must be the flat data |
* segment, otherwise the SYSENTER wouldn't work in the first place). |
*/ |
.global __syscall_sysenter |
__syscall_sysenter: |
pushl %ebx |
pushl %esi |
pushl %edi |
pushl %ebp |
mov %esp, %ebp |
lea ra, %edi |
movl 20(%esp), %edx # First argument. |
movl 24(%esp), %ecx # Second argument. |
movl 28(%esp), %ebx # Third argument. |
movl 32(%esp), %esi # Fourth argument. |
movl 44(%esp), %eax # Syscall number. |
sysenter |
ra: |
movw %cs, %cx |
addw $8, %cx |
movw %cx, %ds |
movw %cx, %es |
movw %cx, %fs |
popl %ebp |
popl %edi |
popl %esi |
popl %ebx |
ret |
/branches/dynload/uspace/srv/loader/main.c |
---|
100,7 → 100,7 |
if (len > sizeof(task_id)) len = sizeof(task_id); |
ipc_data_write_finalize(callid, &task_id, len); |
ipc_data_read_finalize(callid, &task_id, len); |
ipc_answer_0(rid, EOK); |
} |
/branches/dynload/uspace/srv/fs/tmpfs/tmpfs_dump.c |
---|
38,17 → 38,12 |
#include "tmpfs.h" |
#include "../../vfs/vfs.h" |
#include <ipc/ipc.h> |
#include <async.h> |
#include <errno.h> |
#include <stdlib.h> |
#include <string.h> |
#include <sys/types.h> |
#include <as.h> |
#include <libfs.h> |
#include <ipc/services.h> |
#include <ipc/devmap.h> |
#include <sys/mman.h> |
#include <libblock.h> |
#include <byteorder.h> |
#define TMPFS_BLOCK_SIZE 1024 |
59,8 → 54,8 |
} __attribute__((packed)); |
static bool |
tmpfs_restore_recursion(int phone, void *block, off_t *bufpos, size_t *buflen, |
off_t *pos, tmpfs_dentry_t *parent) |
tmpfs_restore_recursion(int dev, off_t *bufpos, size_t *buflen, off_t *pos, |
tmpfs_dentry_t *parent) |
{ |
struct rdentry entry; |
libfs_ops_t *ops = &tmpfs_libfs_ops; |
70,8 → 65,8 |
tmpfs_dentry_t *node; |
uint32_t size; |
if (!libfs_blockread(phone, block, bufpos, buflen, pos, &entry, |
sizeof(entry), TMPFS_BLOCK_SIZE)) |
if (!block_read(dev, bufpos, buflen, pos, &entry, sizeof(entry), |
TMPFS_BLOCK_SIZE)) |
return false; |
entry.len = uint32_t_le2host(entry.len); |
90,8 → 85,8 |
return false; |
} |
if (!libfs_blockread(phone, block, bufpos, buflen, pos, |
fname, entry.len, TMPFS_BLOCK_SIZE)) { |
if (!block_read(dev, bufpos, buflen, pos, fname, |
entry.len, TMPFS_BLOCK_SIZE)) { |
ops->destroy((void *) node); |
free(fname); |
return false; |
105,8 → 100,8 |
} |
free(fname); |
if (!libfs_blockread(phone, block, bufpos, buflen, pos, |
&size, sizeof(size), TMPFS_BLOCK_SIZE)) |
if (!block_read(dev, bufpos, buflen, pos, &size, |
sizeof(size), TMPFS_BLOCK_SIZE)) |
return false; |
size = uint32_t_le2host(size); |
116,8 → 111,8 |
return false; |
node->size = size; |
if (!libfs_blockread(phone, block, bufpos, buflen, pos, |
node->data, size, TMPFS_BLOCK_SIZE)) |
if (!block_read(dev, bufpos, buflen, pos, node->data, |
size, TMPFS_BLOCK_SIZE)) |
return false; |
break; |
132,7 → 127,7 |
return false; |
} |
if (!libfs_blockread(phone, block, bufpos, buflen, pos, |
if (!block_read(dev, bufpos, buflen, pos, |
fname, entry.len, TMPFS_BLOCK_SIZE)) { |
ops->destroy((void *) node); |
free(fname); |
147,8 → 142,8 |
} |
free(fname); |
if (!tmpfs_restore_recursion(phone, block, bufpos, |
buflen, pos, node)) |
if (!tmpfs_restore_recursion(dev, bufpos, buflen, pos, |
node)) |
return false; |
break; |
163,31 → 158,18 |
bool tmpfs_restore(dev_handle_t dev) |
{ |
libfs_ops_t *ops = &tmpfs_libfs_ops; |
int rc; |
void *block = mmap(NULL, TMPFS_BLOCK_SIZE, |
PROTO_READ | PROTO_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); |
rc = block_init(dev, TMPFS_BLOCK_SIZE, 0, 0); |
if (rc != EOK) |
return false; |
if (block == NULL) |
return false; |
int phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, |
DEVMAP_CONNECT_TO_DEVICE, dev); |
if (phone < 0) { |
munmap(block, TMPFS_BLOCK_SIZE); |
return false; |
} |
if (ipc_share_out_start(phone, block, AS_AREA_READ | AS_AREA_WRITE) != |
EOK) |
goto error; |
off_t bufpos = 0; |
size_t buflen = 0; |
off_t pos = 0; |
char tag[6]; |
if (!libfs_blockread(phone, block, &bufpos, &buflen, &pos, tag, 5, |
if (!block_read(dev, &bufpos, &buflen, &pos, tag, 5, |
TMPFS_BLOCK_SIZE)) |
goto error; |
195,17 → 177,15 |
if (strcmp(tag, "TMPFS") != 0) |
goto error; |
if (!tmpfs_restore_recursion(phone, block, &bufpos, &buflen, &pos, |
if (!tmpfs_restore_recursion(dev, &bufpos, &buflen, &pos, |
ops->root_get(dev))) |
goto error; |
ipc_hangup(phone); |
munmap(block, TMPFS_BLOCK_SIZE); |
block_fini(dev); |
return true; |
error: |
ipc_hangup(phone); |
munmap(block, TMPFS_BLOCK_SIZE); |
block_fini(dev); |
return false; |
} |
/branches/dynload/uspace/srv/fs/tmpfs/Makefile |
---|
31,12 → 31,16 |
LIBC_PREFIX = ../../../lib/libc |
LIBFS_PREFIX = ../../../lib/libfs |
LIBBLOCK_PREFIX = ../../../lib/libblock |
SOFTINT_PREFIX = ../../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += -I $(LIBFS_PREFIX) |
CFLAGS += -I $(LIBFS_PREFIX) -I $(LIBBLOCK_PREFIX) |
LIBS = $(LIBC_PREFIX)/libc.a $(LIBFS_PREFIX)/libfs.a |
LIBS = \ |
$(LIBFS_PREFIX)/libfs.a \ |
$(LIBBLOCK_PREFIX)/libblock.a \ |
$(LIBC_PREFIX)/libc.a |
## Sources |
# |
/branches/dynload/uspace/srv/fs/fat/fat.h |
---|
33,6 → 33,7 |
#ifndef FAT_FAT_H_ |
#define FAT_FAT_H_ |
#include "fat_fat.h" |
#include <ipc/ipc.h> |
#include <libfs.h> |
#include <atomic.h> |
44,7 → 45,12 |
#define dprintf(...) printf(__VA_ARGS__) |
#endif |
typedef struct { |
#define min(a, b) ((a) < (b) ? (a) : (b)) |
#define BS_BLOCK 0 |
#define BS_SIZE 512 |
typedef struct fat_bs { |
uint8_t ji[3]; /**< Jump instruction. */ |
uint8_t oem_name[8]; |
/* BIOS Parameter Block */ |
115,34 → 121,6 |
}; |
} __attribute__ ((packed)) fat_bs_t; |
#define FAT_ATTR_RDONLY (1 << 0) |
#define FAT_ATTR_VOLLABEL (1 << 3) |
#define FAT_ATTR_SUBDIR (1 << 4) |
typedef struct { |
uint8_t name[8]; |
uint8_t ext[3]; |
uint8_t attr; |
uint8_t reserved; |
uint8_t ctime_fine; |
uint16_t ctime; |
uint16_t cdate; |
uint16_t adate; |
union { |
uint16_t eaidx; /* FAT12/FAT16 */ |
uint16_t firstc_hi; /* FAT32 */ |
}; |
uint16_t mtime; |
uint16_t mdate; |
union { |
uint16_t firstc; /* FAT12/FAT16 */ |
uint16_t firstc_lo; /* FAT32 */ |
}; |
uint32_t size; |
} __attribute__ ((packed)) fat_dentry_t; |
typedef uint16_t fat_cluster_t; |
typedef enum { |
FAT_INVALID, |
FAT_DIRECTORY, |
223,6 → 201,7 |
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 void fat_write(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_dentry.c |
---|
0,0 → 1,100 |
/* |
* 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 fs |
* @{ |
*/ |
/** |
* @file fat_dentry.c |
* @brief Functions that work with FAT directory entries. |
*/ |
#include "fat_dentry.h" |
#define FAT_PAD ' ' |
#define FAT_DENTRY_UNUSED 0x00 |
#define FAT_DENTRY_E5_ESC 0x05 |
#define FAT_DENTRY_DOT 0x2e |
#define FAT_DENTRY_ERASED 0xe5 |
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) |
break; |
if (d->name[i] == FAT_DENTRY_E5_ESC) |
*buf++ = 0xe5; |
else |
*buf++ = d->name[i]; |
} |
if (d->ext[0] != FAT_PAD) |
*buf++ = '.'; |
for (i = 0; i < FAT_EXT_LEN; i++) { |
if (d->ext[i] == FAT_PAD) { |
*buf = '\0'; |
return; |
} |
if (d->ext[i] == FAT_DENTRY_E5_ESC) |
*buf++ = 0xe5; |
else |
*buf++ = d->ext[i]; |
} |
*buf = '\0'; |
} |
fat_dentry_clsf_t fat_classify_dentry(fat_dentry_t *d) |
{ |
if (d->attr & FAT_ATTR_VOLLABEL) { |
/* volume label entry */ |
return FAT_DENTRY_SKIP; |
} |
if (d->name[0] == FAT_DENTRY_ERASED) { |
/* not-currently-used entry */ |
return FAT_DENTRY_SKIP; |
} |
if (d->name[0] == FAT_DENTRY_UNUSED) { |
/* never used entry */ |
return FAT_DENTRY_LAST; |
} |
if (d->name[0] == FAT_DENTRY_DOT) { |
/* |
* Most likely '.' or '..'. |
* It cannot occur in a regular file name. |
*/ |
return FAT_DENTRY_SKIP; |
} |
return FAT_DENTRY_VALID; |
} |
/** |
* @} |
*/ |
/branches/dynload/uspace/srv/fs/fat/fat_dentry.h |
---|
0,0 → 1,80 |
/* |
* 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 fs |
* @{ |
*/ |
#ifndef FAT_FAT_DENTRY_H_ |
#define FAT_FAT_DENTRY_H_ |
#include <stdint.h> |
#define FAT_NAME_LEN 8 |
#define FAT_EXT_LEN 3 |
#define FAT_ATTR_RDONLY (1 << 0) |
#define FAT_ATTR_VOLLABEL (1 << 3) |
#define FAT_ATTR_SUBDIR (1 << 4) |
typedef enum { |
FAT_DENTRY_SKIP, |
FAT_DENTRY_LAST, |
FAT_DENTRY_VALID |
} fat_dentry_clsf_t; |
typedef struct { |
uint8_t name[8]; |
uint8_t ext[3]; |
uint8_t attr; |
uint8_t reserved; |
uint8_t ctime_fine; |
uint16_t ctime; |
uint16_t cdate; |
uint16_t adate; |
union { |
uint16_t eaidx; /* FAT12/FAT16 */ |
uint16_t firstc_hi; /* FAT32 */ |
}; |
uint16_t mtime; |
uint16_t mdate; |
union { |
uint16_t firstc; /* FAT12/FAT16 */ |
uint16_t firstc_lo; /* FAT32 */ |
}; |
uint32_t size; |
} __attribute__ ((packed)) fat_dentry_t; |
extern void dentry_name_canonify(fat_dentry_t *, char *); |
extern fat_dentry_clsf_t fat_classify_dentry(fat_dentry_t *); |
#endif |
/** |
* @} |
*/ |
/branches/dynload/uspace/srv/fs/fat/fat_fat.c |
---|
0,0 → 1,384 |
/* |
* 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 fs |
* @{ |
*/ |
/** |
* @file fat_fat.c |
* @brief Functions that manipulate the File Allocation Tables. |
*/ |
#include "fat_fat.h" |
#include "fat_dentry.h" |
#include "fat.h" |
#include "../../vfs/vfs.h" |
#include <libfs.h> |
#include <libblock.h> |
#include <errno.h> |
#include <byteorder.h> |
#include <align.h> |
#include <assert.h> |
#include <futex.h> |
/** |
* The fat_alloc_lock futex protects all copies of the File Allocation Table |
* during allocation of clusters. The lock does not have to be held durring |
* deallocation of clusters. |
*/ |
static futex_t fat_alloc_lock = FUTEX_INITIALIZER; |
/** Read block from file located on a FAT file system. |
* |
* @param bs Buffer holding the boot sector of the file system. |
* @param dev_handle Device handle of the file system. |
* @param firstc First cluster used by the file. Can be zero if the file |
* is empty. |
* @param offset Offset in blocks. |
* |
* @return Block structure holding the requested block. |
*/ |
block_t * |
_fat_block_get(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc, |
off_t offset) |
{ |
block_t *b; |
unsigned bps; |
unsigned spc; |
unsigned rscnt; /* block address of the first FAT */ |
unsigned fatcnt; |
unsigned rde; |
unsigned rds; /* root directory size */ |
unsigned sf; |
unsigned ssa; /* size of the system area */ |
unsigned clusters; |
fat_cluster_t clst = firstc; |
unsigned i; |
bps = uint16_t_le2host(bs->bps); |
spc = bs->spc; |
rscnt = uint16_t_le2host(bs->rscnt); |
fatcnt = bs->fatcnt; |
rde = uint16_t_le2host(bs->root_ent_max); |
sf = uint16_t_le2host(bs->sec_per_fat); |
rds = (sizeof(fat_dentry_t) * rde) / bps; |
rds += ((sizeof(fat_dentry_t) * rde) % bps != 0); |
ssa = rscnt + fatcnt * sf + rds; |
if (firstc == FAT_CLST_ROOT) { |
/* root directory special case */ |
assert(offset < rds); |
b = block_get(dev_handle, rscnt + fatcnt * sf + offset, bps); |
return b; |
} |
clusters = offset / spc; |
for (i = 0; i < clusters; i++) { |
unsigned fsec; /* sector offset relative to FAT1 */ |
unsigned fidx; /* FAT1 entry index */ |
assert(clst >= FAT_CLST_FIRST && clst < FAT_CLST_BAD); |
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); |
assert(clst < FAT_CLST_LAST1); |
block_put(b); |
} |
b = block_get(dev_handle, ssa + (clst - FAT_CLST_FIRST) * spc + |
offset % spc, bps); |
return b; |
} |
/** Return number of blocks allocated to a file. |
* |
* @param bs Buffer holding the boot sector for the file. |
* @param dev_handle Device handle of the device with the file. |
* @param firstc First cluster of the file. |
* @param lastc If non-NULL, output argument holding the |
* last cluster. |
* |
* @return Number of blocks allocated to the file. |
*/ |
uint16_t |
_fat_blcks_get(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc, |
fat_cluster_t *lastc) |
{ |
block_t *b; |
unsigned bps; |
unsigned spc; |
unsigned rscnt; /* block address of the first FAT */ |
unsigned clusters = 0; |
fat_cluster_t clst = firstc; |
bps = uint16_t_le2host(bs->bps); |
spc = bs->spc; |
rscnt = uint16_t_le2host(bs->rscnt); |
if (firstc == FAT_CLST_RES0) { |
/* No space allocated to the file. */ |
if (lastc) |
*lastc = firstc; |
return 0; |
} |
while (clst < FAT_CLST_LAST1) { |
unsigned fsec; /* sector offset relative to FAT1 */ |
unsigned fidx; /* FAT1 entry index */ |
assert(clst >= FAT_CLST_FIRST); |
if (lastc) |
*lastc = clst; /* remember the last cluster */ |
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++; |
} |
if (lastc) |
*lastc = clst; |
return clusters * spc; |
} |
/** Fill the gap between EOF and a new file position. |
* |
* @param bs Buffer holding the boot sector for nodep. |
* @param nodep FAT node with the gap. |
* @param mcl First cluster in an independent cluster chain that will |
* be later appended to the end of the node's own cluster |
* chain. If pos is still in the last allocated cluster, |
* this argument is ignored. |
* @param pos Position in the last node block. |
*/ |
void fat_fill_gap(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl, off_t pos) |
{ |
uint16_t bps; |
unsigned spc; |
block_t *b; |
off_t o, boundary; |
bps = uint16_t_le2host(bs->bps); |
spc = bs->spc; |
boundary = ROUND_UP(nodep->size, bps * spc); |
/* zero out already allocated space */ |
for (o = nodep->size - 1; o < pos && o < boundary; |
o = ALIGN_DOWN(o + bps, bps)) { |
b = fat_block_get(bs, nodep, o / bps); |
memset(b->data + o % bps, 0, bps - o % bps); |
b->dirty = true; /* need to sync node */ |
block_put(b); |
} |
if (o >= pos) |
return; |
/* zero out the initial part of the new cluster chain */ |
for (o = boundary; o < pos; o += bps) { |
b = _fat_block_get(bs, nodep->idx->dev_handle, mcl, |
(o - boundary) / bps); |
memset(b->data, 0, min(bps, pos - o)); |
b->dirty = true; /* need to sync node */ |
block_put(b); |
} |
} |
/** Mark cluster in one instance of FAT. |
* |
* @param bs Buffer holding the boot sector for the file system. |
* @param dev_handle Device handle for the file system. |
* @param fatno Number of the FAT instance where to make the change. |
* @param clst Cluster which is to be marked. |
* @param value Value mark the cluster with. |
*/ |
void |
fat_mark_cluster(fat_bs_t *bs, dev_handle_t dev_handle, unsigned fatno, |
fat_cluster_t clst, fat_cluster_t value) |
{ |
block_t *b; |
uint16_t bps; |
uint16_t rscnt; |
uint16_t sf; |
fat_cluster_t *cp; |
bps = uint16_t_le2host(bs->bps); |
rscnt = uint16_t_le2host(bs->rscnt); |
sf = uint16_t_le2host(bs->sec_per_fat); |
assert(fatno < bs->fatcnt); |
b = block_get(dev_handle, rscnt + sf * fatno + |
(clst * sizeof(fat_cluster_t)) / bps, bps); |
cp = (fat_cluster_t *)b->data + clst % (bps / sizeof(fat_cluster_t)); |
*cp = host2uint16_t_le(value); |
b->dirty = true; /* need to sync block */ |
block_put(b); |
} |
/** Replay the allocatoin of clusters in all shadow instances of FAT. |
* |
* @param bs Buffer holding the boot sector of the file system. |
* @param dev_handle Device handle of the file system. |
* @param lifo Chain of allocated clusters. |
* @param nclsts Number of clusters in the lifo chain. |
*/ |
void fat_alloc_shadow_clusters(fat_bs_t *bs, dev_handle_t dev_handle, |
fat_cluster_t *lifo, unsigned nclsts) |
{ |
uint8_t fatno; |
unsigned c; |
for (fatno = FAT1 + 1; fatno < bs->fatcnt; fatno++) { |
for (c = 0; c < nclsts; c++) { |
fat_mark_cluster(bs, dev_handle, fatno, lifo[c], |
c == 0 ? FAT_CLST_LAST1 : lifo[c - 1]); |
} |
} |
} |
/** Allocate clusters in FAT1. |
* |
* This function will attempt to allocate the requested number of clusters in |
* the first FAT instance. The FAT will be altered so that the allocated |
* clusters form an independent chain (i.e. a chain which does not belong to any |
* file yet). |
* |
* @param bs Buffer holding the boot sector of the file system. |
* @param dev_handle Device handle of the file system. |
* @param nclsts Number of clusters to allocate. |
* @param mcl Output parameter where the first cluster in the chain |
* will be returned. |
* @param lcl Output parameter where the last cluster in the chain |
* will be returned. |
* |
* @return EOK on success, a negative error code otherwise. |
*/ |
int |
fat_alloc_clusters(fat_bs_t *bs, dev_handle_t dev_handle, unsigned nclsts, |
fat_cluster_t *mcl, fat_cluster_t *lcl) |
{ |
uint16_t bps; |
uint16_t rscnt; |
uint16_t sf; |
block_t *blk; |
fat_cluster_t *lifo; /* stack for storing free cluster numbers */ |
unsigned found = 0; /* top of the free cluster number stack */ |
unsigned b, c, cl; |
lifo = (fat_cluster_t *) malloc(nclsts * sizeof(fat_cluster_t)); |
if (lifo) |
return ENOMEM; |
bps = uint16_t_le2host(bs->bps); |
rscnt = uint16_t_le2host(bs->rscnt); |
sf = uint16_t_le2host(bs->sec_per_fat); |
/* |
* Search FAT1 for unused clusters. |
*/ |
futex_down(&fat_alloc_lock); |
for (b = 0, cl = 0; b < sf; blk++) { |
blk = block_get(dev_handle, rscnt + b, bps); |
for (c = 0; c < bps / sizeof(fat_cluster_t); c++, cl++) { |
fat_cluster_t *clst = (fat_cluster_t *)blk->data + c; |
if (uint16_t_le2host(*clst) == FAT_CLST_RES0) { |
/* |
* The cluster is free. Put it into our stack |
* of found clusters and mark it as non-free. |
*/ |
lifo[found] = cl; |
*clst = (found == 0) ? |
host2uint16_t_le(FAT_CLST_LAST1) : |
host2uint16_t_le(lifo[found - 1]); |
blk->dirty = true; /* need to sync block */ |
if (++found == nclsts) { |
/* we are almost done */ |
block_put(blk); |
/* update the shadow copies of FAT */ |
fat_alloc_shadow_clusters(bs, |
dev_handle, lifo, nclsts); |
*mcl = lifo[found - 1]; |
*lcl = lifo[0]; |
free(lifo); |
futex_up(&fat_alloc_lock); |
return EOK; |
} |
} |
} |
block_put(blk); |
} |
futex_up(&fat_alloc_lock); |
/* |
* We could not find enough clusters. Now we need to free the clusters |
* we have allocated so far. |
*/ |
while (found--) { |
fat_mark_cluster(bs, dev_handle, FAT1, lifo[found], |
FAT_CLST_RES0); |
} |
free(lifo); |
return ENOSPC; |
} |
/** Append a cluster chain to the last file cluster in all FATs. |
* |
* @param bs Buffer holding boot sector of the file system. |
* @param nodep Node representing the file. |
* @param mcl First cluster of the cluster chain to append. |
*/ |
void fat_append_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl) |
{ |
dev_handle_t dev_handle = nodep->idx->dev_handle; |
fat_cluster_t lcl; |
uint8_t fatno; |
if (_fat_blcks_get(bs, dev_handle, nodep->firstc, &lcl) == 0) { |
nodep->firstc = host2uint16_t_le(mcl); |
nodep->dirty = true; /* need to sync node */ |
return; |
} |
for (fatno = FAT1; fatno < bs->fatcnt; fatno++) |
fat_mark_cluster(bs, nodep->idx->dev_handle, fatno, lcl, mcl); |
} |
/** |
* @} |
*/ |
/branches/dynload/uspace/srv/fs/fat/fat_fat.h |
---|
0,0 → 1,83 |
/* |
* 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 fs |
* @{ |
*/ |
#ifndef FAT_FAT_FAT_H_ |
#define FAT_FAT_FAT_H_ |
#include "../../vfs/vfs.h" |
#include <stdint.h> |
#define FAT1 0 |
#define FAT_CLST_RES0 0x0000 |
#define FAT_CLST_RES1 0x0001 |
#define FAT_CLST_FIRST 0x0002 |
#define FAT_CLST_BAD 0xfff7 |
#define FAT_CLST_LAST1 0xfff8 |
#define FAT_CLST_LAST8 0xffff |
/* internally used to mark root directory's parent */ |
#define FAT_CLST_ROOTPAR FAT_CLST_RES0 |
/* internally used to mark root directory */ |
#define FAT_CLST_ROOT FAT_CLST_RES1 |
/* forward declarations */ |
struct block; |
struct fat_node; |
struct fat_bs; |
typedef uint16_t fat_cluster_t; |
#define fat_block_get(bs, np, off) \ |
_fat_block_get((bs), (np)->idx->dev_handle, (np)->firstc, (off)) |
extern struct block *_fat_block_get(struct fat_bs *, dev_handle_t, |
fat_cluster_t, off_t); |
extern uint16_t _fat_blcks_get(struct fat_bs *, dev_handle_t, fat_cluster_t, |
fat_cluster_t *); |
extern void fat_append_clusters(struct fat_bs *, struct fat_node *, |
fat_cluster_t); |
extern int fat_alloc_clusters(struct fat_bs *, dev_handle_t, unsigned, |
fat_cluster_t *, fat_cluster_t *); |
extern void fat_alloc_shadow_clusters(struct fat_bs *, dev_handle_t, |
fat_cluster_t *, unsigned); |
extern void fat_mark_cluster(struct fat_bs *, dev_handle_t, unsigned, |
fat_cluster_t, fat_cluster_t); |
extern void fat_fill_gap(struct fat_bs *, struct fat_node *, fat_cluster_t, |
off_t); |
#endif |
/** |
* @} |
*/ |
/branches/dynload/uspace/srv/fs/fat/fat.c |
---|
110,6 → 110,9 |
case VFS_READ: |
fat_read(callid, &call); |
break; |
case VFS_WRITE: |
fat_write(callid, &call); |
break; |
default: |
ipc_answer_0(callid, ENOTSUP); |
break; |
/branches/dynload/uspace/srv/fs/fat/fat_ops.c |
---|
36,8 → 36,11 |
*/ |
#include "fat.h" |
#include "fat_dentry.h" |
#include "fat_fat.h" |
#include "../../vfs/vfs.h" |
#include <libfs.h> |
#include <libblock.h> |
#include <ipc/ipc.h> |
#include <ipc/services.h> |
#include <ipc/devmap.h> |
50,10 → 53,8 |
#include <assert.h> |
#include <futex.h> |
#include <sys/mman.h> |
#include <align.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; |
60,216 → 61,6 |
/** List of cached free FAT nodes. */ |
static LIST_INITIALIZE(ffn_head); |
#define FAT_NAME_LEN 8 |
#define FAT_EXT_LEN 3 |
#define FAT_PAD ' ' |
#define FAT_DENTRY_UNUSED 0x00 |
#define FAT_DENTRY_E5_ESC 0x05 |
#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) |
break; |
if (d->name[i] == FAT_DENTRY_E5_ESC) |
*buf++ = 0xe5; |
else |
*buf++ = d->name[i]; |
} |
if (d->ext[0] != FAT_PAD) |
*buf++ = '.'; |
for (i = 0; i < FAT_EXT_LEN; i++) { |
if (d->ext[i] == FAT_PAD) { |
*buf = '\0'; |
return; |
} |
if (d->ext[i] == FAT_DENTRY_E5_ESC) |
*buf++ = 0xe5; |
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, size_t bs) |
{ |
/* 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) |
{ |
/* FIXME */ |
free(block->data); |
free(block); |
} |
#define FAT_BS(b) ((fat_bs_t *)((b)->data)) |
#define FAT_CLST_RES0 0x0000 |
#define FAT_CLST_RES1 0x0001 |
#define FAT_CLST_FIRST 0x0002 |
#define FAT_CLST_BAD 0xfff7 |
#define FAT_CLST_LAST1 0xfff8 |
#define FAT_CLST_LAST8 0xffff |
/* internally used to mark root directory's parent */ |
#define FAT_CLST_ROOTPAR FAT_CLST_RES0 |
/* internally used to mark root directory */ |
#define FAT_CLST_ROOT FAT_CLST_RES1 |
#define fat_block_get(np, off) \ |
_fat_block_get((np)->idx->dev_handle, (np)->firstc, (off)) |
static block_t * |
_fat_block_get(dev_handle_t dev_handle, fat_cluster_t firstc, off_t offset) |
{ |
block_t *bb; |
block_t *b; |
unsigned bps; |
unsigned spc; |
unsigned rscnt; /* block address of the first FAT */ |
unsigned fatcnt; |
unsigned rde; |
unsigned rds; /* root directory size */ |
unsigned sf; |
unsigned ssa; /* size of the system area */ |
unsigned clusters; |
fat_cluster_t clst = firstc; |
unsigned i; |
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); |
fatcnt = FAT_BS(bb)->fatcnt; |
rde = uint16_t_le2host(FAT_BS(bb)->root_ent_max); |
sf = uint16_t_le2host(FAT_BS(bb)->sec_per_fat); |
block_put(bb); |
rds = (sizeof(fat_dentry_t) * rde) / bps; |
rds += ((sizeof(fat_dentry_t) * rde) % bps != 0); |
ssa = rscnt + fatcnt * sf + rds; |
if (firstc == FAT_CLST_ROOT) { |
/* root directory special case */ |
assert(offset < rds); |
b = block_get(dev_handle, rscnt + fatcnt * sf + offset, bps); |
return b; |
} |
clusters = offset / spc; |
for (i = 0; i < clusters; i++) { |
unsigned fsec; /* sector offset relative to FAT1 */ |
unsigned fidx; /* FAT1 entry index */ |
assert(clst >= FAT_CLST_FIRST && clst < FAT_CLST_BAD); |
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); |
assert(clst < FAT_CLST_LAST1); |
block_put(b); |
} |
b = block_get(dev_handle, ssa + (clst - FAT_CLST_FIRST) * 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); |
282,54 → 73,35 |
node->dirty = false; |
} |
static uint16_t fat_bps_get(dev_handle_t dev_handle) |
static void fat_node_sync(fat_node_t *node) |
{ |
block_t *bb; |
block_t *b; |
fat_bs_t *bs; |
fat_dentry_t *d; |
uint16_t bps; |
unsigned dps; |
bb = block_get(dev_handle, BS_BLOCK, BS_SIZE); |
assert(bb != NULL); |
bps = uint16_t_le2host(FAT_BS(bb)->bps); |
block_put(bb); |
assert(node->dirty); |
return bps; |
} |
bs = block_bb_get(node->idx->dev_handle); |
bps = uint16_t_le2host(bs->bps); |
dps = bps / sizeof(fat_dentry_t); |
/* Read the block that contains the dentry of interest. */ |
b = _fat_block_get(bs, node->idx->dev_handle, node->idx->pfc, |
(node->idx->pdi * sizeof(fat_dentry_t)) / bps); |
typedef enum { |
FAT_DENTRY_SKIP, |
FAT_DENTRY_LAST, |
FAT_DENTRY_VALID |
} fat_dentry_clsf_t; |
d = ((fat_dentry_t *)b->data) + (node->idx->pdi % dps); |
static fat_dentry_clsf_t fat_classify_dentry(fat_dentry_t *d) |
{ |
if (d->attr & FAT_ATTR_VOLLABEL) { |
/* volume label entry */ |
return FAT_DENTRY_SKIP; |
} |
if (d->name[0] == FAT_DENTRY_ERASED) { |
/* not-currently-used entry */ |
return FAT_DENTRY_SKIP; |
} |
if (d->name[0] == FAT_DENTRY_UNUSED) { |
/* never used entry */ |
return FAT_DENTRY_LAST; |
} |
if (d->name[0] == FAT_DENTRY_DOT) { |
/* |
* Most likely '.' or '..'. |
* It cannot occur in a regular file name. |
*/ |
return FAT_DENTRY_SKIP; |
} |
return FAT_DENTRY_VALID; |
d->firstc = host2uint16_t_le(node->firstc); |
if (node->type == FAT_FILE) |
d->size = host2uint32_t_le(node->size); |
/* TODO: update other fields? (e.g time fields, attr field) */ |
b->dirty = true; /* need to sync block */ |
block_put(b); |
} |
static void fat_node_sync(fat_node_t *node) |
{ |
/* TODO */ |
} |
/** Internal version of fat_node_get(). |
* |
* @param idxp Locked index structure. |
337,6 → 109,7 |
static void *fat_node_get_core(fat_idx_t *idxp) |
{ |
block_t *b; |
fat_bs_t *bs; |
fat_dentry_t *d; |
fat_node_t *nodep = NULL; |
unsigned bps; |
389,11 → 162,12 |
} |
fat_node_initialize(nodep); |
bps = fat_bps_get(idxp->dev_handle); |
bs = block_bb_get(idxp->dev_handle); |
bps = uint16_t_le2host(bs->bps); |
dps = bps / sizeof(fat_dentry_t); |
/* Read the block that contains the dentry of interest. */ |
b = _fat_block_get(idxp->dev_handle, idxp->pfc, |
b = _fat_block_get(bs, idxp->dev_handle, idxp->pfc, |
(idxp->pdi * sizeof(fat_dentry_t)) / bps); |
assert(b); |
410,8 → 184,8 |
* 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)); |
nodep->size = bps * _fat_blcks_get(bs, idxp->dev_handle, |
uint16_t_le2host(d->firstc), NULL); |
} else { |
nodep->type = FAT_FILE; |
nodep->size = uint32_t_le2host(d->size); |
479,6 → 253,7 |
static void *fat_match(void *prnt, const char *component) |
{ |
fat_bs_t *bs; |
fat_node_t *parentp = (fat_node_t *)prnt; |
char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1]; |
unsigned i, j; |
489,17 → 264,13 |
block_t *b; |
futex_down(&parentp->idx->lock); |
bps = fat_bps_get(parentp->idx->dev_handle); |
bs = block_bb_get(parentp->idx->dev_handle); |
bps = uint16_t_le2host(bs->bps); |
dps = bps / sizeof(fat_dentry_t); |
blocks = parentp->size / bps + (parentp->size % bps != 0); |
blocks = parentp->size / bps; |
for (i = 0; i < blocks; i++) { |
unsigned dentries; |
b = fat_block_get(parentp, i); |
dentries = (i == blocks - 1) ? |
parentp->size % sizeof(fat_dentry_t) : |
dps; |
for (j = 0; j < dentries; j++) { |
b = fat_block_get(bs, parentp, i); |
for (j = 0; j < dps; j++) { |
d = ((fat_dentry_t *)b->data) + j; |
switch (fat_classify_dentry(d)) { |
case FAT_DENTRY_SKIP: |
542,6 → 313,7 |
} |
block_put(b); |
} |
futex_up(&parentp->idx->lock); |
return NULL; |
} |
566,6 → 338,7 |
static bool fat_has_children(void *node) |
{ |
fat_bs_t *bs; |
fat_node_t *nodep = (fat_node_t *)node; |
unsigned bps; |
unsigned dps; |
575,22 → 348,19 |
if (nodep->type != FAT_DIRECTORY) |
return false; |
futex_down(&nodep->idx->lock); |
bps = fat_bps_get(nodep->idx->dev_handle); |
bs = block_bb_get(nodep->idx->dev_handle); |
bps = uint16_t_le2host(bs->bps); |
dps = bps / sizeof(fat_dentry_t); |
blocks = nodep->size / bps + (nodep->size % bps != 0); |
blocks = nodep->size / bps; |
for (i = 0; i < blocks; i++) { |
unsigned dentries; |
fat_dentry_t *d; |
b = fat_block_get(nodep, i); |
dentries = (i == blocks - 1) ? |
nodep->size % sizeof(fat_dentry_t) : |
dps; |
for (j = 0; j < dentries; j++) { |
b = fat_block_get(bs, nodep, i); |
for (j = 0; j < dps; j++) { |
d = ((fat_dentry_t *)b->data) + j; |
switch (fat_classify_dentry(d)) { |
case FAT_DENTRY_SKIP: |
658,50 → 428,27 |
void fat_mounted(ipc_callid_t rid, ipc_call_t *request) |
{ |
dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); |
block_t *bb; |
fat_bs_t *bs; |
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); |
/* initialize libblock */ |
rc = block_init(dev_handle, BS_SIZE, BS_BLOCK * BS_SIZE, BS_SIZE); |
if (rc != EOK) { |
munmap(dev_buffer, BS_SIZE); |
ipc_answer_0(rid, rc); |
ipc_answer_0(rid, 0); |
return; |
} |
/* get the buffer with the boot sector */ |
bs = block_bb_get(dev_handle); |
/* Read the number of root directory entries. */ |
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); |
bps = uint16_t_le2host(bs->bps); |
rde = uint16_t_le2host(bs->root_ent_max); |
if (bps != BS_SIZE) { |
munmap(dev_buffer, BS_SIZE); |
block_fini(dev_handle); |
ipc_answer_0(rid, ENOTSUP); |
return; |
} |
708,7 → 455,7 |
rc = fat_idx_init_by_dev_handle(dev_handle); |
if (rc != EOK) { |
munmap(dev_buffer, BS_SIZE); |
block_fini(dev_handle); |
ipc_answer_0(rid, rc); |
return; |
} |
716,7 → 463,7 |
/* Initialize the root node. */ |
fat_node_t *rootp = (fat_node_t *)malloc(sizeof(fat_node_t)); |
if (!rootp) { |
munmap(dev_buffer, BS_SIZE); |
block_fini(dev_handle); |
fat_idx_fini_by_dev_handle(dev_handle); |
ipc_answer_0(rid, ENOMEM); |
return; |
725,7 → 472,7 |
fat_idx_t *ridxp = fat_idx_get_by_pos(dev_handle, FAT_CLST_ROOTPAR, 0); |
if (!ridxp) { |
munmap(dev_buffer, BS_SIZE); |
block_fini(dev_handle); |
free(rootp); |
fat_idx_fini_by_dev_handle(dev_handle); |
ipc_answer_0(rid, ENOMEM); |
763,7 → 510,8 |
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); |
fat_bs_t *bs; |
uint16_t bps; |
size_t bytes; |
block_t *b; |
781,6 → 529,9 |
return; |
} |
bs = block_bb_get(dev_handle); |
bps = uint16_t_le2host(bs->bps); |
if (nodep->type == FAT_FILE) { |
/* |
* Our strategy for regular file reads is to read one block at |
787,11 → 538,18 |
* 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); |
if (pos >= nodep->size) { |
/* reading beyond the EOF */ |
bytes = 0; |
(void) ipc_data_read_finalize(callid, NULL, 0); |
} else { |
bytes = min(len, bps - pos % bps); |
bytes = min(bytes, nodep->size - pos); |
b = fat_block_get(bs, nodep, pos / bps); |
(void) ipc_data_read_finalize(callid, b->data + pos % bps, |
bytes); |
block_put(b); |
} |
} else { |
unsigned bnum; |
off_t spos = pos; |
812,7 → 570,7 |
while (bnum < nodep->size / bps) { |
off_t o; |
b = fat_block_get(nodep, bnum); |
b = fat_block_get(bs, nodep, bnum); |
for (o = pos % (bps / sizeof(fat_dentry_t)); |
o < bps / sizeof(fat_dentry_t); |
o++, pos++) { |
847,6 → 605,116 |
ipc_answer_1(rid, EOK, (ipcarg_t)bytes); |
} |
void fat_write(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); |
fat_bs_t *bs; |
size_t bytes; |
block_t *b; |
uint16_t bps; |
unsigned spc; |
off_t boundary; |
if (!nodep) { |
ipc_answer_0(rid, ENOENT); |
return; |
} |
/* XXX remove me when you are ready */ |
{ |
ipc_answer_0(rid, ENOTSUP); |
fat_node_put(nodep); |
return; |
} |
ipc_callid_t callid; |
size_t len; |
if (!ipc_data_write_receive(&callid, &len)) { |
fat_node_put(nodep); |
ipc_answer_0(callid, EINVAL); |
ipc_answer_0(rid, EINVAL); |
return; |
} |
/* |
* In all scenarios, we will attempt to write out only one block worth |
* of data at maximum. There might be some more efficient approaches, |
* but this one greatly simplifies fat_write(). Note that we can afford |
* to do this because the client must be ready to handle the return |
* value signalizing a smaller number of bytes written. |
*/ |
bytes = min(len, bps - pos % bps); |
bs = block_bb_get(dev_handle); |
bps = uint16_t_le2host(bs->bps); |
spc = bs->spc; |
boundary = ROUND_UP(nodep->size, bps * spc); |
if (pos < boundary) { |
/* |
* This is the easier case - we are either overwriting already |
* existing contents or writing behind the EOF, but still within |
* the limits of the last cluster. The node size may grow to the |
* next block size boundary. |
*/ |
fat_fill_gap(bs, nodep, FAT_CLST_RES0, pos); |
b = fat_block_get(bs, nodep, pos / bps); |
(void) ipc_data_write_finalize(callid, b->data + pos % bps, |
bytes); |
b->dirty = true; /* need to sync block */ |
block_put(b); |
if (pos + bytes > nodep->size) { |
nodep->size = pos + bytes; |
nodep->dirty = true; /* need to sync node */ |
} |
fat_node_put(nodep); |
ipc_answer_1(rid, EOK, bytes); |
return; |
} else { |
/* |
* This is the more difficult case. We must allocate new |
* clusters for the node and zero them out. |
*/ |
int status; |
unsigned nclsts; |
fat_cluster_t mcl, lcl; |
nclsts = (ROUND_UP(pos + bytes, bps * spc) - boundary) / |
bps * spc; |
/* create an independent chain of nclsts clusters in all FATs */ |
status = fat_alloc_clusters(bs, dev_handle, nclsts, &mcl, |
&lcl); |
if (status != EOK) { |
/* could not allocate a chain of nclsts clusters */ |
fat_node_put(nodep); |
ipc_answer_0(callid, status); |
ipc_answer_0(rid, status); |
return; |
} |
/* zero fill any gaps */ |
fat_fill_gap(bs, nodep, mcl, pos); |
b = _fat_block_get(bs, dev_handle, lcl, |
(pos / bps) % spc); |
(void) ipc_data_write_finalize(callid, b->data + pos % bps, |
bytes); |
b->dirty = true; /* need to sync block */ |
block_put(b); |
/* |
* Append the cluster chain starting in mcl to the end of the |
* node's cluster chain. |
*/ |
fat_append_clusters(bs, nodep, mcl); |
nodep->size = pos + bytes; |
nodep->dirty = true; /* need to sync node */ |
fat_node_put(nodep); |
ipc_answer_1(rid, EOK, bytes); |
return; |
} |
} |
/** |
* @} |
*/ |
/branches/dynload/uspace/srv/fs/fat/Makefile |
---|
31,12 → 31,16 |
LIBC_PREFIX = ../../../lib/libc |
LIBFS_PREFIX = ../../../lib/libfs |
LIBBLOCK_PREFIX = ../../../lib/libblock |
SOFTINT_PREFIX = ../../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += -I $(LIBFS_PREFIX) |
CFLAGS += -I $(LIBFS_PREFIX) -I $(LIBBLOCK_PREFIX) |
LIBS = $(LIBC_PREFIX)/libc.a $(LIBFS_PREFIX)/libfs.a |
LIBS = \ |
$(LIBFS_PREFIX)/libfs.a \ |
$(LIBBLOCK_PREFIX)/libblock.a \ |
$(LIBC_PREFIX)/libc.a |
## Sources |
# |
45,7 → 49,9 |
SOURCES = \ |
fat.c \ |
fat_ops.c \ |
fat_idx.c |
fat_idx.c \ |
fat_dentry.c \ |
fat_fat.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
/branches/dynload/uspace/srv/vfs/vfs.c |
---|
49,8 → 49,6 |
#define NAME "vfs" |
#define dprintf(...) printf(__VA_ARGS__) |
static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall) |
{ |
bool keep_on_going = 1; |
/branches/dynload/uspace/srv/vfs/vfs_ops.c |
---|
153,7 → 153,7 |
return; |
} |
/* Allocate buffer for the mount point data being received. */ |
uint8_t *buf; |
char *buf; |
buf = malloc(size + 1); |
if (!buf) { |
ipc_answer_0(callid, ENOMEM); |
/branches/dynload/uspace/Makefile |
---|
34,6 → 34,7 |
DIRS = \ |
lib/libc \ |
lib/libfs \ |
lib/libblock \ |
lib/softint \ |
lib/softfloat \ |
lib/rtld \ |
/branches/dynload/boot/boot.config |
---|
82,3 → 82,6 |
@ "tmpfs" TMPFS image |
@ "fat" FAT16 image |
! RDFMT (choice) |
# External ramdisk |
! [ARCH=sparc64] CONFIG_RD_EXTERNAL (y/n) |
/branches/dynload/boot/arch/sparc64/Makefile.inc |
---|
26,18 → 26,27 |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
TMP=distroot |
TMP = distroot |
build: $(BASE)/image.iso |
ifeq ($(CONFIG_RD_EXTERNAL),y) |
SILO_CONF_FILTER = cat |
else |
SILO_CONF_FILTER = grep -v initrd |
endif |
$(BASE)/image.iso: depend arch/$(ARCH)/loader/image.boot |
mkdir -p $(TMP)/boot |
mkdir -p $(TMP)/HelenOS |
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)/silo/README arch/$(ARCH)/silo/COPYING $(TMP)/boot |
cat arch/$(ARCH)/silo/silo.conf | $(SILO_CONF_FILTER) >$(TMP)/boot/silo.conf |
cp arch/$(ARCH)/loader/image.boot $(TMP)/HelenOS/image.boot |
gzip -f $(TMP)/HelenOS/image.boot |
ifeq ($(CONFIG_RD_EXTERNAL),y) |
cp arch/$(ARCH)/loader/initrd.img $(TMP)/HelenOS/initrd.img |
endif |
mkisofs -f -G $(TMP)/boot/isofs.b -B ... -r -o $(BASE)/image.iso $(TMP)/ |
depend: |
/branches/dynload/boot/arch/sparc64/loader/Makefile |
---|
57,7 → 57,7 |
OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump |
endif |
CFLAGS = -DRELEASE=\"$(RELEASE)\" -I. -I../../../generic -I../../../genarch -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mcpu=ultrasparc -m64 |
CFLAGS = -DRELEASE=\"$(RELEASE)\" -I. -I../../../generic -I../../../genarch -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mcpu=ultrasparc -m64 -mno-fpu -pipe |
ifdef REVISION |
CFLAGS += "-DREVISION=\"$(REVISION)\"" |
79,6 → 79,9 |
asm.S \ |
boot.S |
# |
# All components that go to image.boot without the ramdisk. |
# |
COMPONENTS = \ |
$(KERNELDIR)/kernel.bin \ |
$(USPACEDIR)/srv/ns/ns \ |
94,6 → 97,14 |
COMPONENTS += $(USPACEDIR)/srv/fs/fat/fat |
endif |
# |
# Final list of all components that go to image.boot. |
# |
ALL_COMPONENTS = $(COMPONENTS) |
ifeq ($(CONFIG_RD_EXTERNAL),n) |
ALL_COMPONENTS += ./initrd.img |
endif |
RD_SRVS = \ |
$(USPACEDIR)/srv/fb/fb \ |
$(USPACEDIR)/srv/kbd/kbd \ |
109,7 → 120,7 |
$(USPACEDIR)/app/klog/klog |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
COMPONENT_OBJECTS := $(addsuffix .o,$(basename $(notdir $(COMPONENTS)))) |
ALL_COMPONENT_OBJECTS := $(addsuffix .o,$(basename $(notdir $(ALL_COMPONENTS)))) |
.PHONY: all clean depend |
117,11 → 128,11 |
-include Makefile.depend |
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 $@ |
image.boot: depend _components.h _link.ld $(ALL_COMPONENT_OBJECTS) $(OBJECTS) |
$(LD) -Map image.map -no-check-sections -N -T _link.ld $(ALL_COMPONENT_OBJECTS) $(OBJECTS) -o $@ |
depend: |
-makedepend $(DEFS) $(CFLAGS) -f - $(SOURCES) > Makefile.depend 2> /dev/null |
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null |
clean: |
-for file in $(RD_SRVS) ; do \ |
130,9 → 141,9 |
-for file in $(RD_APPS) ; do \ |
rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \ |
done |
-rm -f _components.h _components.c _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) initrd.img image.boot image.map image.disasm Makefile.depend |
-rm -f _components.h _components.c _link.ld $(ALL_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_SRVS) $(RD_APPS) _link.ld.in |
_components.h _components.c _link.ld $(ALL_COMPONENT_OBJECTS): $(COMPONENTS) $(RD_SRVS) $(RD_APPS) _link.ld.in |
for file in $(RD_SRVS) ; do \ |
cp $$file $(USPACEDIR)/dist/srv/ ; \ |
done |
143,11 → 154,11 |
../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ initrd.fs |
endif |
ifeq ($(RDFMT),fat) |
../../../../tools/mkfat.sh $(USPACEDIR)/dist/ initrd.fs |
../../../../tools/mkfat.py $(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) |
../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 1 "unsigned long" $(ALL_COMPONENTS) |
%.o: %.S |
$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dynload/boot/arch/ia64/loader/Makefile |
---|
68,7 → 68,7 |
endif |
#-mno-pic means do not use gp + imm22 to address data |
CFLAGS = -DRELEASE=\"$(RELEASE)\" -I. -I../../../generic -I../../../genarch -I../../../../kernel/generic/include -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -fno-unwind-tables -mfixed-range=f32-f127 -mno-pic |
CFLAGS = -DRELEASE=\"$(RELEASE)\" -I. -I../../../generic -I../../../genarch -I../../../../kernel/generic/include -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -fno-unwind-tables -mfixed-range=f32-f127 -mno-pic -pipe |
ifdef REVISION |
CFLAGS += "-DREVISION=\"$(REVISION)\"" |
120,7 → 120,7 |
$(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 |
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null |
clean: |
-rm -f _components.h _components.c _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) image.boot image.map image.disasm Makefile.depend ../../../../image.bin ../../../../hello.efi |
/branches/dynload/boot/arch/arm32/loader/Makefile |
---|
57,7 → 57,7 |
OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump |
endif |
CFLAGS = -DRELEASE=\"$(RELEASE)\" -I. -I../../../generic -I../../.. -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 |
CFLAGS = -DRELEASE=\"$(RELEASE)\" -I. -I../../../generic -I../../.. -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -pipe |
ifdef REVISION |
CFLAGS += "-DREVISION=\"$(REVISION)\"" |
123,7 → 123,7 |
$(LD) -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) -o $@ |
depend: |
-makedepend $(DEFS) $(CFLAGS) -f - $(SOURCES) > Makefile.depend 2> /dev/null |
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null |
clean: |
-for file in $(RD_SRVS) ; do \ |
145,7 → 145,7 |
../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ initrd.fs |
endif |
ifeq ($(RDFMT),fat) |
../../../../tools/mkfat.sh $(USPACEDIR)/dist/ initrd.fs |
../../../../tools/mkfat.py $(USPACEDIR)/dist/ initrd.fs |
endif |
../../../../tools/mkhord.py 4096 initrd.fs initrd.img |
rm initrd.fs |
/branches/dynload/boot/arch/ppc32/loader/Makefile |
---|
57,7 → 57,7 |
OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump |
endif |
CFLAGS = -DRELEASE=\"$(RELEASE)\" -I. -I../../../generic -I../../../genarch -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mcpu=powerpc -msoft-float -m32 |
CFLAGS = -DRELEASE=\"$(RELEASE)\" -I. -I../../../generic -I../../../genarch -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mcpu=powerpc -msoft-float -m32 -pipe |
ifdef REVISION |
CFLAGS += "-DREVISION=\"$(REVISION)\"" |
123,7 → 123,7 |
$(LD) -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) -o $@ |
depend: |
-makedepend $(DEFS) $(CFLAGS) -f - $(SOURCES) > Makefile.depend 2> /dev/null |
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null |
clean: |
-for file in $(RD_SRVS) ; do \ |
151,7 → 151,7 |
../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ initrd.fs |
endif |
ifeq ($(RDFMT),fat) |
../../../../tools/mkfat.sh $(USPACEDIR)/dist/ initrd.fs |
../../../../tools/mkfat.py $(USPACEDIR)/dist/ initrd.fs |
endif |
../../../../tools/mkhord.py 4096 initrd.fs initrd.img |
rm initrd.fs |
/branches/dynload/boot/arch/amd64/Makefile.inc |
---|
80,7 → 80,7 |
$(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 |
$(BASE)/tools/mkfat.py $(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 |
/branches/dynload/boot/arch/ppc64/loader/Makefile |
---|
57,7 → 57,7 |
OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump |
endif |
CFLAGS = -DRELEASE=\"$(RELEASE)\" -I. -I../../../generic -I../../../genarch -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mcpu=powerpc64 -msoft-float -m64 |
CFLAGS = -DRELEASE=\"$(RELEASE)\" -I. -I../../../generic -I../../../genarch -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mcpu=powerpc64 -msoft-float -m64 -pipe |
ifdef REVISION |
CFLAGS += "-DREVISION=\"$(REVISION)\"" |
105,7 → 105,7 |
$(LD) -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) -o $@ |
depend: |
-makedepend $(DEFS) $(CFLAGS) -f - $(SOURCES) > Makefile.depend 2> /dev/null |
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null |
clean: |
-rm -f _components.h _components.c _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) image.boot Makefile.depend |
/branches/dynload/boot/arch/mips32/loader/Makefile |
---|
63,7 → 63,7 |
OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump |
endif |
CFLAGS = -DRELEASE=\"$(RELEASE)\" -I. -I../../../generic -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mhard-float -mips3 |
CFLAGS = -DRELEASE=\"$(RELEASE)\" -I. -I../../../generic -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mhard-float -mips3 -pipe |
ifdef REVISION |
CFLAGS += "-DREVISION=\"$(REVISION)\"" |
123,7 → 123,7 |
$(LD) -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) -o $@ |
depend: |
-makedepend $(DEFS) $(CFLAGS) -f - $(SOURCES) > Makefile.depend 2> /dev/null |
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null |
clean: |
-for file in $(RD_SRVS) ; do \ |
145,7 → 145,7 |
../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ initrd.fs |
endif |
ifeq ($(RDFMT),fat) |
../../../../tools/mkfat.sh $(USPACEDIR)/dist/ initrd.fs |
../../../../tools/mkfat.py $(USPACEDIR)/dist/ initrd.fs |
endif |
../../../../tools/mkhord.py 16384 initrd.fs initrd.img |
rm initrd.fs |
/branches/dynload/boot/arch/ia32/Makefile.inc |
---|
87,7 → 87,7 |
$(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 |
$(BASE)/tools/mkfat.py $(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 |