- add a simple virtual filesystem and as simple initial ramdisk
git-svn-id: http://svn.lfbs.rwth-aachen.de/svn/scc/trunk/MetalSVM@102 315a16e6-25f9-4109-90ae-ca3045a26c18
This commit is contained in:
parent
bda5f3618e
commit
5cfbfb5a32
17 changed files with 535 additions and 47 deletions
|
@ -1,7 +1,7 @@
|
|||
export TOPDIR = /home/stefan/SCC/MetalSVM
|
||||
export ARCH = x86
|
||||
NAME = metalsvm.bin
|
||||
KERNDIRS = libkern kernel mm arch lwip drivers
|
||||
KERNDIRS = libkern kernel mm fs arch lwip drivers
|
||||
SUBDIRS = libgloss $(KERNDIRS)
|
||||
OBJS = $(shell for i in $(KERNDIRS); do find $$i -name *.o; done)
|
||||
|
||||
|
|
7
NOTICE
7
NOTICE
|
@ -51,3 +51,10 @@ proprietary applications can adopt newlib because its use does not
|
|||
require distribution of the end work's source code. For convenience, all
|
||||
of newlib's licenses are gathered up into the file COPYING.NEWLIB,
|
||||
which is included in the directory newlib or in newlib's source code.
|
||||
|
||||
=========================================================================
|
||||
= JamesM's kernel development tutorials =
|
||||
=========================================================================
|
||||
MetalSVM's virtual filesystem and its initial ramdiks is is derived from
|
||||
JamesM's kernel development tutorials.
|
||||
(http://www.jamesmolloy.co.uk/tutorial_html/index.html)
|
||||
|
|
|
@ -25,6 +25,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
typedef unsigned int size_t;
|
||||
typedef int ptrdiff_t;
|
||||
|
||||
/* This defines what the stack looks like after an ISR was running */
|
||||
struct state {
|
||||
|
|
20
fs/Makefile
Normal file
20
fs/Makefile
Normal file
|
@ -0,0 +1,20 @@
|
|||
C_source = fs.c initrd.c
|
||||
|
||||
OBJS += $(patsubst %.c, %.o, $(filter %.c, $(C_source)))
|
||||
|
||||
# other implicit rules
|
||||
%.o : %.c
|
||||
$(CC) -c $(CFLAGS) -o $@ $<
|
||||
|
||||
default: $(OBJS)
|
||||
|
||||
all: $(OBJS)
|
||||
|
||||
clean:
|
||||
$(RM) *.o *~ $(NAME)
|
||||
|
||||
depend:
|
||||
$(CC) -MM $(CFLAGS) $(C_source) > Makefile.dep
|
||||
|
||||
-include Makefile.dep
|
||||
# DO NOT DELETE
|
72
fs/fs.c
Normal file
72
fs/fs.c
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright 2010 Stefan Lankes, Chair for Operating Systems,
|
||||
* RWTH Aachen University
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is part of MetalSVM.
|
||||
*/
|
||||
|
||||
#include <metalsvm/fs.h>
|
||||
|
||||
fs_node_t *fs_root = NULL; // The root of the filesystem.
|
||||
|
||||
uint32_t read_fs(fs_node_t * node, uint32_t offset, uint32_t size, uint8_t * buffer)
|
||||
{
|
||||
// Has the node got a read callback?
|
||||
if (node->read != 0)
|
||||
return node->read(node, offset, size, buffer);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t write_fs(fs_node_t * node, uint32_t offset, uint32_t size, uint8_t * buffer)
|
||||
{
|
||||
// Has the node got a write callback?
|
||||
if (node->write != 0)
|
||||
return node->write(node, offset, size, buffer);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void open_fs(fs_node_t * node, uint8_t read, uint8_t write)
|
||||
{
|
||||
// Has the node got an open callback?
|
||||
if (node->open != 0)
|
||||
return node->open(node);
|
||||
}
|
||||
|
||||
void close_fs(fs_node_t * node)
|
||||
{
|
||||
// Has the node got a close callback?
|
||||
if (node->close != 0)
|
||||
return node->close(node);
|
||||
}
|
||||
|
||||
struct dirent *readdir_fs(fs_node_t * node, uint32_t index)
|
||||
{
|
||||
// Is the node a directory, and does it have a callback?
|
||||
if ((node->flags & 0x7) == FS_DIRECTORY && node->readdir != 0)
|
||||
return node->readdir(node, index);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fs_node_t *finddir_fs(fs_node_t * node, char *name)
|
||||
{
|
||||
// Is the node a directory, and does it have a callback?
|
||||
if ((node->flags & 0x7) == FS_DIRECTORY && node->finddir != 0)
|
||||
return node->finddir(node, name);
|
||||
else
|
||||
return NULL;
|
||||
}
|
150
fs/initrd.c
Normal file
150
fs/initrd.c
Normal file
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Copyright 2010 Stefan Lankes, Chair for Operating Systems,
|
||||
* RWTH Aachen University
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is part of MetalSVM.
|
||||
*/
|
||||
|
||||
#include <metalsvm/stdlib.h>
|
||||
#include <metalsvm/stdio.h>
|
||||
#include <metalsvm/string.h>
|
||||
#include <metalsvm/initrd.h>
|
||||
#include <asm/multiboot.h>
|
||||
|
||||
initrd_header_t *initrd_header; // The header.
|
||||
initrd_file_header_t *file_headers; // The list of file headers.
|
||||
fs_node_t *initrd_root; // Our root directory node.
|
||||
fs_node_t *initrd_dev; // We also add a directory node for /dev, so we can mount devfs later on.
|
||||
fs_node_t *root_nodes; // List of file nodes.
|
||||
int nroot_nodes; // Number of file nodes.
|
||||
|
||||
struct dirent dirent;
|
||||
|
||||
static uint32_t initrd_read(fs_node_t * node, uint32_t offset, uint32_t size,
|
||||
uint8_t * buffer)
|
||||
{
|
||||
initrd_file_header_t header = file_headers[node->inode];
|
||||
if (offset > header.length)
|
||||
return 0;
|
||||
if (offset + size > header.length)
|
||||
size = header.length - offset;
|
||||
memcpy(buffer, (uint8_t *) (header.offset + offset), size);
|
||||
return size;
|
||||
}
|
||||
|
||||
static struct dirent *initrd_readdir(fs_node_t * node, uint32_t index)
|
||||
{
|
||||
if (node == initrd_root && index == 0) {
|
||||
strcpy(dirent.name, "dev");
|
||||
dirent.name[3] = 0;
|
||||
dirent.ino = 0;
|
||||
return &dirent;
|
||||
}
|
||||
|
||||
if (index - 1 >= nroot_nodes)
|
||||
return NULL;
|
||||
strcpy(dirent.name, root_nodes[index - 1].name);
|
||||
dirent.name[strlen(root_nodes[index - 1].name)] = 0;
|
||||
dirent.ino = root_nodes[index - 1].inode;
|
||||
return &dirent;
|
||||
}
|
||||
|
||||
static fs_node_t *initrd_finddir(fs_node_t * node, char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (node == initrd_root && !strcmp(name, "dev"))
|
||||
return initrd_dev;
|
||||
|
||||
for (i = 0; i < nroot_nodes; i++)
|
||||
if (!strcmp(name, root_nodes[i].name))
|
||||
return &root_nodes[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void initrd_init(void)
|
||||
{
|
||||
uint32_t i, location = 0;
|
||||
|
||||
#ifdef CONFIG_MULTIBOOT
|
||||
if (mb_info && (mb_info->flags & (1 << (3)))) {
|
||||
multiboot_module_t* mmodule = (multiboot_module_t*) mb_info->mods_addr;
|
||||
location = mmodule->mod_start;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Initialise the main and file header pointers and populate the root directory.
|
||||
initrd_header = (initrd_header_t *) location;
|
||||
file_headers =
|
||||
(initrd_file_header_t *) (location + sizeof(initrd_header_t));
|
||||
|
||||
// Initialise the root directory.
|
||||
initrd_root = (fs_node_t *) kmalloc(sizeof(fs_node_t));
|
||||
strcpy(initrd_root->name, "/");
|
||||
initrd_root->mask = initrd_root->uid = initrd_root->gid =
|
||||
initrd_root->inode = initrd_root->length = 0;
|
||||
initrd_root->flags = FS_DIRECTORY;
|
||||
initrd_root->read = 0;
|
||||
initrd_root->write = 0;
|
||||
initrd_root->open = 0;
|
||||
initrd_root->close = 0;
|
||||
initrd_root->readdir = &initrd_readdir;
|
||||
initrd_root->finddir = &initrd_finddir;
|
||||
initrd_root->ptr = 0;
|
||||
initrd_root->impl = 0;
|
||||
|
||||
// Initialise the /dev directory (required!)
|
||||
initrd_dev = (fs_node_t *) kmalloc(sizeof(fs_node_t));
|
||||
strcpy(initrd_dev->name, "dev");
|
||||
initrd_dev->mask = initrd_dev->uid = initrd_dev->gid =
|
||||
initrd_dev->inode = initrd_dev->length = 0;
|
||||
initrd_dev->flags = FS_DIRECTORY;
|
||||
initrd_dev->read = 0;
|
||||
initrd_dev->write = 0;
|
||||
initrd_dev->open = 0;
|
||||
initrd_dev->close = 0;
|
||||
initrd_dev->readdir = &initrd_readdir;
|
||||
initrd_dev->finddir = &initrd_finddir;
|
||||
initrd_dev->ptr = 0;
|
||||
initrd_dev->impl = 0;
|
||||
|
||||
root_nodes =
|
||||
(fs_node_t *) kmalloc(sizeof(fs_node_t) * initrd_header->nfiles);
|
||||
nroot_nodes = initrd_header->nfiles;
|
||||
|
||||
// For every file...
|
||||
for(i=0; i<initrd_header->nfiles; i++) {
|
||||
// Edit the file's header - currently it holds the file offset
|
||||
// relative to the start of the ramdisk. We want it relative to the start
|
||||
// of memory.
|
||||
file_headers[i].offset += location;
|
||||
// Create a new file node.
|
||||
strncpy(root_nodes[i].name, file_headers[i].name, MAX_FNAME);
|
||||
root_nodes[i].mask = root_nodes[i].uid = root_nodes[i].gid = 0;
|
||||
root_nodes[i].length = file_headers[i].length;
|
||||
root_nodes[i].inode = i;
|
||||
root_nodes[i].flags = FS_FILE;
|
||||
root_nodes[i].read = &initrd_read;
|
||||
root_nodes[i].write = 0;
|
||||
root_nodes[i].readdir = 0;
|
||||
root_nodes[i].finddir = 0;
|
||||
root_nodes[i].open = 0;
|
||||
root_nodes[i].close = 0;
|
||||
root_nodes[i].impl = 0;
|
||||
}
|
||||
|
||||
/* In our case, initrd is also the root of our file system */
|
||||
fs_root = initrd_root;
|
||||
}
|
80
include/metalsvm/fs.h
Normal file
80
include/metalsvm/fs.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright 2010 Stefan Lankes, Chair for Operating Systems,
|
||||
* RWTH Aachen University
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is part of MetalSVM.
|
||||
*/
|
||||
|
||||
#ifndef __FS_H__
|
||||
#define __FS_H__
|
||||
|
||||
#include <metalsvm/stddef.h>
|
||||
|
||||
#define FS_FILE 0x01
|
||||
#define FS_DIRECTORY 0x02
|
||||
#define FS_CHARDEVICE 0x03
|
||||
#define FS_BLOCKDEVICE 0x04
|
||||
#define FS_PIPE 0x05
|
||||
#define FS_SYMLINK 0x06
|
||||
#define FS_MOUNTPOINT 0x08 // Is the file an active mountpoint?
|
||||
|
||||
struct fs_node;
|
||||
|
||||
/* These typedefs define the type of callbacks - called when read/write/open/close are called. */
|
||||
typedef uint32_t(*read_type_t) (struct fs_node *, uint32_t, uint32_t, uint8_t *);
|
||||
typedef uint32_t(*write_type_t) (struct fs_node *, uint32_t, uint32_t, uint8_t *);
|
||||
typedef void (*open_type_t) (struct fs_node *);
|
||||
typedef void (*close_type_t) (struct fs_node *);
|
||||
typedef struct dirent *(*readdir_type_t) (struct fs_node *, uint32_t);
|
||||
typedef struct fs_node *(*finddir_type_t) (struct fs_node *, char *name);
|
||||
|
||||
typedef struct fs_node {
|
||||
char name[MAX_FNAME]; // The filename.
|
||||
uint32_t mask; // The permissions mask.
|
||||
uint32_t uid; // The owning user.
|
||||
uint32_t gid; // The owning group.
|
||||
uint32_t flags; // Includes the node type. See #defines above.
|
||||
uint32_t inode; // This is device-specific - provides a way for a filesystem to identify files.
|
||||
uint32_t length; // Size of the file, in bytes.
|
||||
uint32_t impl; // An implementation-defined number.
|
||||
read_type_t read;
|
||||
write_type_t write;
|
||||
open_type_t open;
|
||||
close_type_t close;
|
||||
readdir_type_t readdir;
|
||||
finddir_type_t finddir;
|
||||
struct fs_node *ptr; // Used by mountpoints and symlinks.
|
||||
} fs_node_t;
|
||||
|
||||
struct dirent {
|
||||
char name[MAX_FNAME]; // Filename.
|
||||
uint32_t ino; // Inode number. Required by POSIX.
|
||||
};
|
||||
|
||||
extern fs_node_t *fs_root; // The root of the filesystem.
|
||||
|
||||
/*
|
||||
* Standard read/write/open/close functions. Note that these are all suffixed with
|
||||
* _fs to distinguish them from the read/write/open/close which deal with file descriptors,
|
||||
* not file nodes.
|
||||
*/
|
||||
uint32_t read_fs(fs_node_t * node, uint32_t offset, uint32_t size, uint8_t * buffer);
|
||||
uint32_t write_fs(fs_node_t * node, uint32_t offset, uint32_t size, uint8_t * buffer);
|
||||
void open_fs(fs_node_t * node, uint8_t read, uint8_t write);
|
||||
void close_fs(fs_node_t * node);
|
||||
struct dirent *readdir_fs(fs_node_t * node, uint32_t index);
|
||||
fs_node_t *finddir_fs(fs_node_t * node, char *name);
|
||||
|
||||
#endif
|
38
include/metalsvm/initrd.h
Normal file
38
include/metalsvm/initrd.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright 2010 Stefan Lankes, Chair for Operating Systems,
|
||||
* RWTH Aachen University
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is part of MetalSVM.
|
||||
*/
|
||||
|
||||
#ifndef __INITRD_H__
|
||||
#define __INITRD_H__
|
||||
|
||||
#include <metalsvm/fs.h>
|
||||
|
||||
typedef struct {
|
||||
uint32_t nfiles; // The number of files in the ramdisk.
|
||||
} initrd_header_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t magic; // Magic number, for error checking.
|
||||
char name[MAX_FNAME]; // Filename.
|
||||
uint32_t offset; // Offset in the initrd that the file starts.
|
||||
uint32_t length; // Length of the file.
|
||||
} initrd_file_header_t;
|
||||
|
||||
void initrd_init(void);
|
||||
|
||||
#endif
|
|
@ -48,6 +48,10 @@ char* strncpy(char *dest, const char *src, size_t n);
|
|||
char* strcpy(char *dest, const char *src);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_ARCH_STRCMP
|
||||
int strcmp(const char *s1, const char *s2);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <metalsvm/mmu.h>
|
||||
#include <metalsvm/tasks.h>
|
||||
#include <metalsvm/processor.h>
|
||||
#include <metalsvm/initrd.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/irqflags.h>
|
||||
#include <asm/kb.h>
|
||||
|
@ -45,7 +46,35 @@
|
|||
extern int test_init(void);
|
||||
extern const void kernel_start;
|
||||
extern const void kernel_end;
|
||||
unsigned long user_tasks[MAX_TASKS] = {[0 ... MAX_TASKS-1] = 0};
|
||||
|
||||
static void list_root(void)
|
||||
{
|
||||
// list the contents of /
|
||||
int i = 0;
|
||||
struct dirent *node = NULL;
|
||||
|
||||
while ((node = readdir_fs(fs_root, i)) != 0) {
|
||||
kprintf("Found file %s\n", node->name);
|
||||
fs_node_t *fsnode = finddir_fs(fs_root, node->name);
|
||||
|
||||
if ((fsnode->flags&0x7) == FS_DIRECTORY)
|
||||
kputs("\t(directory)\n");
|
||||
else {
|
||||
char buf[256];
|
||||
uint32_t sz;
|
||||
int j;
|
||||
|
||||
kputs("\t contents: \"");
|
||||
sz = read_fs(fsnode, 0, 256, buf);
|
||||
|
||||
for (j = 0; j < sz; j++)
|
||||
kputchar(buf[j]);
|
||||
|
||||
kputs("\"\n");
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_LWIP) && defined(CONFIG_ROCKCREEK)
|
||||
err_t sccpcif_init(struct netif* netif);
|
||||
|
@ -97,7 +126,6 @@ int STDCALL scc_pc_task(void* arg)
|
|||
|
||||
int main(void)
|
||||
{
|
||||
unsigned int i;
|
||||
#ifdef CONFIG_LWIP
|
||||
tid_t pc_id;
|
||||
#endif
|
||||
|
@ -113,6 +141,7 @@ int main(void)
|
|||
mmu_init();
|
||||
multitasking_init();
|
||||
koutput_init();
|
||||
initrd_init();
|
||||
|
||||
irq_enable();
|
||||
|
||||
|
@ -130,11 +159,9 @@ int main(void)
|
|||
timer_set_frequency(TIMER_FREQ);
|
||||
|
||||
sleep(5);
|
||||
list_root();
|
||||
test_init();
|
||||
|
||||
for(i=0; (i<MAX_TASKS) && user_tasks[i]; i++)
|
||||
create_user_task(NULL, (entry_point_t)user_tasks[i], NULL, 0);
|
||||
|
||||
#ifdef CONFIG_LWIP
|
||||
create_kernel_task(&pc_id, scc_pc_task, NULL);
|
||||
#endif
|
||||
|
|
|
@ -63,7 +63,7 @@ typedef unsigned short u_short;
|
|||
typedef unsigned long long u_quad_t;
|
||||
typedef long long quad_t;
|
||||
typedef unsigned long uintptr_t;
|
||||
typedef long ptrdiff_t;
|
||||
//typedef long ptrdiff_t;
|
||||
#define NBBY 8 /* number of bits in a byte */
|
||||
char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
#define hex2ascii(hex) (hex2ascii_data[hex])
|
||||
|
|
|
@ -98,3 +98,21 @@ char* strcpy(char *dest, const char *src)
|
|||
return dest;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_ARCH_STRCMP
|
||||
int strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
do {
|
||||
ret = (int) (*s1 - *s2);
|
||||
s1++; s2++;
|
||||
} while ((*s1 != '\0') && (*s2 != '\0') && !ret);
|
||||
|
||||
if (!ret)
|
||||
ret = (int) (*s1 - *s2);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
43
mm/memory.c
43
mm/memory.c
|
@ -43,7 +43,6 @@ atomic_int32_t total_available_pages = ATOMIC_INIT(0);
|
|||
|
||||
extern const void kernel_start;
|
||||
extern const void kernel_end;
|
||||
extern unsigned long user_tasks[MAX_TASKS];
|
||||
|
||||
inline static int page_marked(unsigned int i)
|
||||
{
|
||||
|
@ -118,46 +117,12 @@ int mmu_init(void)
|
|||
|
||||
if (mb_info && (mb_info->flags & (1 << (3)))) {
|
||||
multiboot_module_t* mmodule = (multiboot_module_t*) mb_info->mods_addr;
|
||||
elf_header_t* header;
|
||||
elf_program_header_t* ph;
|
||||
int j;
|
||||
|
||||
for(i=0; i<mb_info->mods_count; i++, mmodule++) {
|
||||
header = (elf_header_t*) mmodule->mod_start;
|
||||
|
||||
/* Did we found a ELF-file? */
|
||||
if (header->magic != ELF_MAGIC) {
|
||||
kprintf("Bad magic number!!!\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i<MAX_TASKS)
|
||||
user_tasks[i] = header->entry;
|
||||
else
|
||||
kprintf("Too many tasks!!!\n");
|
||||
kprintf("Entry point of task %i at %lx\n", i, user_tasks[i]);
|
||||
|
||||
ph = (elf_program_header_t*) (((char*) mmodule->mod_start) + header->ph_offset);
|
||||
for (j=0; j<header->ph_entry_count; j++, ph++) {
|
||||
void* dest = (void*) ph->virt_addr;
|
||||
void* src = ((char*) mmodule->mod_start) + ph->offset;
|
||||
|
||||
/* We load only regions from typ LOAD into the memory */
|
||||
if (ph->type != PT_LOAD)
|
||||
continue;
|
||||
if (!dest)
|
||||
continue;
|
||||
|
||||
memset(dest, 0, ph->mem_size);
|
||||
memcpy(dest, src, ph->file_size);
|
||||
|
||||
addr = (size_t) dest;
|
||||
while(addr < ph->mem_size) {
|
||||
page_set_mark(addr / PAGE_SIZE);
|
||||
addr += PAGE_SIZE;
|
||||
atomic_int32_inc(&total_allocated_pages);
|
||||
atomic_int32_dec(&total_available_pages);
|
||||
}
|
||||
for(addr=mmodule->mod_start; addr<mmodule->mod_end; addr+=PAGE_SIZE) {
|
||||
page_set_mark(addr / PAGE_SIZE);
|
||||
atomic_int32_inc(&total_allocated_pages);
|
||||
atomic_int32_dec(&total_available_pages);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
MAKE = make
|
||||
CC = gcc
|
||||
CFLAGS = -O2 -nostdinc -fno-stack-protector -fno-builtin -I../current/include -I../../include -I../../arch/x86/include
|
||||
CFLAGS = -O2 -nostdinc -Wall -fno-builtin -I../current/include -I../../include -I../../arch/x86/include -fno-stack-protector
|
||||
LDFLGAS = -nostdlib -L../current/lib/
|
||||
|
||||
# other implicit rules
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#undef errno
|
||||
extern int errno;
|
||||
|
|
23
tools/Makefile
Normal file
23
tools/Makefile
Normal file
|
@ -0,0 +1,23 @@
|
|||
MAKE = make
|
||||
CC = gcc
|
||||
CFLAGS = -O2 -Wall
|
||||
LDFLGAS =
|
||||
|
||||
# other implicit rules
|
||||
%.o : %.c
|
||||
$(CC) -c $(CFLAGS) -o $@ $<
|
||||
|
||||
default:
|
||||
$(MAKE) all
|
||||
|
||||
all: make_initrd.o
|
||||
$(CC) $(CFLAGS) -o make_initrd $< $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
$(RM) *.o *~
|
||||
|
||||
depend:
|
||||
$(CC) -MM $(CFLAGS) *.c > Makefile.dep
|
||||
|
||||
-include Makefile.dep
|
||||
# DO NOT DELETE
|
81
tools/make_initrd.c
Normal file
81
tools/make_initrd.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright 2010 Stefan Lankes, Chair for Operating Systems,
|
||||
* RWTH Aachen University
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is part of MetalSVM.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
struct initrd_header {
|
||||
unsigned char magic;
|
||||
char name[128];
|
||||
unsigned int offset;
|
||||
unsigned int length;
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
int i, nheaders = (argc - 1) / 2;
|
||||
struct initrd_header headers[64];
|
||||
unsigned int off = sizeof(struct initrd_header) * 64 + sizeof(int);
|
||||
|
||||
memset(headers, 0x00, 64*sizeof(struct initrd_header));
|
||||
printf("size of header: %d\n", sizeof(struct initrd_header));
|
||||
|
||||
for (i = 0; i < nheaders; i++) {
|
||||
printf("writing file %s->%s at 0x%x\n", argv[i * 2 + 1],
|
||||
argv[i * 2 + 2], off);
|
||||
strcpy(headers[i].name, argv[i * 2 + 2]);
|
||||
headers[i].offset = off;
|
||||
FILE *stream = fopen(argv[i * 2 + 1], "r");
|
||||
if (stream == 0) {
|
||||
printf("Error: file not found: %s\n", argv[i * 2 + 1]);
|
||||
return 1;
|
||||
}
|
||||
fseek(stream, 0, SEEK_END);
|
||||
headers[i].length = ftell(stream);
|
||||
off += headers[i].length;
|
||||
fclose(stream);
|
||||
headers[i].magic = 0xBF;
|
||||
}
|
||||
|
||||
FILE *wstream = fopen("./initrd.img", "w");
|
||||
unsigned char *data = (unsigned char *)malloc(off);
|
||||
fwrite(&nheaders, sizeof(int), 1, wstream);
|
||||
fwrite(headers, sizeof(struct initrd_header), 64, wstream);
|
||||
|
||||
for (i = 0; i < nheaders; i++) {
|
||||
FILE *stream = fopen(argv[i * 2 + 1], "r");
|
||||
unsigned char *buf = (unsigned char *)malloc(headers[i].length);
|
||||
size_t curr, len = headers[i].length;
|
||||
|
||||
do {
|
||||
curr = fread(buf, 1, len, stream);
|
||||
fwrite(buf, 1, len, wstream);
|
||||
len -= curr;
|
||||
} while(len > 0);
|
||||
fclose(stream);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
fclose(wstream);
|
||||
free(data);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue