Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2444 → Rev 2445

/trunk/kernel/doc/AUTHORS
4,4 → 4,5
Jakub Vana <vana@helenos.eu>
Josef Cejka <cejka@helenos.eu>
Sergey Bondari <bondari@helenos.eu>
Michal Konopa <mkonopa@seznam.cz>
 
/trunk/kernel/generic/include/lib/rd.h
40,7 → 40,7
/**
* RAM disk version
*/
#define RD_VERSION 0
#define RD_VERSION 1
 
/**
* RAM disk magic number
/trunk/kernel/generic/include/errno.h
37,6 → 37,7
 
/* 1-255 are kernel error codes, 256-512 are user error codes */
 
#define EOK 0 /* No error */
#define ENOENT -1 /* No such entry */
#define ENOMEM -2 /* Not enough memory */
#define ELIMIT -3 /* Limit exceeded */
/trunk/kernel/generic/src/main/kinit.c
167,6 → 167,7
 
task_t *utask = task_run_program((void *) init.tasks[i].addr,
"uspace");
if (utask) {
/*
* Set capabilities to init userspace tasks.
181,7 → 182,7
init.tasks[i].size);
if (rd != RE_OK)
printf("Init binary %zd not used.\n", i);
printf("Init binary %zd not used, error code %d.\n", i, rd);
}
}
 
/trunk/kernel/generic/src/lib/rd.c
42,9 → 42,16
#include <mm/frame.h>
#include <sysinfo/sysinfo.h>
#include <ddi/ddi.h>
#include <print.h>
#include <align.h>
 
static parea_t rd_parea; /**< Physical memory area for rd. */
 
/**
* RAM disk initialization routine. At this point, the RAM disk memory is shared
* and information about the share is provided as sysinfo values to the userspace
* tasks.
*/
int init_rd(rd_header * header, size_t size)
{
/* Identify RAM disk */
74,6 → 81,9
if ((hsize % FRAME_SIZE) || (dsize % FRAME_SIZE))
return RE_UNSUPPORTED;
if (dsize % FRAME_SIZE)
return RE_UNSUPPORTED;
 
if (hsize > size)
return RE_INVALID;
80,7 → 90,7
if ((uint64_t) hsize + dsize > size)
dsize = size - hsize;
rd_parea.pbase = KA2PA((void *) header + hsize);
rd_parea.pbase = ALIGN_DOWN((uintptr_t) KA2PA((void *) header + hsize), FRAME_SIZE);
rd_parea.vbase = (uintptr_t) ((void *) header + hsize);
rd_parea.frames = SIZE2FRAMES(dsize);
rd_parea.cacheable = true;
87,6 → 97,7
ddi_parea_register(&rd_parea);
 
sysinfo_set_item_val("rd", NULL, true);
sysinfo_set_item_val("rd.header_size", NULL, hsize);
sysinfo_set_item_val("rd.size", NULL, dsize);
sysinfo_set_item_val("rd.address.physical", NULL, (unative_t)
KA2PA((void *) header + hsize));
/trunk/uspace/rd/rd.c
1,5 → 1,7
/*
* Copyright (c) 2006 Martin Decky
* Copyright (c) 2007 Michal Konopa
* Copyright (c) 2007 Martin Jelen
* Copyright (c) 2007 Peter Majer
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
45,7 → 47,17
#include <bool.h>
#include <errno.h>
#include <async.h>
#include <stdlib.h>
#include <unistd.h>
#include <align.h>
#include <async.h>
#include <ddi.h>
#include <libarch/ddi.h>
#include <stdio.h>
#include "rd.h"
 
static void *rd_addr;
static void *fs_addr;
 
static void rd_connection(ipc_callid_t iid, ipc_call_t *icall)
{
54,15 → 66,24
int retval;
 
ipc_answer_fast(iid, 0, 0, 0);
ipcarg_t offset;
 
while (1) {
callid = async_get_call(&call);
switch (IPC_GET_METHOD(call)) {
case IPC_M_PHONE_HUNGUP:
ipc_answer_fast(callid, 0,0,0);
return;
default:
retval = EINVAL;
case IPC_M_PHONE_HUNGUP:
ipc_answer_fast(callid, 0,0,0);
return;
case IPC_M_AS_AREA_SEND:
ipc_answer_fast(callid, 0, (uintptr_t)fs_addr, 0);
continue;
case RD_READ_BLOCK:
offset = IPC_GET_ARG1(call);
memcpy((void *)fs_addr, rd_addr+offset, BLOCK_SIZE);
retval = EOK;
break;
default:
retval = EINVAL;
}
ipc_answer_fast(callid, retval, 0, 0);
}
71,6 → 92,8
 
static bool rd_init(void)
{
int retval, flags;
 
size_t rd_size = sysinfo_value("rd.size");
void * rd_ph_addr = (void *) sysinfo_value("rd.address.physical");
77,14 → 100,20
if (rd_size == 0)
return false;
void * rd_addr = as_get_mappable_page(rd_size);
rd_addr = as_get_mappable_page(rd_size);
physmem_map(rd_ph_addr, rd_addr, ALIGN_UP(rd_size, PAGE_SIZE) >> PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE);
flags = AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE;
retval = physmem_map(rd_ph_addr, rd_addr, ALIGN_UP(rd_size, PAGE_SIZE) >> PAGE_WIDTH, flags);
 
if (retval < 0)
return false;
size_t fs_size = ALIGN_UP(BLOCK_SIZE * sizeof(char), PAGE_SIZE);
fs_addr = as_get_mappable_page(fs_size);
 
return true;
}
 
 
int main(int argc, char **argv)
{
if (rd_init()) {
/trunk/uspace/rd/rd.h
0,0 → 1,52
/*
* Copyright (c) 2007 Michal Konopa
* Copyright (c) 2007 Martin Jelen
* Copyright (c) 2007 Peter Majer
* 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 rd
* @{
*/
 
/**
* @file rd.h
* @brief Initial RAM disk for HelenOS - header
*/
 
/* Basic constants. */
 
#ifndef _RD_H
#define _RD_H
 
#define BLOCK_SIZE 1024 /**< Working block size */
 
#define RD_OFFSET 100 /**< IPC Message offset */
 
#define RD_BASE (FIRST_USER_METHOD + RD_OFFSET) /**< IPC Index of the first RD message */
#define RD_READ_BLOCK (RD_BASE + 1) /**< IPC Index of the RD_READ_BLOCK message */
 
#endif /* _RD_H */
/trunk/uspace/libc/include/io/file.h
0,0 → 1,101
/*
* Copyright (c) 2007 Michal Konopa
* Copyright (c) 2007 Martin Jelen
* Copyright (c) 2007 Peter Majer
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libc
* @{
*/
 
/**
* @file file.h
* @brief The main header for the user library for working with the file system
*/
 
#ifndef _FILE_H
#define _FILE_H
 
#include "../../../fs/const.h"
#include "../../../fs/type.h"
#include "../../../fs/stat.h"
#include "../../../fs/dir.h"
#include "../../../share/message.h"
 
#define F_OK 0x00
#define F_FILE_NOT_FOUND 0x01
#define F_FILE_NOT_OPEN 0x02
#define F_READ_ERROR 0x10
#define F_READ_OVERFLOW 0x11
#define F_SYSTEM_ERROR 0xf0
#define F_IPC_FAILURE 0xf1
#define F_MMAP_FAILURE 0xf2
#define F_COMM_FAILURE 0xf3
 
#define F_ERRTYPE_MASK 0xf0
 
#define F_MODE_READ 0x01
#define F_MODE_WRITE 0x02
#define F_MODE_READ_WRITE F_MODE_READ | F_MODE_WRITE
#define F_MODE_APPEND 0x04
 
/**
*
*/
typedef struct {
char name[30];
unsigned short inode_num;
} dir_item_t;
 
/**
*
*/
typedef struct {
size_t size;
dir_item_t base_info;
void *share;
message_params_t *params;
unsigned int handle;
stat_t stat;
} file_t;
 
static int f_err;
 
dir_item_t *ls(unsigned int *length);
int chdir(char *new_dir);
 
file_t *fopen(char *name, int mode);
int fstat(file_t *file);
int fread(file_t *file, void *buffer, unsigned int size);
int fseek(file_t * file, int offset, int whence);
int fclose(file_t *file);
 
#endif
 
/**
*@}
/
/trunk/uspace/libc/include/ipc/services.h
42,6 → 42,7
#define SERVICE_VIDEO 3
#define SERVICE_CONSOLE 4
#define SERVICE_RD 5
#define SERVICE_FS 6
 
/* Memory area to be received from NS */
#define SERVICE_MEM_REALTIME 1
/trunk/uspace/libc/generic/io/file.c
0,0 → 1,288
/*
* Copyright (c) 2007 Michal Konopa
* Copyright (c) 2007 Martin Jelen
* Copyright (c) 2007 Peter Majer
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libc
* @{
*/
 
/**
* @file file.c
* @brief The user library for working with the file system
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <async.h>
#include <ipc/services.h>
#include <ipc/ipc.h>
#include <sys/mman.h>
#include <io/file.h>
#include <bool.h>
#include <err.h>
#include <align.h>
#include "../../../fs/dir.h"
#include "../../../share/message.h"
#include "../../../share/shared_proto.h"
 
#define CONNECT_SLEEP_INTERVAL 10000
#define CONNECT_SLEEP_TIMEOUT 100000
 
/**
*
*/
static int fs_phone;
 
static file_t *file_connect();
static int file_disconnect(file_t *file);
 
/**
* Connect to the FS task and share memory with it for further data and
* extended memory transfers
*/
file_t *file_connect() {
file_t *result;
size_t size;
void *share = NULL;
int retval;
 
size = ALIGN_UP(BLOCK_SIZE * sizeof(char), PAGE_SIZE);
share = mmap(share, size, AS_AREA_READ | AS_AREA_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
if ((int) share < 0) {
f_err = F_MMAP_FAILURE;
return NULL;
}
 
retval = async_req_2(fs_phone, FS_NEW_CONSUMER, task_get_id(), 0, NULL, NULL);
if (retval < 0) {
f_err = F_COMM_FAILURE;
return NULL;
}
 
int flags = 0;
flags = AS_AREA_READ | AS_AREA_WRITE;
retval = async_req_3(fs_phone, IPC_M_AS_AREA_SEND, (uintptr_t)share, size, flags, NULL, NULL, NULL);
if (retval < 0) {
f_err = F_COMM_FAILURE;
return NULL;
}
/* Allocating structure for extended message. */
message_params_t *params = malloc(sizeof(message_params_t));
memset((void*) params, 0, sizeof(message_params_t));
result = malloc(sizeof(file_t));
result->share = share;
result->size = size;
result->params = params;
f_err = F_OK;
return result;
}
 
/**
* Disconnect from the FS task, unsharing memory and freeing the file data structure
*/
int file_disconnect(file_t *file) {
int retval = send_request(fs_phone, FS_DROP_CONSUMER, file->params, file->share);
if (retval < 0)
return -1;
/* Unmapping share area. */
retval = munmap(file->share, file->size);
if (retval < 0)
return -1;
file->size = ALIGN_UP(BLOCK_SIZE * sizeof(char), PAGE_SIZE);
file->share = mmap(file->share, file->size, AS_AREA_READ | AS_AREA_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
if ((int) (file->share) < 0)
return -1;
free(file);
f_err = F_OK;
return F_OK;
}
 
/**
* List contents of the current directory
*/
dir_item_t *ls(unsigned int *length) {
dir_item_t *result;
unsigned short entries_num;
 
file_t *shared_file = file_connect();
if (shared_file == NULL)
return NULL;
/* We want lookup our work directory. */
retval = send_request(fs_phone, FS_DSUM, shared_file->params, shared_file->share);
if (retval < 0) {
f_err = F_READ_ERROR;
return NULL;
}
entries_num = retval;
*length = entries_num;
result = malloc(entries_num * sizeof (dir_item_t));
int entry;
for (entry = 0; entry < entries_num; entry++) {
shared_file->params->entry_number = entry;
retval = send_request(fs_phone, FS_READENTRY, shared_file->params, shared_file->share);
if (retval < 0) {
f_err = F_READ_ERROR;
return NULL;
}
memcpy(&(result[entry].inode_num), shared_file->share, sizeof(unsigned short));
memcpy(result[entry].name, (void *)(shared_file->share+sizeof(unsigned short)), retval-sizeof(unsigned short));
 
/* Do not show empty entries. */
if (!result[entry].inode_num)
continue;
}
return result;
}
 
/**
* Change the current working directory for the task
*/
int chdir(char * new_dir)
{
file_t *shared_file = file_connect();
if (shared_file == NULL) {
f_err = F_READ_ERROR;
return F_READ_ERROR;
}
memcpy(shared_file->params->fname, new_dir, 30);
int retval = send_request(fs_phone, FS_CHDIR, shared_file->params, shared_file->share);
if (retval < 0) {
f_err = F_READ_ERROR;
return F_READ_ERROR;
}
 
retval = file_disconnect(shared_file);
f_err = F_OK;
return F_OK;
}
 
/**
* Open a file for reading and/or writing
*/
file_t *fopen(char *name, int mode)
{
file_t *file = file_connect();
/* We want to work with the specified file. */
memcpy(file->params->fname, name, 30);
 
int retval = send_request(fs_phone, FS_OPEN, file->params, file->share);
if (retval < 0)
return NULL;
file->handle = retval;
return file;
}
 
/**
* Read status information about a file
*/
int fstat(file_t *file)
{
memcpy(file->params->fname, file->base_info.name, 30);
file->params->fd = file->handle;
 
int retval = send_request(fs_phone, FS_FSTAT, file->params, file->share);
if (retval < 0)
return -1;
memcpy((void *)(&file->stat), file->share, sizeof(stat_t));
f_err = F_OK;
return F_OK;
}
 
/**
* Read data from a file
*/
int fread(file_t *file, void* buffer, unsigned int size)
{
file->params->nbytes = size;
int retval = send_request(fs_phone, FS_READ, file->params, file->share);
if (retval < 0)
return -1;
 
f_err = F_OK;
return F_OK;
}
 
/**
* Seek to a position within a file
*/
int fseek(file_t *file, int offset, int whence)
{
file->params->offset = 0;
file->params->whence = 0; /* from beginning of the file */
 
int retval = send_request(fs_phone, FS_SEEK, file->params, file->share);
if (retval < 0)
return -1;
 
f_err = F_OK;
return F_OK;
}
 
/**
* Close a file
*/
int fclose(file_t *file)
{
int retval = send_request(fs_phone, FS_CLOSE, file->params, file->share);
if (retval < 0)
return -1;
 
if (file != NULL)
file_disconnect(file);
f_err = F_OK;
return F_OK;
}
 
/**
*@}
*/