vfs, initrd
parent
3a798edb83
commit
2f719330b8
@ -1,3 +1,5 @@
|
||||
*.o
|
||||
*.swp
|
||||
*.swo
|
||||
initrd.img
|
||||
main.elf
|
||||
|
@ -0,0 +1 @@
|
||||
Hello, world!!
|
@ -0,0 +1,22 @@
|
||||
CFILES = $(wildcard *.c)
|
||||
AFILES = $(wildcard *.s)
|
||||
OFILES = $(patsubst %.c, %.o, $(CFILES)) \
|
||||
$(patsubst %.s, %.asm.o, $(AFILES))
|
||||
|
||||
CFLAGS += -I.. -I../arch/cmsis
|
||||
|
||||
all: $(OFILES)
|
||||
|
||||
%.o: %.c
|
||||
@echo " CC " $<
|
||||
@$(CROSS)$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
%.asm.o: %.s
|
||||
@echo " AS " $<
|
||||
@$(CROSS)$(AS) $(AFLAGS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
@echo " CLEAN"
|
||||
@rm -f $(OFILES)
|
||||
|
||||
|
@ -0,0 +1,97 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <kernel/heap.h>
|
||||
#include <kernel/vfs.h>
|
||||
|
||||
typedef struct {
|
||||
char *address;
|
||||
uint32_t pos;
|
||||
uint32_t size;
|
||||
} initrd_info;
|
||||
|
||||
extern uint8_t _binary_initrd_img_start[];
|
||||
extern uint8_t _binary_initrd_img_size[];
|
||||
|
||||
static const uint8_t *initrd_start = (uint8_t *)_binary_initrd_img_start;
|
||||
static const uint32_t initrd_size = (uint32_t)_binary_initrd_img_size;
|
||||
|
||||
void *initrd_open(const char *file);
|
||||
uint32_t initrd_read(void *info, uint32_t count, uint8_t *buffer);
|
||||
|
||||
char *initrd_getfile(uint32_t offset);
|
||||
|
||||
static const vfs_volume_funcs initrd_funcs = {
|
||||
initrd_open,
|
||||
0, // close
|
||||
initrd_read,
|
||||
0, // write
|
||||
0 // readdir
|
||||
};
|
||||
|
||||
void initrd_init(void)
|
||||
{
|
||||
vfs_mount(&initrd_funcs, VFS_READONLY);
|
||||
}
|
||||
|
||||
void *initrd_open(const char *file)
|
||||
{
|
||||
char *ptr;
|
||||
for (uint32_t i = 0; ptr = initrd_getfile(i), ptr != 0; i++) {
|
||||
uint32_t len = *((uint32_t *)ptr);
|
||||
if (!strncmp(file, ptr + 4, len)) {
|
||||
initrd_info *file = (initrd_info *)malloc(
|
||||
sizeof(initrd_info));
|
||||
file->address = ptr + len + 8;
|
||||
file->pos = 0;
|
||||
file->size = *(uint32_t *)(ptr + len + 4);
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t initrd_read(void *info, uint32_t count, uint8_t *buffer)
|
||||
{
|
||||
initrd_info *iinfo = (initrd_info *)info;
|
||||
if (iinfo == 0 || iinfo->address == 0)
|
||||
return 0;
|
||||
|
||||
uint32_t i;
|
||||
for (i = 0; i < count; i++) {
|
||||
if (iinfo->pos >= iinfo->size)
|
||||
break;
|
||||
|
||||
buffer[iinfo->pos] = iinfo->address[iinfo->pos];
|
||||
iinfo->pos++;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/*char *readfile(const char *name)
|
||||
{
|
||||
char *ptr;
|
||||
for (uint32_t i = 0; ptr = getfile(i), ptr != 0; i++) {
|
||||
uint32_t len = *((uint32_t *)ptr);
|
||||
if (!strncmp(name, ptr + 4, len))
|
||||
return ptr + len + 8;
|
||||
}
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
char *initrd_getfile(uint32_t offset)
|
||||
{
|
||||
char *ptr = (char *)initrd_start;
|
||||
for (uint32_t i = 0; i < offset; i++) {
|
||||
uint32_t len = *((uint32_t *)ptr);
|
||||
uint32_t datalen = *((uint32_t *)(ptr + 4 + len));
|
||||
ptr += len + datalen + 8;
|
||||
if (ptr >= (char *)(initrd_start + initrd_size))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
@ -0,0 +1,6 @@
|
||||
#ifndef INTIRD_H_
|
||||
#define INITRD_H_
|
||||
|
||||
void initrd_init(void);
|
||||
|
||||
#endif // INITRD_H_
|
@ -1,15 +1,121 @@
|
||||
#include "vfs.h"
|
||||
#include "task.h"
|
||||
|
||||
//static vfs_node vfs_root;
|
||||
#include <kernel/task.h>
|
||||
|
||||
int vfs_open(const char *path, int mode)
|
||||
#define VFS_MAX_VOLS 8
|
||||
#define VFS_MAX_FILES 10
|
||||
|
||||
static vfs_volume vfs_volumes[VFS_MAX_VOLS];
|
||||
static vfs_file vfs_files[VFS_MAX_FILES];
|
||||
|
||||
void vfs_svc(uint32_t *args)
|
||||
{
|
||||
switch (args[0]) {
|
||||
case 0:
|
||||
*((int *)args[3]) = vfs_mount((vfs_volume_funcs *)args[1],
|
||||
args[2]);
|
||||
break;
|
||||
case 1:
|
||||
*((int *)args[3]) = vfs_open((const char *)args[1], args[2]);
|
||||
break;
|
||||
case 2:
|
||||
*((int *)args[4]) = vfs_read(args[1], args[2], (uint8_t *)args[3]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void vfs_init(void)
|
||||
{
|
||||
for (int i = 0; i < VFS_MAX_VOLS; i++)
|
||||
vfs_volumes[i].flags = 0;
|
||||
for (int i = 0; i < VFS_MAX_FILES; i++)
|
||||
vfs_files[i].flags = 0;
|
||||
}
|
||||
|
||||
int vfs_mount(vfs_volume_funcs *funcs, uint32_t flags)
|
||||
{
|
||||
for (int i = 0; i < VFS_MAX_VOLS; i++) {
|
||||
if (!(vfs_volumes[i].flags && VFS_MOUNTED)) {
|
||||
vfs_volumes[i].flags = VFS_MOUNTED | flags;
|
||||
vfs_volumes[i].funcs = funcs;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int vfs_get_drive(const char *path)
|
||||
{
|
||||
// Validate parameters
|
||||
if (path[0] == '\0' || path[1] == '\0' || path[1] != ':' ||
|
||||
path[2] == '\0' || path[2] != '/')
|
||||
return -1;
|
||||
|
||||
// Find chosen drive
|
||||
int drive = -1;
|
||||
for (int i = 0; i < VFS_MAX_VOLS; i++) {
|
||||
if (path[0] == ('a' + i) || path[0] == ('A' + i)) {
|
||||
drive = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (drive == -1 || !(vfs_volumes[drive].flags && VFS_MOUNTED))
|
||||
return -1;
|
||||
|
||||
return drive;
|
||||
}
|
||||
|
||||
int vfs_open(const char *path, uint32_t flags)
|
||||
{
|
||||
int drive = vfs_get_drive(path);
|
||||
if (drive == -1)
|
||||
return -1;
|
||||
if (vfs_volumes[drive].funcs->open == 0)
|
||||
return -1;
|
||||
|
||||
// Find available file handle
|
||||
int file = -1;
|
||||
for (int i = 0; i < VFS_MAX_FILES; i++) {
|
||||
if (!(vfs_files[i].flags & VFS_FILE_OPEN)) {
|
||||
file = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (file == -1)
|
||||
return -1;
|
||||
|
||||
vfs_files[file].flags = VFS_FILE_OPEN | flags;
|
||||
vfs_files[file].vol = drive;
|
||||
vfs_files[file].pid = task_getpid();
|
||||
vfs_files[file].fsinfo =
|
||||
vfs_volumes[drive].funcs->open(path + 3);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
uint32_t vfs_read(int fd, uint32_t count, uint8_t *buffer)
|
||||
{
|
||||
(void)path;
|
||||
(void)mode;
|
||||
// vfs_node *cd = task_getcwd();
|
||||
// if (cd == 0)
|
||||
// cd = &vfs_root;
|
||||
if (fd < 0 || fd > VFS_MAX_FILES || count == 0 || buffer == 0)
|
||||
return 0;
|
||||
if (vfs_volumes[vfs_files[fd].vol].funcs->read == 0)
|
||||
return -1;
|
||||
if (vfs_files[fd].pid != task_getpid())
|
||||
return 0;
|
||||
if ((!(vfs_files[fd].flags & VFS_FILE_READ)) || (vfs_files[fd].flags &
|
||||
VFS_EOF))
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
uint32_t ret = vfs_volumes[vfs_files[fd].vol].funcs->read(vfs_files[fd].fsinfo,
|
||||
count, buffer);
|
||||
|
||||
if (ret < count)
|
||||
vfs_files[fd].flags |= VFS_EOF;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,72 @@
|
||||
/**
|
||||
* @file rba.cpp
|
||||
* A "really basic archiver"
|
||||
*
|
||||
* Copyright (C) 2018 Clyne Sullivan
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// check args
|
||||
if (argc < 3) {
|
||||
std::cout << "Usage: " << argv[0] << " archive files...\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::ofstream archive (argv[1], std::ios::out);
|
||||
for (int i = 2; i < argc; i++) {
|
||||
// attempt to read file contents
|
||||
std::string fileName (argv[i]);
|
||||
std::ifstream contents (fileName, std::ios::in | std::ios::ate);
|
||||
std::string shortName;
|
||||
if (auto pos = fileName.rfind('/'); pos != std::string::npos)
|
||||
shortName = fileName.substr(pos + 1);
|
||||
else
|
||||
shortName = fileName;
|
||||
|
||||
if (contents.good()) {
|
||||
uint32_t size = contents.tellg();
|
||||
contents.seekg(0);
|
||||
std::cout << "Adding file " << fileName <<" ("
|
||||
<< size << " bytes)...\n";
|
||||
|
||||
// read in file
|
||||
char *buffer = new char[size];
|
||||
contents.read(buffer, size);
|
||||
|
||||
// write name size/text
|
||||
uint32_t nameSize = shortName.size();
|
||||
archive.write((char *)&nameSize, sizeof(uint32_t));
|
||||
archive.write(shortName.data(), nameSize);
|
||||
// write data size/content
|
||||
archive.write((char *)&size, sizeof(uint32_t));
|
||||
archive.write(buffer, size);
|
||||
|
||||
delete[] buffer;
|
||||
} else {
|
||||
std::cout << "Failed to add file " << fileName
|
||||
<< ", continuing...\n";
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Created archive " << argv[1] << '\n';
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue