mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-20 22:23:16 +00:00
Update FatFS port to version 0.13
- Update FatFS port from 0.07e to 0.13 - Multi-device support - Basic test at run/fatfs - Adaption of existing components Note, ffat is now consistently renamed to fatfs. Ref #2410
This commit is contained in:
parent
473aa3454d
commit
f09fc4a5a2
@ -11,16 +11,16 @@
|
|||||||
* under the terms of the GNU Affero General Public License version 3.
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _INCLUDE__FFAT__BLOCK_H_
|
#ifndef _INCLUDE__FATFS__BLOCK_H_
|
||||||
#define _INCLUDE__FFAT__BLOCK_H_
|
#define _INCLUDE__FATFS__BLOCK_H_
|
||||||
|
|
||||||
namespace Genode {
|
namespace Genode {
|
||||||
struct Env;
|
struct Env;
|
||||||
struct Allocator;
|
struct Allocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Ffat {
|
namespace Fatfs {
|
||||||
void block_init(Genode::Env &, Genode::Allocator &heap);
|
void block_init(Genode::Env &, Genode::Allocator &heap);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _INCLUDE__FFAT__BLOCK_H_ */
|
#endif /* _INCLUDE__FATFS__BLOCK_H_ */
|
1
repos/libports/lib/import/import-fatfs_block.mk
Normal file
1
repos/libports/lib/import/import-fatfs_block.mk
Normal file
@ -0,0 +1 @@
|
|||||||
|
INC_DIR += $(call select_from_ports,fatfs)/include
|
@ -1 +0,0 @@
|
|||||||
INC_DIR += $(call select_from_ports,ffat)/include
|
|
17
repos/libports/lib/mk/fatfs_block.mk
Normal file
17
repos/libports/lib/mk/fatfs_block.mk
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#
|
||||||
|
# FAT File System Module using a Block session as disk I/O backend
|
||||||
|
#
|
||||||
|
|
||||||
|
FATFS_PORT_DIR := $(call select_from_ports,fatfs)
|
||||||
|
FATFS_PORT_SRC_DIR := $(FATFS_PORT_DIR)/src/lib/fatfs/source
|
||||||
|
FATFS_LOCAL_SRC_DIR := $(REP_DIR)/src/lib/fatfs
|
||||||
|
|
||||||
|
INC_DIR += $(REP_DIR)/include/fatfs $(FATFS_PORT_DIR)/include
|
||||||
|
|
||||||
|
SRC_C = ff.c ffunicode.c
|
||||||
|
SRC_CC = diskio_block.cc
|
||||||
|
|
||||||
|
CC_OPT += -Wno-unused-variable
|
||||||
|
|
||||||
|
vpath % $(FATFS_LOCAL_SRC_DIR)
|
||||||
|
vpath % $(FATFS_PORT_SRC_DIR)
|
@ -1,16 +0,0 @@
|
|||||||
#
|
|
||||||
# FAT File System Module using a Block session as disk I/O backend
|
|
||||||
#
|
|
||||||
|
|
||||||
FFAT_PORT_DIR := $(call select_from_ports,ffat)
|
|
||||||
|
|
||||||
INC_DIR += $(FFAT_PORT_DIR)/include
|
|
||||||
|
|
||||||
FFAT_DIR := $(FFAT_PORT_DIR)/src/lib/ffat
|
|
||||||
|
|
||||||
SRC_C = ff.c ccsbcs.c
|
|
||||||
SRC_CC = diskio_block.cc
|
|
||||||
|
|
||||||
vpath % $(REP_DIR)/src/lib/ffat/
|
|
||||||
vpath % $(FFAT_DIR)/src
|
|
||||||
vpath % $(FFAT_DIR)/src/option
|
|
6
repos/libports/lib/mk/libc_fatfs.mk
Normal file
6
repos/libports/lib/mk/libc_fatfs.mk
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
SRC_CC = plugin.cc
|
||||||
|
LIBS += libc fatfs_block
|
||||||
|
|
||||||
|
vpath plugin.cc $(REP_DIR)/src/lib/libc_fatfs
|
||||||
|
|
||||||
|
SHARED_LIB = yes
|
@ -1,6 +0,0 @@
|
|||||||
SRC_CC = plugin.cc
|
|
||||||
LIBS += libc ffat_block
|
|
||||||
|
|
||||||
vpath plugin.cc $(REP_DIR)/src/lib/libc_ffat
|
|
||||||
|
|
||||||
SHARED_LIB = yes
|
|
1
repos/libports/ports/fatfs.hash
Normal file
1
repos/libports/ports/fatfs.hash
Normal file
@ -0,0 +1 @@
|
|||||||
|
4ca5681b074e2b5f64454b4065faab28b33f2cc5
|
13
repos/libports/ports/fatfs.port
Normal file
13
repos/libports/ports/fatfs.port
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
LICENSE := BSD
|
||||||
|
VERSION := 0.13
|
||||||
|
DOWNLOADS := fatfs.archive
|
||||||
|
|
||||||
|
URL(fatfs) := http://www.elm-chan.org/fsw/ff/arc/ff13.zip
|
||||||
|
SHA(fatfs) := 8ce22f86e339b0fc59c8c69941fbaf86e5cf9364
|
||||||
|
DIR(fatfs) := src/lib/fatfs
|
||||||
|
|
||||||
|
PATCHES := src/lib/fatfs/ffconf.patch src/lib/fatfs/integer.patch
|
||||||
|
|
||||||
|
DIRS := include/fatfs
|
||||||
|
DIR_CONTENT(include/fatfs) := \
|
||||||
|
$(addprefix src/lib/fatfs/source/, ff.h ffconf.h diskio.h integer.h)
|
@ -1 +0,0 @@
|
|||||||
c77033bdfb9e0e291b2a6bcf3b168e5823235649
|
|
@ -1,18 +0,0 @@
|
|||||||
LICENSE := BSD
|
|
||||||
VERSION := 0.07e
|
|
||||||
DOWNLOADS := ffat.archive
|
|
||||||
|
|
||||||
#
|
|
||||||
# Download archive from genode.org instead of the original location
|
|
||||||
# 'http://elm-chan.org/fsw/ff/ff007e.zip' because the elm-chan webserver
|
|
||||||
# does not like wget.
|
|
||||||
#
|
|
||||||
URL(ffat) := https://genode.org/files/ff007e.zip
|
|
||||||
SHA(ffat) := 3379ad817e1c4f9993ae2722e86235ec85d7e36d
|
|
||||||
DIR(ffat) := src/lib/ffat
|
|
||||||
|
|
||||||
PATCHES := src/lib/ffat/config.patch
|
|
||||||
|
|
||||||
DIRS := include/ffat
|
|
||||||
DIR_CONTENT(include/ffat) := $(addprefix src/lib/ffat/src/,\
|
|
||||||
ff.h diskio.h integer.h ffconf.h)
|
|
148
repos/libports/run/fatfs_blkio.run
Normal file
148
repos/libports/run/fatfs_blkio.run
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
#
|
||||||
|
# \brief Test of FatFS blkio implementation
|
||||||
|
# \author Emery Hemingway
|
||||||
|
# \date 2017-07-31
|
||||||
|
#
|
||||||
|
|
||||||
|
if {[have_spec odroid_xu] || [have_spec zynq]} {
|
||||||
|
puts "Run script does not support this platform."
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# use SD on ARM
|
||||||
|
set use_sd_card_drv [expr [have_spec omap4] || [have_spec arndale] || [have_spec pl180]]
|
||||||
|
|
||||||
|
# use AHCI on x86
|
||||||
|
set use_ahci [expr [have_spec x86] && ![have_spec linux]]
|
||||||
|
|
||||||
|
# use ram_blk on Linux
|
||||||
|
set use_ram_blk [have_spec linux]
|
||||||
|
|
||||||
|
if {[expr ![have_include "power_on/qemu"] && !$use_ram_blk]} {
|
||||||
|
puts "\nPlease setup your native sd or hard drive. Remove this fail stop";
|
||||||
|
puts "check when you have prepared your native environment.\n";
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build
|
||||||
|
#
|
||||||
|
set build_components {
|
||||||
|
test/fatfs_blkio
|
||||||
|
}
|
||||||
|
|
||||||
|
lappend_if $use_sd_card_drv build_components drivers/sd_card
|
||||||
|
|
||||||
|
source ${genode_dir}/repos/base/run/platform_drv.inc
|
||||||
|
append_platform_drv_build_components
|
||||||
|
|
||||||
|
build $build_components
|
||||||
|
|
||||||
|
create_boot_directory
|
||||||
|
|
||||||
|
set depot_pkgs "genodelabs/src/[base_src] genodelabs/src/init"
|
||||||
|
|
||||||
|
lappend_if $use_ahci depot_pkgs genodelabs/src/ahci_drv
|
||||||
|
lappend_if $use_ram_blk depot_pkgs genodelabs/src/ram_blk
|
||||||
|
|
||||||
|
import_from_depot {*}$depot_pkgs
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate config
|
||||||
|
#
|
||||||
|
append config {
|
||||||
|
<config>
|
||||||
|
<parent-provides>
|
||||||
|
<service name="CPU"/>
|
||||||
|
<service name="IO_MEM"/>
|
||||||
|
<service name="IO_PORT"/>
|
||||||
|
<service name="IRQ"/>
|
||||||
|
<service name="LOG"/>
|
||||||
|
<service name="PD"/>
|
||||||
|
<service name="RAM"/>
|
||||||
|
<service name="RM"/>
|
||||||
|
<service name="ROM"/>
|
||||||
|
</parent-provides>
|
||||||
|
<default-route>
|
||||||
|
<any-service> <parent/> <any-child/> </any-service>
|
||||||
|
</default-route>
|
||||||
|
<default caps="128"/>
|
||||||
|
<start name="timer">
|
||||||
|
<resource name="RAM" quantum="1M"/>
|
||||||
|
<provides><service name="Timer"/></provides>
|
||||||
|
</start>
|
||||||
|
<start name="test-fatfs_blkio">
|
||||||
|
<resource name="RAM" quantum="10M"/>
|
||||||
|
<config ld_verbose="true">
|
||||||
|
<libc stdout="/log" stderr="/log"/>
|
||||||
|
<vfs> <log/> </vfs>
|
||||||
|
</config>
|
||||||
|
</start>}
|
||||||
|
|
||||||
|
append_platform_drv_config
|
||||||
|
|
||||||
|
append_if $use_ahci config {
|
||||||
|
<start name="ahci_drv">
|
||||||
|
<resource name="RAM" quantum="10M" />
|
||||||
|
<provides><service name="Block" /></provides>
|
||||||
|
<route>
|
||||||
|
<any-service> <parent /> <any-child /></any-service>
|
||||||
|
</route>
|
||||||
|
<config>
|
||||||
|
<policy label_prefix="test-fatfs_blkio" device="0"/>
|
||||||
|
</config>
|
||||||
|
</start>}
|
||||||
|
|
||||||
|
append_if $use_sd_card_drv config {
|
||||||
|
<start name="sd_card_drv">
|
||||||
|
<resource name="RAM" quantum="1M" />
|
||||||
|
<provides><service name="Block"/></provides>
|
||||||
|
</start>
|
||||||
|
}
|
||||||
|
|
||||||
|
append_if $use_ram_blk config {
|
||||||
|
<start name="ram_blk">
|
||||||
|
<resource name="RAM" quantum="4M" />
|
||||||
|
<provides><service name="Block"/></provides>
|
||||||
|
<config size="1M" block_size="512"/>
|
||||||
|
</start>}
|
||||||
|
|
||||||
|
append config {
|
||||||
|
</config>
|
||||||
|
}
|
||||||
|
|
||||||
|
install_config $config
|
||||||
|
|
||||||
|
#
|
||||||
|
# Boot modules
|
||||||
|
#
|
||||||
|
|
||||||
|
set disk_image "bin/test.hda"
|
||||||
|
set cmd "dd if=/dev/zero of=$disk_image bs=512 count=4096"
|
||||||
|
puts "creating disk image: $cmd"
|
||||||
|
catch { exec sh -c $cmd }
|
||||||
|
|
||||||
|
# generic modules
|
||||||
|
set boot_modules {
|
||||||
|
libc.lib.so
|
||||||
|
libm.lib.so
|
||||||
|
test-fatfs_blkio
|
||||||
|
}
|
||||||
|
|
||||||
|
lappend_if $use_sd_card_drv boot_modules sd_card_drv
|
||||||
|
lappend_if $use_ram_blk boot_modules test.hda
|
||||||
|
|
||||||
|
append_platform_drv_boot_modules
|
||||||
|
|
||||||
|
build_boot_image $boot_modules
|
||||||
|
|
||||||
|
#
|
||||||
|
# Qemu
|
||||||
|
#
|
||||||
|
append qemu_args " -nographic "
|
||||||
|
append_if $use_ahci qemu_args " -drive id=disk,file=$disk_image,format=raw,if=none -device ahci,id=ahci -device ide-drive,drive=disk,bus=ahci.0 -boot d"
|
||||||
|
append_if $use_sd_card_drv qemu_args " -drive file=$disk_image,format=raw,if=sd,cache=writeback "
|
||||||
|
|
||||||
|
run_genode_until {.*child "test-fatfs_blkio" exited with exit value 0.*} 60
|
||||||
|
|
||||||
|
exec rm -f $disk_image
|
@ -1,9 +1,9 @@
|
|||||||
set mkfs_cmd [check_installed mkfs.vfat]
|
set mkfs_cmd [check_installed mkfs.vfat]
|
||||||
set mkfs_opts "-F32"
|
set mkfs_opts "-F32"
|
||||||
set filesystem ffat
|
set filesystem fatfs
|
||||||
|
|
||||||
#
|
#
|
||||||
# The ffat_libc plugin opens a block session directly. If the VFS opened
|
# The fatfs_libc plugin opens a block session directly. If the VFS opened
|
||||||
# the block session, the plugin would try to open a second one, which
|
# the block session, the plugin would try to open a second one, which
|
||||||
# would get denied by the block driver.
|
# would get denied by the block driver.
|
||||||
#
|
#
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# \brief Test for using the libc_ffat plugin
|
# \brief Test for using file systems in the libc
|
||||||
# \author Christian Prochaska
|
# \author Christian Prochaska
|
||||||
# \date 2011-05-27
|
# \date 2011-05-27
|
||||||
#
|
#
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
set build_component server/ffat_fs
|
set build_component server/fatfs_fs
|
||||||
set binary ffat_fs
|
set binary fatfs_fs
|
||||||
set mkfs_cmd mkfs.vfat
|
set mkfs_cmd mkfs.vfat
|
||||||
set mkfs_opts "-F32"
|
set mkfs_opts "-F32"
|
||||||
set vfs_dev_blkdev ""
|
set vfs_dev_blkdev ""
|
@ -22,7 +22,7 @@ lappend_if $use_sd_card_driver build_components drivers/sd_card
|
|||||||
lappend_if $use_ahci_driver build_components drivers/ahci
|
lappend_if $use_ahci_driver build_components drivers/ahci
|
||||||
lappend_if [have_spec acpi] build_components drivers/acpi
|
lappend_if [have_spec acpi] build_components drivers/acpi
|
||||||
lappend_if [have_spec linux] build_components server/ram_fs
|
lappend_if [have_spec linux] build_components server/ram_fs
|
||||||
lappend_if [expr ![have_spec linux]] build_components server/ffat_fs
|
lappend_if [expr ![have_spec linux]] build_components server/fatfs_fs
|
||||||
|
|
||||||
build $build_components
|
build $build_components
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ append_if $use_ahci_driver config {
|
|||||||
<resource name="RAM" quantum="5M"/>
|
<resource name="RAM" quantum="5M"/>
|
||||||
<provides> <service name="Block"/> </provides>
|
<provides> <service name="Block"/> </provides>
|
||||||
<config>
|
<config>
|
||||||
<policy label_prefix="ffat_fs" device="0" />
|
<policy label_prefix="fatfs_fs" device="0" />
|
||||||
</config>
|
</config>
|
||||||
</start>}
|
</start>}
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ append_if [have_spec linux] config {
|
|||||||
</start>}
|
</start>}
|
||||||
|
|
||||||
append_if [expr ![have_spec linux]] config {
|
append_if [expr ![have_spec linux]] config {
|
||||||
<start name="ffat_fs">
|
<start name="fatfs_fs">
|
||||||
<resource name="RAM" quantum="10M"/>
|
<resource name="RAM" quantum="10M"/>
|
||||||
<provides><service name="File_system"/></provides>
|
<provides><service name="File_system"/></provides>
|
||||||
<config>
|
<config>
|
||||||
@ -146,7 +146,7 @@ append boot_modules {
|
|||||||
|
|
||||||
# platform-specific modules
|
# platform-specific modules
|
||||||
lappend_if [have_spec linux] boot_modules ram_fs
|
lappend_if [have_spec linux] boot_modules ram_fs
|
||||||
lappend_if [expr ![have_spec linux]] boot_modules ffat_fs
|
lappend_if [expr ![have_spec linux]] boot_modules fatfs_fs
|
||||||
lappend_if $use_sd_card_driver boot_modules sd_card_drv
|
lappend_if $use_sd_card_driver boot_modules sd_card_drv
|
||||||
lappend_if $use_ahci_driver boot_modules ahci_drv
|
lappend_if $use_ahci_driver boot_modules ahci_drv
|
||||||
|
|
||||||
|
215
repos/libports/src/lib/fatfs/diskio_block.cc
Normal file
215
repos/libports/src/lib/fatfs/diskio_block.cc
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
/*
|
||||||
|
* \brief Low level disk I/O module using a Block session
|
||||||
|
* \author Christian Prochaska
|
||||||
|
* \date 2011-05-30
|
||||||
|
*
|
||||||
|
* See doc/en/appnote.html in the FatFS source.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011-2017 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <block_session/connection.h>
|
||||||
|
#include <base/allocator_avl.h>
|
||||||
|
#include <base/log.h>
|
||||||
|
|
||||||
|
/* Genode block backend */
|
||||||
|
#include <fatfs/block.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Fatfs {
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
/* fatfs includes */
|
||||||
|
#include <fatfs/diskio.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace Genode;
|
||||||
|
|
||||||
|
struct Drive;
|
||||||
|
struct Platform
|
||||||
|
{
|
||||||
|
Genode::Env &env;
|
||||||
|
Genode::Allocator &alloc;
|
||||||
|
Genode::Allocator_avl tx_alloc { &alloc };
|
||||||
|
|
||||||
|
enum { MAX_DEV_NUM = 8 };
|
||||||
|
|
||||||
|
/* XXX: could make a tree... */
|
||||||
|
Drive* drives[MAX_DEV_NUM];
|
||||||
|
|
||||||
|
Platform(Genode::Env &env, Genode::Allocator &alloc)
|
||||||
|
: env(env), alloc(alloc)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_DEV_NUM; ++i)
|
||||||
|
drives[i] = nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static Constructible<Platform> _platform;
|
||||||
|
|
||||||
|
void block_init(Genode::Env &env, Genode::Allocator &alloc) {
|
||||||
|
_platform.construct(env, alloc); }
|
||||||
|
|
||||||
|
struct Drive : Block::Connection
|
||||||
|
{
|
||||||
|
Block::sector_t block_count;
|
||||||
|
Genode::size_t block_size;
|
||||||
|
Block::Session::Operations ops;
|
||||||
|
|
||||||
|
Drive(Platform &platform, char const *label)
|
||||||
|
: Block::Connection(platform.env, &platform.tx_alloc, 128*1024, label)
|
||||||
|
{
|
||||||
|
info(&block_count, &block_size, &ops);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
using namespace Fatfs;
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" Fatfs::DSTATUS disk_initialize (BYTE drv)
|
||||||
|
{
|
||||||
|
if (drv >= Platform::MAX_DEV_NUM) {
|
||||||
|
Genode::error("only ", (int)Platform::MAX_DEV_NUM," supported");
|
||||||
|
return STA_NODISK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_platform->drives[drv]) {
|
||||||
|
destroy(_platform->alloc, _platform->drives[drv]);
|
||||||
|
_platform->drives[drv] = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
String<2> label(drv);
|
||||||
|
_platform->drives[drv] = new (_platform->alloc) Drive(*_platform, label.string());
|
||||||
|
} catch(Service_denied) {
|
||||||
|
Genode::error("could not open block connection for drive ", drv);
|
||||||
|
return STA_NODISK;
|
||||||
|
}
|
||||||
|
|
||||||
|
Drive &drive = *_platform->drives[drv];
|
||||||
|
|
||||||
|
/* check for read- and write-capability */
|
||||||
|
if (!drive.ops.supported(Block::Packet_descriptor::READ)) {
|
||||||
|
Genode::error("drive ", drv, " not readable!");
|
||||||
|
destroy(_platform->alloc, _platform->drives[drv]);
|
||||||
|
_platform->drives[drv] = nullptr;
|
||||||
|
return STA_NOINIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!drive.ops.supported(Block::Packet_descriptor::WRITE))
|
||||||
|
return STA_PROTECT;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" DSTATUS disk_status (BYTE drv)
|
||||||
|
{
|
||||||
|
if (_platform->drives[drv]) {
|
||||||
|
if (_platform->drives[drv]->ops.supported(Block::Packet_descriptor::WRITE))
|
||||||
|
return 0;
|
||||||
|
return STA_PROTECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STA_NOINIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count)
|
||||||
|
{
|
||||||
|
if (!_platform->drives[pdrv])
|
||||||
|
return RES_NOTRDY;
|
||||||
|
|
||||||
|
Drive &drive = *_platform->drives[pdrv];
|
||||||
|
|
||||||
|
Genode::size_t const op_len = drive.block_size*count;
|
||||||
|
|
||||||
|
/* allocate packet-descriptor for reading */
|
||||||
|
Block::Packet_descriptor p(drive.tx()->alloc_packet(op_len),
|
||||||
|
Block::Packet_descriptor::READ, sector, count);
|
||||||
|
drive.tx()->submit_packet(p);
|
||||||
|
p = drive.tx()->get_acked_packet();
|
||||||
|
|
||||||
|
DRESULT res;
|
||||||
|
if (p.succeeded() && p.size() >= op_len) {
|
||||||
|
Genode::memcpy(buff, drive.tx()->packet_content(p), op_len);
|
||||||
|
res = RES_OK;
|
||||||
|
} else {
|
||||||
|
Genode::error(__func__, " failed at sector ", sector, ", count ", count);
|
||||||
|
res = RES_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
drive.tx()->release_packet(p);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if _READONLY == 0
|
||||||
|
extern "C" DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count)
|
||||||
|
{
|
||||||
|
if (!_platform->drives[pdrv])
|
||||||
|
return RES_NOTRDY;
|
||||||
|
|
||||||
|
Drive &drive = *_platform->drives[pdrv];
|
||||||
|
|
||||||
|
Genode::size_t const op_len = drive.block_size*count;
|
||||||
|
|
||||||
|
/* allocate packet-descriptor for writing */
|
||||||
|
Block::Packet_descriptor p(drive.tx()->alloc_packet(op_len),
|
||||||
|
Block::Packet_descriptor::WRITE, sector, count);
|
||||||
|
|
||||||
|
Genode::memcpy(drive.tx()->packet_content(p), buff, op_len);
|
||||||
|
|
||||||
|
drive.tx()->submit_packet(p);
|
||||||
|
p = drive.tx()->get_acked_packet();
|
||||||
|
|
||||||
|
DRESULT res;
|
||||||
|
if (p.succeeded()) {
|
||||||
|
res = RES_OK;
|
||||||
|
} else {
|
||||||
|
Genode::error(__func__, " failed at sector ", sector, ", count ", count);
|
||||||
|
res = RES_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
drive.tx()->release_packet(p);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#endif /* _READONLY */
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff)
|
||||||
|
{
|
||||||
|
if (!_platform->drives[pdrv])
|
||||||
|
return RES_NOTRDY;
|
||||||
|
|
||||||
|
Drive &drive = *_platform->drives[pdrv];
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case CTRL_SYNC:
|
||||||
|
drive.sync();
|
||||||
|
return RES_OK;
|
||||||
|
|
||||||
|
case GET_SECTOR_COUNT:
|
||||||
|
*((DWORD*)buff) = drive.block_count;
|
||||||
|
return RES_OK;
|
||||||
|
|
||||||
|
case GET_SECTOR_SIZE:
|
||||||
|
*((WORD*)buff) = drive.block_size;
|
||||||
|
return RES_OK;
|
||||||
|
|
||||||
|
case GET_BLOCK_SIZE :
|
||||||
|
*((DWORD*)buff) = 1;
|
||||||
|
return RES_OK;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return RES_PARERR;
|
||||||
|
}
|
||||||
|
}
|
72
repos/libports/src/lib/fatfs/ffconf.patch
Normal file
72
repos/libports/src/lib/fatfs/ffconf.patch
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
--- src/lib/fatfs/source/ffconf.h
|
||||||
|
+++ src/lib/fatfs/source/ffconf.h
|
||||||
|
@@ -55,7 +55,7 @@
|
||||||
|
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
|
||||||
|
|
||||||
|
|
||||||
|
-#define FF_USE_LABEL 0
|
||||||
|
+#define FF_USE_LABEL 1
|
||||||
|
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
||||||
|
/ (0:Disable or 1:Enable) */
|
||||||
|
|
||||||
|
@@ -68,7 +68,7 @@
|
||||||
|
/ Locale and Namespace Configurations
|
||||||
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
-#define FF_CODE_PAGE 932
|
||||||
|
+#define FF_CODE_PAGE 0
|
||||||
|
/* This option specifies the OEM code page to be used on the target system.
|
||||||
|
/ Incorrect code page setting can cause a file open failure.
|
||||||
|
/
|
||||||
|
@@ -97,7 +97,7 @@
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
-#define FF_USE_LFN 0
|
||||||
|
+#define FF_USE_LFN 2
|
||||||
|
#define FF_MAX_LFN 255
|
||||||
|
/* The FF_USE_LFN switches the support for LFN (long file name).
|
||||||
|
/
|
||||||
|
@@ -135,7 +135,7 @@
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
-#define FF_FS_RPATH 0
|
||||||
|
+#define FF_FS_RPATH 1
|
||||||
|
/* This option configures support for relative path.
|
||||||
|
/
|
||||||
|
/ 0: Disable relative path and remove related functions.
|
||||||
|
@@ -148,7 +148,7 @@
|
||||||
|
/ Drive/Volume Configurations
|
||||||
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
-#define FF_VOLUMES 1
|
||||||
|
+#define FF_VOLUMES 10
|
||||||
|
/* Number of volumes (logical drives) to be used. (1-10) */
|
||||||
|
|
||||||
|
|
||||||
|
@@ -171,7 +171,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_MIN_SS 512
|
||||||
|
-#define FF_MAX_SS 512
|
||||||
|
+#define FF_MAX_SS 4096
|
||||||
|
/* This set of options configures the range of sector size to be supported. (512,
|
||||||
|
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
|
||||||
|
/ harddisk. But a larger value may be required for on-board flash memory and some
|
||||||
|
@@ -210,13 +210,13 @@
|
||||||
|
/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
|
||||||
|
|
||||||
|
|
||||||
|
-#define FF_FS_EXFAT 0
|
||||||
|
+#define FF_FS_EXFAT 1
|
||||||
|
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
|
||||||
|
/ When enable exFAT, also LFN needs to be enabled.
|
||||||
|
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
|
||||||
|
|
||||||
|
|
||||||
|
-#define FF_FS_NORTC 0
|
||||||
|
+#define FF_FS_NORTC 1
|
||||||
|
#define FF_NORTC_MON 5
|
||||||
|
#define FF_NORTC_MDAY 1
|
||||||
|
#define FF_NORTC_YEAR 2017
|
36
repos/libports/src/lib/fatfs/integer.patch
Normal file
36
repos/libports/src/lib/fatfs/integer.patch
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
--- src/lib/fatfs/source/integer.h 2017-05-21 13:10:48.000000000 -0500
|
||||||
|
+++ src/lib/fatfs/source/integer.h 2017-07-22 10:59:54.856013544 -0500
|
||||||
|
@@ -14,24 +14,26 @@
|
||||||
|
|
||||||
|
#else /* Embedded platform */
|
||||||
|
|
||||||
|
+#include <base/fixed_stdint.h>
|
||||||
|
+
|
||||||
|
/* These types MUST be 16-bit or 32-bit */
|
||||||
|
typedef int INT;
|
||||||
|
typedef unsigned int UINT;
|
||||||
|
|
||||||
|
/* This type MUST be 8-bit */
|
||||||
|
-typedef unsigned char BYTE;
|
||||||
|
+typedef genode_uint8_t BYTE;
|
||||||
|
|
||||||
|
/* These types MUST be 16-bit */
|
||||||
|
-typedef short SHORT;
|
||||||
|
-typedef unsigned short WORD;
|
||||||
|
-typedef unsigned short WCHAR;
|
||||||
|
+typedef genode_int16_t SHORT;
|
||||||
|
+typedef genode_uint16_t WORD;
|
||||||
|
+typedef genode_uint16_t WCHAR;
|
||||||
|
|
||||||
|
/* These types MUST be 32-bit */
|
||||||
|
-typedef long LONG;
|
||||||
|
-typedef unsigned long DWORD;
|
||||||
|
+typedef genode_int32_t LONG;
|
||||||
|
+typedef genode_uint32_t DWORD;
|
||||||
|
|
||||||
|
/* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */
|
||||||
|
-typedef unsigned long long QWORD;
|
||||||
|
+typedef genode_uint64_t QWORD;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -1,37 +0,0 @@
|
|||||||
+++ src/lib/ffat/src/ffconf.h 2012-07-09 13:08:03.000000000 +0200
|
|
||||||
@@ -40,7 +40,7 @@
|
|
||||||
/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
|
|
||||||
|
|
||||||
|
|
||||||
-#define _USE_MKFS 0 /* 0 or 1 */
|
|
||||||
+#define _USE_MKFS 1 /* 0 or 1 */
|
|
||||||
/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
|
|
||||||
|
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@
|
|
||||||
/ Locale and Namespace Configurations
|
|
||||||
/----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
-#define _CODE_PAGE 932
|
|
||||||
+#define _CODE_PAGE 858
|
|
||||||
/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
|
|
||||||
/ Incorrect setting of the code page can cause a file open failure.
|
|
||||||
/
|
|
||||||
@@ -86,7 +86,7 @@
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
-#define _USE_LFN 0 /* 0, 1 or 2 */
|
|
||||||
+#define _USE_LFN 1 /* 0, 1 or 2 */
|
|
||||||
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
|
|
||||||
/* The _USE_LFN option switches the LFN support.
|
|
||||||
/
|
|
||||||
@@ -105,7 +105,7 @@
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
-#define _FS_RPATH 0 /* 0 or 1 */
|
|
||||||
+#define _FS_RPATH 1 /* 0 or 1 */
|
|
||||||
/* When _FS_RPATH is set to 1, relative path feature is enabled and f_chdir,
|
|
||||||
/ f_chdrive function are available.
|
|
||||||
/ Note that output of the f_readdir fnction is affected by this option. */
|
|
@ -1,146 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Low level disk I/O module
|
|
||||||
* \author Sebastian Sumpf <Sebastian.Sumpf@genode-labs.com>
|
|
||||||
* \date 2009-11-20
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2009-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <ffat/diskio.h>
|
|
||||||
#include <dde_linux26/block.h>
|
|
||||||
|
|
||||||
typedef __SIZE_TYPE__ size_t;
|
|
||||||
extern void *memcpy(void *dest, const void *src, size_t n);
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Inidialize a Drive */
|
|
||||||
|
|
||||||
DSTATUS disk_initialize (
|
|
||||||
BYTE drv /* Physical drive nmuber (0..) */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (dde_linux26_block_present((int)drv))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return STA_NOINIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Return Disk Status */
|
|
||||||
|
|
||||||
DSTATUS disk_status (
|
|
||||||
BYTE drv /* Physical drive nmuber (0..) */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (dde_linux26_block_present((int)drv))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return STA_NODISK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Read Sector(s) */
|
|
||||||
|
|
||||||
DRESULT disk_read (
|
|
||||||
BYTE drv, /* Physical drive nmuber (0..) */
|
|
||||||
BYTE *buff, /* Data buffer to store read data */
|
|
||||||
DWORD sector, /* Sector address (LBA) */
|
|
||||||
BYTE count /* Number of sectors to read (1..255) */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
BYTE i;
|
|
||||||
void * dma_buf = dde_linux26_block_malloc(512);
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
result = dde_linux26_block_read((int)drv, (unsigned long)(sector + i), dma_buf);
|
|
||||||
|
|
||||||
switch (result) {
|
|
||||||
case -EBLK_NODEV: return RES_NOTRDY;
|
|
||||||
case -EBLK_FAULT: return RES_PARERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(buff + (i * 512), dma_buf, 512);
|
|
||||||
}
|
|
||||||
dde_linux26_block_free(dma_buf);
|
|
||||||
return RES_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Write Sector(s) */
|
|
||||||
|
|
||||||
#if _READONLY == 0
|
|
||||||
DRESULT disk_write (
|
|
||||||
BYTE drv, /* Physical drive nmuber (0..) */
|
|
||||||
const BYTE *buff, /* Data to be written */
|
|
||||||
DWORD sector, /* Sector address (LBA) */
|
|
||||||
BYTE count /* Number of sectors to write (1..255) */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
BYTE i;
|
|
||||||
void * dma_buf = dde_linux26_block_malloc(512);
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
result = dde_linux26_block_write((int)drv, (unsigned long)(sector + i), dma_buf);
|
|
||||||
|
|
||||||
switch (result) {
|
|
||||||
case -EBLK_NODEV: return RES_NOTRDY;
|
|
||||||
case -EBLK_FAULT: return RES_PARERR;
|
|
||||||
}
|
|
||||||
memcpy(dma_buf, buff + (i * 512), 512);
|
|
||||||
}
|
|
||||||
dde_linux26_block_free(dma_buf);
|
|
||||||
return RES_OK;
|
|
||||||
}
|
|
||||||
#endif /* _READONLY */
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Miscellaneous Functions */
|
|
||||||
|
|
||||||
DRESULT disk_ioctl (
|
|
||||||
BYTE drv, /* Physical drive nmuber (0..) */
|
|
||||||
BYTE ctrl, /* Control code */
|
|
||||||
void *buff /* Buffer to send/receive control data */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
DWORD dresult = 1;
|
|
||||||
if(!dde_linux26_block_present((int)drv))
|
|
||||||
return RES_PARERR;
|
|
||||||
switch (ctrl) {
|
|
||||||
case CTRL_SYNC:
|
|
||||||
break;
|
|
||||||
case GET_SECTOR_SIZE:
|
|
||||||
result = dde_linux26_block_size((int)drv);
|
|
||||||
if (result < 0)
|
|
||||||
return RES_ERROR;
|
|
||||||
memcpy(buff, &result, sizeof(int));
|
|
||||||
break;
|
|
||||||
case GET_SECTOR_COUNT:
|
|
||||||
result = dde_linux26_block_count((int)drv);
|
|
||||||
if(result < 0)
|
|
||||||
return RES_ERROR;
|
|
||||||
memcpy(buff, &result, sizeof(int));
|
|
||||||
break;
|
|
||||||
case GET_BLOCK_SIZE:
|
|
||||||
memcpy(buff, &dresult, sizeof(DWORD));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return RES_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD get_fattime(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,188 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Low level disk I/O module using a Block session
|
|
||||||
* \author Christian Prochaska
|
|
||||||
* \date 2011-05-30
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2011-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Genode includes */
|
|
||||||
#include <base/allocator_avl.h>
|
|
||||||
#include <base/log.h>
|
|
||||||
#include <block_session/connection.h>
|
|
||||||
|
|
||||||
/* Genode block backend */
|
|
||||||
#include <ffat/block.h>
|
|
||||||
|
|
||||||
/* Ffat includes */
|
|
||||||
extern "C" {
|
|
||||||
#include <ffat/diskio.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Ffat {
|
|
||||||
void block_init(Genode::Env &, Genode::Allocator &alloc);
|
|
||||||
}
|
|
||||||
|
|
||||||
using namespace Genode;
|
|
||||||
|
|
||||||
static bool const verbose = false;
|
|
||||||
|
|
||||||
static Constructible<Genode::Allocator_avl> _block_alloc;
|
|
||||||
static Constructible<Block::Connection> _block_connection;
|
|
||||||
static size_t _blk_size = 0;
|
|
||||||
static Block::sector_t _blk_cnt = 0;
|
|
||||||
static Block::Session::Tx::Source *_source;
|
|
||||||
static Genode::Env *_global_env;
|
|
||||||
|
|
||||||
|
|
||||||
void Ffat::block_init(Genode::Env &env, Genode::Allocator &alloc)
|
|
||||||
{
|
|
||||||
_global_env = &env;
|
|
||||||
_block_alloc.construct(&alloc);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" DSTATUS disk_initialize (BYTE drv)
|
|
||||||
{
|
|
||||||
static bool initialized = false;
|
|
||||||
|
|
||||||
if (verbose)
|
|
||||||
Genode::log("disk_initialize(drv=", drv, ") called.");
|
|
||||||
|
|
||||||
if (drv != 0) {
|
|
||||||
Genode::error("only one disk drive is supported at this time.");
|
|
||||||
return STA_NOINIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (initialized) {
|
|
||||||
Genode::error("drv 0 has already been initialized.");
|
|
||||||
return STA_NOINIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
_block_connection.construct(*_global_env, &*_block_alloc);
|
|
||||||
} catch(...) {
|
|
||||||
Genode::error("could not open block connection");
|
|
||||||
return STA_NOINIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
_source = _block_connection->tx();
|
|
||||||
|
|
||||||
Block::Session::Operations ops;
|
|
||||||
_block_connection->info(&_blk_cnt, &_blk_size, &ops);
|
|
||||||
|
|
||||||
/* check for read- and write-capability */
|
|
||||||
if (!ops.supported(Block::Packet_descriptor::READ)) {
|
|
||||||
Genode::error("block device not readable!");
|
|
||||||
_block_connection.destruct();
|
|
||||||
return STA_NOINIT;
|
|
||||||
}
|
|
||||||
if (!ops.supported(Block::Packet_descriptor::WRITE)) {
|
|
||||||
Genode::warning("block device not writeable!");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (verbose)
|
|
||||||
Genode::log(__func__, ": We have ", _blk_cnt, " blocks with a "
|
|
||||||
"size of ", _blk_size, " bytes");
|
|
||||||
|
|
||||||
initialized = true;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" DSTATUS disk_status (BYTE drv)
|
|
||||||
{
|
|
||||||
if (drv != 0) {
|
|
||||||
Genode::error("only one disk drive is supported at this time.");
|
|
||||||
return STA_NODISK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" DRESULT disk_read(BYTE drv, BYTE *buff, DWORD sector, BYTE count)
|
|
||||||
{
|
|
||||||
if (verbose)
|
|
||||||
Genode::log(__func__, ": disk_read(drv=", drv, ", buff=", buff, ", "
|
|
||||||
"sector=", sector, ", count=", count, ") called.");
|
|
||||||
|
|
||||||
if (drv != 0) {
|
|
||||||
Genode::error("only one disk drive is supported at this time.");
|
|
||||||
return RES_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allocate packet-descriptor for reading */
|
|
||||||
Block::Packet_descriptor p(_source->alloc_packet(_blk_size),
|
|
||||||
Block::Packet_descriptor::READ, sector, count);
|
|
||||||
_source->submit_packet(p);
|
|
||||||
p = _source->get_acked_packet();
|
|
||||||
|
|
||||||
/* check for success of operation */
|
|
||||||
if (!p.succeeded()) {
|
|
||||||
Genode::error("could not read block(s)");
|
|
||||||
_source->release_packet(p);
|
|
||||||
return RES_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(buff, _source->packet_content(p), count * _blk_size);
|
|
||||||
|
|
||||||
_source->release_packet(p);
|
|
||||||
return RES_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if _READONLY == 0
|
|
||||||
extern "C" DRESULT disk_write(BYTE drv, const BYTE *buff, DWORD sector, BYTE count)
|
|
||||||
{
|
|
||||||
if (verbose)
|
|
||||||
Genode::log(__func__, ": disk_write(drv=", drv, ", buff=", buff, ", "
|
|
||||||
"sector=", sector, ", count=", count, ") called.");
|
|
||||||
|
|
||||||
if (drv != 0) {
|
|
||||||
Genode::error("only one disk drive is supported at this time.");
|
|
||||||
return RES_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allocate packet-descriptor for writing */
|
|
||||||
Block::Packet_descriptor p(_source->alloc_packet(_blk_size),
|
|
||||||
Block::Packet_descriptor::WRITE, sector, count);
|
|
||||||
|
|
||||||
memcpy(_source->packet_content(p), buff, count * _blk_size);
|
|
||||||
|
|
||||||
_source->submit_packet(p);
|
|
||||||
p = _source->get_acked_packet();
|
|
||||||
|
|
||||||
/* check for success of operation */
|
|
||||||
if (!p.succeeded()) {
|
|
||||||
Genode::error("could not write block(s)");
|
|
||||||
_source->release_packet(p);
|
|
||||||
return RES_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
_source->release_packet(p);
|
|
||||||
return RES_OK;
|
|
||||||
}
|
|
||||||
#endif /* _READONLY */
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" DRESULT disk_ioctl(BYTE drv, BYTE ctrl, void *buff)
|
|
||||||
{
|
|
||||||
Genode::warning(__func__, "(drv=", drv, ", ctrl=", ctrl, ", buff=", buff, ") "
|
|
||||||
"called - not yet implemented.");
|
|
||||||
return RES_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" DWORD get_fattime(void)
|
|
||||||
{
|
|
||||||
Genode::warning(__func__, "() called - not yet implemented.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* \brief FFAT libc plugin
|
* \brief FATFS libc plugin
|
||||||
* \author Christian Prochaska
|
* \author Christian Prochaska
|
||||||
* \date 2011-05-27
|
* \date 2011-05-27
|
||||||
*/
|
*/
|
||||||
@ -29,21 +29,12 @@
|
|||||||
#include <libc-plugin/plugin.h>
|
#include <libc-plugin/plugin.h>
|
||||||
#include <libc-plugin/fd_alloc.h>
|
#include <libc-plugin/fd_alloc.h>
|
||||||
|
|
||||||
/* Genode block backend */
|
#include <fatfs/block.h>
|
||||||
#include <ffat/block.h>
|
|
||||||
|
|
||||||
/* ffat includes */
|
namespace Fatfs { extern "C" {
|
||||||
namespace Ffat { extern "C" {
|
#include <fatfs/ff.h>
|
||||||
#include <ffat/ff.h>
|
|
||||||
} }
|
} }
|
||||||
|
|
||||||
/*
|
|
||||||
* These macros are defined in later versions of the FatFs lib, but not in the
|
|
||||||
* one currently used for Genode.
|
|
||||||
*/
|
|
||||||
#define f_size(fp) ((fp)->fsize)
|
|
||||||
#define f_tell(fp) ((fp)->fptr)
|
|
||||||
|
|
||||||
static bool const verbose = false;
|
static bool const verbose = false;
|
||||||
|
|
||||||
|
|
||||||
@ -98,7 +89,7 @@ class File_plugin_context : public Plugin_context
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Ffat::FIL _ffat_file;
|
Fatfs::FIL _fatfs_file;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -106,13 +97,13 @@ class File_plugin_context : public Plugin_context
|
|||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* \param filename
|
* \param filename
|
||||||
* \param ffat_file file object used for interacting with the
|
* \param fatfs_file file object used for interacting with the
|
||||||
* file API of ffat
|
* file API of fatfs
|
||||||
*/
|
*/
|
||||||
File_plugin_context(const char *filename, Ffat::FIL ffat_file) :
|
File_plugin_context(const char *filename, Fatfs::FIL fatfs_file) :
|
||||||
Plugin_context(filename), _ffat_file(ffat_file) { }
|
Plugin_context(filename), _fatfs_file(fatfs_file) { }
|
||||||
|
|
||||||
Ffat::FIL *ffat_file() { return &_ffat_file; }
|
Fatfs::FIL *fatfs_file() { return &_fatfs_file; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -120,7 +111,7 @@ class Directory_plugin_context : public Plugin_context
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Ffat::DIR _ffat_dir;
|
Fatfs::DIR _fatfs_dir;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -128,13 +119,13 @@ class Directory_plugin_context : public Plugin_context
|
|||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* \param filename
|
* \param filename
|
||||||
* \param ffat_dir dir object used for interacting with the
|
* \param fatfs_dir dir object used for interacting with the
|
||||||
* file API of ffat
|
* file API of fatfs
|
||||||
*/
|
*/
|
||||||
Directory_plugin_context(const char *filename, Ffat::DIR ffat_dir) :
|
Directory_plugin_context(const char *filename, Fatfs::DIR fatfs_dir) :
|
||||||
Plugin_context(filename), _ffat_dir(ffat_dir) { }
|
Plugin_context(filename), _fatfs_dir(fatfs_dir) { }
|
||||||
|
|
||||||
Ffat::DIR *ffat_dir() { return &_ffat_dir; }
|
Fatfs::DIR *fatfs_dir() { return &_fatfs_dir; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -144,26 +135,26 @@ class Plugin : public Libc::Plugin
|
|||||||
|
|
||||||
Genode::Constructible<Genode::Heap> _heap;
|
Genode::Constructible<Genode::Heap> _heap;
|
||||||
|
|
||||||
Ffat::FATFS _fatfs;
|
Fatfs::FATFS _fatfs;
|
||||||
|
|
||||||
Ffat::FIL *_get_ffat_file(Libc::File_descriptor *fd)
|
Fatfs::FIL *_get_fatfs_file(Libc::File_descriptor *fd)
|
||||||
{
|
{
|
||||||
File_plugin_context *file_plugin_context =
|
File_plugin_context *file_plugin_context =
|
||||||
dynamic_cast<File_plugin_context*>(context(fd));
|
dynamic_cast<File_plugin_context*>(context(fd));
|
||||||
if (!file_plugin_context) {
|
if (!file_plugin_context) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return file_plugin_context->ffat_file();
|
return file_plugin_context->fatfs_file();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ffat::DIR *_get_ffat_dir(Libc::File_descriptor *fd)
|
Fatfs::DIR *_get_fatfs_dir(Libc::File_descriptor *fd)
|
||||||
{
|
{
|
||||||
Directory_plugin_context *directory_plugin_context =
|
Directory_plugin_context *directory_plugin_context =
|
||||||
dynamic_cast<Directory_plugin_context*>(context(fd));
|
dynamic_cast<Directory_plugin_context*>(context(fd));
|
||||||
if (!directory_plugin_context) {
|
if (!directory_plugin_context) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return directory_plugin_context->ffat_dir();
|
return directory_plugin_context->fatfs_dir();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -181,20 +172,20 @@ class Plugin : public Libc::Plugin
|
|||||||
~Plugin()
|
~Plugin()
|
||||||
{
|
{
|
||||||
/* unmount the file system */
|
/* unmount the file system */
|
||||||
Ffat::f_mount(0, NULL);
|
Fatfs::f_unmount("");
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(Genode::Env &env) override
|
void init(Genode::Env &env) override
|
||||||
{
|
{
|
||||||
_heap.construct(env.ram(), env.rm());
|
_heap.construct(env.ram(), env.rm());
|
||||||
|
|
||||||
Ffat::block_init(env, *_heap);
|
Fatfs::block_init(env, *_heap);
|
||||||
|
|
||||||
/* mount the file system */
|
/* mount the file system */
|
||||||
if (verbose)
|
if (verbose)
|
||||||
Genode::log(__func__, ": mounting device ...");
|
Genode::log(__func__, ": mounting device ...");
|
||||||
|
|
||||||
if (f_mount(0, &_fatfs) != Ffat::FR_OK) {
|
if (f_mount(&_fatfs, "", 0) != Fatfs::FR_OK) {
|
||||||
Genode::error("mount failed");
|
Genode::error("mount failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -248,7 +239,7 @@ class Plugin : public Libc::Plugin
|
|||||||
bool supports_symlink(const char *, const char *) override
|
bool supports_symlink(const char *, const char *) override
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Even though FFAT does not support symlinks, we still want
|
* Even though FATFS does not support symlinks, we still want
|
||||||
* to capture calls of 'symlink' to return ENOSYS, which is
|
* to capture calls of 'symlink' to return ENOSYS, which is
|
||||||
* checked in the file-system test.
|
* checked in the file-system test.
|
||||||
*/
|
*/
|
||||||
@ -257,18 +248,18 @@ class Plugin : public Libc::Plugin
|
|||||||
|
|
||||||
int close(Libc::File_descriptor *fd) override
|
int close(Libc::File_descriptor *fd) override
|
||||||
{
|
{
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
FIL *ffat_file = _get_ffat_file(fd);
|
FIL *fatfs_file = _get_fatfs_file(fd);
|
||||||
|
|
||||||
if (!ffat_file){
|
if (!fatfs_file){
|
||||||
/* directory */
|
/* directory */
|
||||||
Genode::destroy(&*_heap, context(fd));
|
Genode::destroy(&*_heap, context(fd));
|
||||||
Libc::file_descriptor_allocator()->free(fd);
|
Libc::file_descriptor_allocator()->free(fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FRESULT res = f_close(ffat_file);
|
FRESULT res = f_close(fatfs_file);
|
||||||
|
|
||||||
Genode::destroy(&*_heap, context(fd));
|
Genode::destroy(&*_heap, context(fd));
|
||||||
Libc::file_descriptor_allocator()->free(fd);
|
Libc::file_descriptor_allocator()->free(fd);
|
||||||
@ -283,7 +274,7 @@ class Plugin : public Libc::Plugin
|
|||||||
errno = EIO;
|
errno = EIO;
|
||||||
return -1;
|
return -1;
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
Genode::error("f_close() returned an unexpected error code");
|
Genode::error("f_close() returned an unexpected error code");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -314,9 +305,9 @@ class Plugin : public Libc::Plugin
|
|||||||
|
|
||||||
int fsync(Libc::File_descriptor *fd) override
|
int fsync(Libc::File_descriptor *fd) override
|
||||||
{
|
{
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
FRESULT res = f_sync(_get_ffat_file(fd));
|
FRESULT res = f_sync(_get_fatfs_file(fd));
|
||||||
|
|
||||||
switch(res) {
|
switch(res) {
|
||||||
case FR_OK:
|
case FR_OK:
|
||||||
@ -328,7 +319,7 @@ class Plugin : public Libc::Plugin
|
|||||||
errno = EIO;
|
errno = EIO;
|
||||||
return -1;
|
return -1;
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
Genode::error("f_sync() returned an unexpected error code");
|
Genode::error("f_sync() returned an unexpected error code");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -336,14 +327,14 @@ class Plugin : public Libc::Plugin
|
|||||||
|
|
||||||
int ftruncate(Libc::File_descriptor *fd, ::off_t length) override
|
int ftruncate(Libc::File_descriptor *fd, ::off_t length) override
|
||||||
{
|
{
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
/* 'f_truncate()' truncates to the current seek pointer */
|
/* 'f_truncate()' truncates to the current seek pointer */
|
||||||
|
|
||||||
if (lseek(fd, length, SEEK_SET) == -1)
|
if (lseek(fd, length, SEEK_SET) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
FRESULT res = f_truncate(_get_ffat_file(fd));
|
FRESULT res = f_truncate(_get_fatfs_file(fd));
|
||||||
|
|
||||||
switch(res) {
|
switch(res) {
|
||||||
case FR_OK:
|
case FR_OK:
|
||||||
@ -355,7 +346,7 @@ class Plugin : public Libc::Plugin
|
|||||||
errno = EIO;
|
errno = EIO;
|
||||||
return -1;
|
return -1;
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
Genode::error("f_truncate() returned an unexpected error code");
|
Genode::error("f_truncate() returned an unexpected error code");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -364,7 +355,7 @@ class Plugin : public Libc::Plugin
|
|||||||
ssize_t getdirentries(Libc::File_descriptor *fd, char *buf,
|
ssize_t getdirentries(Libc::File_descriptor *fd, char *buf,
|
||||||
::size_t nbytes, ::off_t *basep) override
|
::size_t nbytes, ::off_t *basep) override
|
||||||
{
|
{
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
if (nbytes < sizeof(struct dirent)) {
|
if (nbytes < sizeof(struct dirent)) {
|
||||||
Genode::error(__func__, ": buf too small");
|
Genode::error(__func__, ": buf too small");
|
||||||
@ -375,11 +366,9 @@ class Plugin : public Libc::Plugin
|
|||||||
struct dirent *dirent = (struct dirent *)buf;
|
struct dirent *dirent = (struct dirent *)buf;
|
||||||
::memset(dirent, 0, sizeof(struct dirent));
|
::memset(dirent, 0, sizeof(struct dirent));
|
||||||
|
|
||||||
FILINFO ffat_file_info;
|
FILINFO fatfs_file_info;
|
||||||
ffat_file_info.lfname = dirent->d_name;
|
|
||||||
ffat_file_info.lfsize = sizeof(dirent->d_name);
|
|
||||||
|
|
||||||
FRESULT res = f_readdir(_get_ffat_dir(fd), &ffat_file_info);
|
FRESULT res = f_readdir(_get_fatfs_dir(fd), &fatfs_file_info);
|
||||||
switch(res) {
|
switch(res) {
|
||||||
case FR_OK:
|
case FR_OK:
|
||||||
break;
|
break;
|
||||||
@ -390,12 +379,12 @@ class Plugin : public Libc::Plugin
|
|||||||
errno = EIO;
|
errno = EIO;
|
||||||
return -1;
|
return -1;
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
Genode::error("f_readdir() returned an unexpected error code");
|
Genode::error("f_readdir() returned an unexpected error code");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ffat_file_info.fname[0] == 0) { /* no (more) entries */
|
if (fatfs_file_info.fname[0] == 0) { /* no (more) entries */
|
||||||
if (verbose)
|
if (verbose)
|
||||||
Genode::log(__func__, ": no more dir entries");
|
Genode::log(__func__, ": no more dir entries");
|
||||||
/* TODO: reset the f_readdir() index? */
|
/* TODO: reset the f_readdir() index? */
|
||||||
@ -404,16 +393,14 @@ class Plugin : public Libc::Plugin
|
|||||||
|
|
||||||
dirent->d_ino = 1; /* libc's readdir() wants an inode number */
|
dirent->d_ino = 1; /* libc's readdir() wants an inode number */
|
||||||
|
|
||||||
if ((ffat_file_info.fattrib & AM_DIR) == AM_DIR)
|
if ((fatfs_file_info.fattrib & AM_DIR) == AM_DIR)
|
||||||
dirent->d_type = DT_DIR;
|
dirent->d_type = DT_DIR;
|
||||||
else
|
else
|
||||||
dirent->d_type = DT_REG;
|
dirent->d_type = DT_REG;
|
||||||
|
|
||||||
dirent->d_reclen = sizeof(struct dirent);
|
dirent->d_reclen = sizeof(struct dirent);
|
||||||
|
|
||||||
if (dirent->d_name[0] == 0) /* use short file name */
|
::strncpy(dirent->d_name, fatfs_file_info.fname, sizeof(dirent->d_name));
|
||||||
::strncpy(dirent->d_name, ffat_file_info.fname,
|
|
||||||
sizeof(dirent->d_name));
|
|
||||||
|
|
||||||
dirent->d_namlen = ::strlen(dirent->d_name);
|
dirent->d_namlen = ::strlen(dirent->d_name);
|
||||||
|
|
||||||
@ -426,25 +413,25 @@ class Plugin : public Libc::Plugin
|
|||||||
|
|
||||||
::off_t lseek(Libc::File_descriptor *fd, ::off_t offset, int whence) override
|
::off_t lseek(Libc::File_descriptor *fd, ::off_t offset, int whence) override
|
||||||
{
|
{
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
switch(whence) {
|
switch(whence) {
|
||||||
case SEEK_CUR:
|
case SEEK_CUR:
|
||||||
offset += f_tell(_get_ffat_file(fd));
|
offset += f_tell(_get_fatfs_file(fd));
|
||||||
break;
|
break;
|
||||||
case SEEK_END:
|
case SEEK_END:
|
||||||
offset += f_size(_get_ffat_file(fd));
|
offset += f_size(_get_fatfs_file(fd));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
FRESULT res = f_lseek(_get_ffat_file(fd), offset);
|
FRESULT res = f_lseek(_get_fatfs_file(fd), offset);
|
||||||
|
|
||||||
switch(res) {
|
switch(res) {
|
||||||
case FR_OK:
|
case FR_OK:
|
||||||
/* according to the FatFs documentation this can happen */
|
/* according to the FatFs documentation this can happen */
|
||||||
if ((off_t)f_tell(_get_ffat_file(fd)) != offset) {
|
if ((off_t)f_tell(_get_fatfs_file(fd)) != offset) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -456,7 +443,7 @@ class Plugin : public Libc::Plugin
|
|||||||
errno = EIO;
|
errno = EIO;
|
||||||
return -1;
|
return -1;
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
Genode::error("f_lseek() returned an unexpected error code");
|
Genode::error("f_lseek() returned an unexpected error code");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -464,7 +451,7 @@ class Plugin : public Libc::Plugin
|
|||||||
|
|
||||||
int mkdir(const char *path, mode_t mode) override
|
int mkdir(const char *path, mode_t mode) override
|
||||||
{
|
{
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
FRESULT res = f_mkdir(path);
|
FRESULT res = f_mkdir(path);
|
||||||
|
|
||||||
@ -491,7 +478,7 @@ class Plugin : public Libc::Plugin
|
|||||||
errno = EIO;
|
errno = EIO;
|
||||||
return -1;
|
return -1;
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
Genode::error("f_mkdir() returned an unexpected error code");
|
Genode::error("f_mkdir() returned an unexpected error code");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -499,34 +486,34 @@ class Plugin : public Libc::Plugin
|
|||||||
|
|
||||||
Libc::File_descriptor *open(const char *pathname, int flags) override
|
Libc::File_descriptor *open(const char *pathname, int flags) override
|
||||||
{
|
{
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
Genode::log(__func__, ": pathname=", pathname);
|
Genode::log(__func__, ": pathname=", pathname);
|
||||||
|
|
||||||
FIL ffat_file;
|
FIL fatfs_file;
|
||||||
BYTE ffat_flags = 0;
|
BYTE fatfs_flags = 0;
|
||||||
|
|
||||||
/* convert libc flags to libffat flags */
|
/* convert libc flags to fatfs flags */
|
||||||
if (((flags & O_RDONLY) == O_RDONLY) || ((flags & O_RDWR) == O_RDWR))
|
if (((flags & O_RDONLY) == O_RDONLY) || ((flags & O_RDWR) == O_RDWR))
|
||||||
ffat_flags |= FA_READ;
|
fatfs_flags |= FA_READ;
|
||||||
|
|
||||||
if (((flags & O_WRONLY) == O_WRONLY) || ((flags & O_RDWR) == O_RDWR))
|
if (((flags & O_WRONLY) == O_WRONLY) || ((flags & O_RDWR) == O_RDWR))
|
||||||
ffat_flags |= FA_WRITE;
|
fatfs_flags |= FA_WRITE;
|
||||||
|
|
||||||
if ((flags & O_CREAT) == O_CREAT) {
|
if ((flags & O_CREAT) == O_CREAT) {
|
||||||
if ((flags & O_EXCL) == O_EXCL)
|
if ((flags & O_EXCL) == O_EXCL)
|
||||||
ffat_flags |= FA_CREATE_NEW;
|
fatfs_flags |= FA_CREATE_NEW;
|
||||||
else
|
else
|
||||||
ffat_flags |= FA_OPEN_ALWAYS;
|
fatfs_flags |= FA_OPEN_ALWAYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
FRESULT res = f_open(&ffat_file, pathname, ffat_flags);
|
FRESULT res = f_open(&fatfs_file, pathname, fatfs_flags);
|
||||||
|
|
||||||
switch(res) {
|
switch(res) {
|
||||||
case FR_OK: {
|
case FR_OK: {
|
||||||
Plugin_context *context = new (&*_heap)
|
Plugin_context *context = new (&*_heap)
|
||||||
File_plugin_context(pathname, ffat_file);
|
File_plugin_context(pathname, fatfs_file);
|
||||||
context->status_flags(flags);
|
context->status_flags(flags);
|
||||||
Libc::File_descriptor *fd = Libc::file_descriptor_allocator()->alloc(this, context);
|
Libc::File_descriptor *fd = Libc::file_descriptor_allocator()->alloc(this, context);
|
||||||
if ((flags & O_TRUNC) && (ftruncate(fd, 0) == -1))
|
if ((flags & O_TRUNC) && (ftruncate(fd, 0) == -1))
|
||||||
@ -539,14 +526,14 @@ class Plugin : public Libc::Plugin
|
|||||||
* that's not supported by f_open(). So we call
|
* that's not supported by f_open(). So we call
|
||||||
* f_opendir() in case the file is a directory.
|
* f_opendir() in case the file is a directory.
|
||||||
*/
|
*/
|
||||||
Ffat::DIR ffat_dir;
|
Fatfs::DIR fatfs_dir;
|
||||||
FRESULT f_opendir_res = f_opendir(&ffat_dir, pathname);
|
FRESULT f_opendir_res = f_opendir(&fatfs_dir, pathname);
|
||||||
if (verbose)
|
if (verbose)
|
||||||
Genode::log(__func__, ": opendir res=", (int)f_opendir_res);
|
Genode::log(__func__, ": opendir res=", (int)f_opendir_res);
|
||||||
switch(f_opendir_res) {
|
switch(f_opendir_res) {
|
||||||
case FR_OK: {
|
case FR_OK: {
|
||||||
Plugin_context *context = new (&*_heap)
|
Plugin_context *context = new (&*_heap)
|
||||||
Directory_plugin_context(pathname, ffat_dir);
|
Directory_plugin_context(pathname, fatfs_dir);
|
||||||
context->status_flags(flags);
|
context->status_flags(flags);
|
||||||
Libc::File_descriptor *f =
|
Libc::File_descriptor *f =
|
||||||
Libc::file_descriptor_allocator()->alloc(this, context);
|
Libc::file_descriptor_allocator()->alloc(this, context);
|
||||||
@ -568,7 +555,7 @@ class Plugin : public Libc::Plugin
|
|||||||
errno = EIO;
|
errno = EIO;
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
Genode::error("f_opendir() returned an unexpected error code");
|
Genode::error("f_opendir() returned an unexpected error code");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -593,7 +580,7 @@ class Plugin : public Libc::Plugin
|
|||||||
errno = EIO;
|
errno = EIO;
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
Genode::error("f_open() returned an unexpected error code");
|
Genode::error("f_open() returned an unexpected error code");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -601,10 +588,16 @@ class Plugin : public Libc::Plugin
|
|||||||
|
|
||||||
int rename(const char *oldpath, const char *newpath) override
|
int rename(const char *oldpath, const char *newpath) override
|
||||||
{
|
{
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
FRESULT res = f_rename(oldpath, newpath);
|
FRESULT res = f_rename(oldpath, newpath);
|
||||||
|
|
||||||
|
/* if newpath already exists - try to unlink it once */
|
||||||
|
if (res == FR_EXIST) {
|
||||||
|
f_unlink(newpath);
|
||||||
|
res = f_rename(oldpath, newpath);
|
||||||
|
}
|
||||||
|
|
||||||
switch(res) {
|
switch(res) {
|
||||||
case FR_OK:
|
case FR_OK:
|
||||||
return 0;
|
return 0;
|
||||||
@ -616,7 +609,7 @@ class Plugin : public Libc::Plugin
|
|||||||
return 0;
|
return 0;
|
||||||
case FR_EXIST:
|
case FR_EXIST:
|
||||||
errno = EEXIST;
|
errno = EEXIST;
|
||||||
return 0;
|
return -1;
|
||||||
case FR_DENIED:
|
case FR_DENIED:
|
||||||
case FR_WRITE_PROTECTED:
|
case FR_WRITE_PROTECTED:
|
||||||
errno = EACCES;
|
errno = EACCES;
|
||||||
@ -629,7 +622,7 @@ class Plugin : public Libc::Plugin
|
|||||||
errno = EIO;
|
errno = EIO;
|
||||||
return -1;
|
return -1;
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
Genode::error("f_rename() returned an unexpected error code");
|
Genode::error("f_rename() returned an unexpected error code");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -637,10 +630,10 @@ class Plugin : public Libc::Plugin
|
|||||||
|
|
||||||
ssize_t read(Libc::File_descriptor *fd, void *buf, ::size_t count) override
|
ssize_t read(Libc::File_descriptor *fd, void *buf, ::size_t count) override
|
||||||
{
|
{
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
UINT result;
|
UINT result;
|
||||||
FRESULT res = f_read(_get_ffat_file(fd), buf, count, &result);
|
FRESULT res = f_read(_get_fatfs_file(fd), buf, count, &result);
|
||||||
|
|
||||||
switch(res) {
|
switch(res) {
|
||||||
case FR_OK:
|
case FR_OK:
|
||||||
@ -655,7 +648,7 @@ class Plugin : public Libc::Plugin
|
|||||||
errno = EIO;
|
errno = EIO;
|
||||||
return -1;
|
return -1;
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
Genode::error("f_read() returned an unexpected error code");
|
Genode::error("f_read() returned an unexpected error code");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -663,12 +656,9 @@ class Plugin : public Libc::Plugin
|
|||||||
|
|
||||||
int stat(const char *path, struct stat *buf) override
|
int stat(const char *path, struct stat *buf) override
|
||||||
{
|
{
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
FILINFO file_info;
|
FILINFO file_info;
|
||||||
/* the long file name is not used in this function */
|
|
||||||
file_info.lfname = 0;
|
|
||||||
file_info.lfsize = 0;
|
|
||||||
|
|
||||||
::memset(buf, 0, sizeof(struct stat));
|
::memset(buf, 0, sizeof(struct stat));
|
||||||
|
|
||||||
@ -697,7 +687,7 @@ class Plugin : public Libc::Plugin
|
|||||||
errno = EIO;
|
errno = EIO;
|
||||||
return -1;
|
return -1;
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
Genode::error("f_stat() returned an unexpected error code");
|
Genode::error("f_stat() returned an unexpected error code");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -741,7 +731,7 @@ class Plugin : public Libc::Plugin
|
|||||||
|
|
||||||
int unlink(const char *path) override
|
int unlink(const char *path) override
|
||||||
{
|
{
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
FRESULT res = f_unlink(path);
|
FRESULT res = f_unlink(path);
|
||||||
|
|
||||||
@ -766,7 +756,7 @@ class Plugin : public Libc::Plugin
|
|||||||
errno = EIO;
|
errno = EIO;
|
||||||
return -1;
|
return -1;
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
Genode::error("f_unlink() returned an unexpected error code");
|
Genode::error("f_unlink() returned an unexpected error code");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -779,10 +769,10 @@ class Plugin : public Libc::Plugin
|
|||||||
|
|
||||||
ssize_t write(Libc::File_descriptor *fd, const void *buf, ::size_t count) override
|
ssize_t write(Libc::File_descriptor *fd, const void *buf, ::size_t count) override
|
||||||
{
|
{
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
UINT result;
|
UINT result;
|
||||||
FRESULT res = f_write(_get_ffat_file(fd), buf, count, &result);
|
FRESULT res = f_write(_get_fatfs_file(fd), buf, count, &result);
|
||||||
|
|
||||||
switch(res) {
|
switch(res) {
|
||||||
case FR_OK:
|
case FR_OK:
|
||||||
@ -797,7 +787,7 @@ class Plugin : public Libc::Plugin
|
|||||||
errno = EIO;
|
errno = EIO;
|
||||||
return -1;
|
return -1;
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
Genode::error("f_write() returned an unexpected error code");
|
Genode::error("f_write() returned an unexpected error code");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -814,7 +804,7 @@ class Plugin : public Libc::Plugin
|
|||||||
} /* unnamed namespace */
|
} /* unnamed namespace */
|
||||||
|
|
||||||
|
|
||||||
void __attribute__((constructor)) init_libc_ffat(void)
|
void __attribute__((constructor)) init_libc_fatfs(void)
|
||||||
{
|
{
|
||||||
static Plugin plugin;
|
static Plugin plugin;
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* \brief FFAT file-system directory node
|
* \brief FATFS file-system directory node
|
||||||
* \author Christian Prochaska
|
* \author Christian Prochaska
|
||||||
* \date 2012-07-04
|
* \date 2012-07-04
|
||||||
*/
|
*/
|
||||||
@ -14,25 +14,25 @@
|
|||||||
#ifndef _DIRECTORY_H_
|
#ifndef _DIRECTORY_H_
|
||||||
#define _DIRECTORY_H_
|
#define _DIRECTORY_H_
|
||||||
|
|
||||||
/* ffat includes */
|
/* fatfs includes */
|
||||||
namespace Ffat { extern "C" {
|
namespace Fatfs { extern "C" {
|
||||||
#include <ffat/ff.h>
|
#include <fatfs/ff.h>
|
||||||
} }
|
} }
|
||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
#include <node.h>
|
#include <node.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Ffat_fs {
|
namespace Fatfs_fs {
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
class Directory;
|
class Directory;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Ffat_fs::Directory : public Node
|
class Fatfs_fs::Directory : public Node
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Ffat::DIR _ffat_dir;
|
Fatfs::DIR _fatfs_dir;
|
||||||
int64_t _prev_index;
|
int64_t _prev_index;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -41,8 +41,8 @@ class Ffat_fs::Directory : public Node
|
|||||||
: Node(name),
|
: Node(name),
|
||||||
_prev_index(-1) { }
|
_prev_index(-1) { }
|
||||||
|
|
||||||
void ffat_dir(Ffat::DIR ffat_dir) { _ffat_dir = ffat_dir; }
|
void fatfs_dir(Fatfs::DIR fatfs_dir) { _fatfs_dir = fatfs_dir; }
|
||||||
Ffat::DIR *ffat_dir() { return &_ffat_dir; }
|
Fatfs::DIR *fatfs_dir() { return &_fatfs_dir; }
|
||||||
|
|
||||||
size_t read(char *dst, size_t len, seek_off_t seek_offset)
|
size_t read(char *dst, size_t len, seek_off_t seek_offset)
|
||||||
{
|
{
|
||||||
@ -58,24 +58,22 @@ class Ffat_fs::Directory : public Node
|
|||||||
|
|
||||||
Directory_entry *e = (Directory_entry *)(dst);
|
Directory_entry *e = (Directory_entry *)(dst);
|
||||||
|
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
FILINFO ffat_file_info;
|
FILINFO fatfs_file_info;
|
||||||
ffat_file_info.lfname = e->name;
|
|
||||||
ffat_file_info.lfsize = sizeof(e->name);
|
|
||||||
|
|
||||||
int64_t index = seek_offset / sizeof(Directory_entry);
|
int64_t index = seek_offset / sizeof(Directory_entry);
|
||||||
|
|
||||||
if (index != (_prev_index + 1)) {
|
if (index != (_prev_index + 1)) {
|
||||||
/* rewind and iterate from the beginning */
|
/* rewind and iterate from the beginning */
|
||||||
f_readdir(&_ffat_dir, 0);
|
f_readdir(&_fatfs_dir, 0);
|
||||||
for (int i = 0; i < index; i++)
|
for (int i = 0; i < index; i++)
|
||||||
f_readdir(&_ffat_dir, &ffat_file_info);
|
f_readdir(&_fatfs_dir, &fatfs_file_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
_prev_index = index;
|
_prev_index = index;
|
||||||
|
|
||||||
FRESULT res = f_readdir(&_ffat_dir, &ffat_file_info);
|
FRESULT res = f_readdir(&_fatfs_dir, &fatfs_file_info);
|
||||||
switch(res) {
|
switch(res) {
|
||||||
case FR_OK:
|
case FR_OK:
|
||||||
break;
|
break;
|
||||||
@ -92,19 +90,18 @@ class Ffat_fs::Directory : public Node
|
|||||||
error("f_readdir() failed with error code FR_NOT_READY");
|
error("f_readdir() failed with error code FR_NOT_READY");
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the libfatfs documentation */
|
||||||
error("f_readdir() returned an unexpected error code");
|
error("f_readdir() returned an unexpected error code");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ffat_file_info.fname[0] == 0) { /* no (more) entries */
|
if (fatfs_file_info.fname[0] == 0) { /* no (more) entries */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e->name[0] == 0) /* use short file name */
|
strncpy(e->name, fatfs_file_info.fname, sizeof(e->name));
|
||||||
strncpy(e->name, ffat_file_info.fname, sizeof(e->name));
|
|
||||||
|
|
||||||
if ((ffat_file_info.fattrib & AM_DIR) == AM_DIR)
|
if ((fatfs_file_info.fattrib & AM_DIR) == AM_DIR)
|
||||||
e->type = Directory_entry::TYPE_DIRECTORY;
|
e->type = Directory_entry::TYPE_DIRECTORY;
|
||||||
else
|
else
|
||||||
e->type = Directory_entry::TYPE_FILE;
|
e->type = Directory_entry::TYPE_FILE;
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* \brief FFAT file-system file node
|
* \brief FATFS file-system file node
|
||||||
* \author Christian Prochaska
|
* \author Christian Prochaska
|
||||||
* \date 2012-07-04
|
* \date 2012-07-04
|
||||||
*/
|
*/
|
||||||
@ -14,24 +14,24 @@
|
|||||||
#ifndef _FILE_H_
|
#ifndef _FILE_H_
|
||||||
#define _FILE_H_
|
#define _FILE_H_
|
||||||
|
|
||||||
/* ffat includes */
|
/* fatfs includes */
|
||||||
namespace Ffat { extern "C" {
|
namespace Fatfs { extern "C" {
|
||||||
#include <ffat/ff.h>
|
#include <fatfs/ff.h>
|
||||||
} }
|
} }
|
||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
#include <node.h>
|
#include <node.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Ffat_fs {
|
namespace Fatfs_fs {
|
||||||
class File;
|
class File;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Ffat_fs::File : public Node
|
class Fatfs_fs::File : public Node
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Ffat::FIL _ffat_fil;
|
Fatfs::FIL _fatfs_fil;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -39,9 +39,9 @@ class Ffat_fs::File : public Node
|
|||||||
|
|
||||||
~File()
|
~File()
|
||||||
{
|
{
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
FRESULT res = f_close(&_ffat_fil);
|
FRESULT res = f_close(&_fatfs_fil);
|
||||||
|
|
||||||
switch(res) {
|
switch(res) {
|
||||||
case FR_OK:
|
case FR_OK:
|
||||||
@ -59,25 +59,29 @@ class Ffat_fs::File : public Node
|
|||||||
error("f_close() failed with error code FR_NOT_READY");
|
error("f_close() failed with error code FR_NOT_READY");
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
error("f_close() returned an unexpected error code");
|
error("f_close() returned an unexpected error code");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ffat_fil(Ffat::FIL ffat_fil) { _ffat_fil = ffat_fil; }
|
void fatfs_fil(Fatfs::FIL fatfs_fil) { _fatfs_fil = fatfs_fil; }
|
||||||
Ffat::FIL *ffat_fil() { return &_ffat_fil; }
|
Fatfs::FIL *fatfs_fil() { return &_fatfs_fil; }
|
||||||
|
|
||||||
size_t read(char *dst, size_t len, seek_off_t seek_offset) override
|
size_t read(char *dst, size_t len, seek_off_t seek_offset) override
|
||||||
{
|
{
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
UINT result;
|
UINT result;
|
||||||
|
|
||||||
if (seek_offset == (seek_off_t)(~0))
|
if (seek_offset == (seek_off_t)(~0)) {
|
||||||
seek_offset = _ffat_fil.fsize;
|
FILINFO file_info;
|
||||||
|
f_stat(name(), &file_info);
|
||||||
|
|
||||||
FRESULT res = f_lseek(&_ffat_fil, seek_offset);
|
seek_offset = file_info.fsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
FRESULT res = f_lseek(&_fatfs_fil, seek_offset);
|
||||||
|
|
||||||
switch(res) {
|
switch(res) {
|
||||||
case FR_OK:
|
case FR_OK:
|
||||||
@ -95,12 +99,12 @@ class Ffat_fs::File : public Node
|
|||||||
Genode::error("f_lseek() failed with error code FR_NOT_READY");
|
Genode::error("f_lseek() failed with error code FR_NOT_READY");
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
Genode::error("f_lseek() returned an unexpected error code");
|
Genode::error("f_lseek() returned an unexpected error code");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = f_read(&_ffat_fil, dst, len, &result);
|
res = f_read(&_fatfs_fil, dst, len, &result);
|
||||||
|
|
||||||
switch(res) {
|
switch(res) {
|
||||||
case FR_OK:
|
case FR_OK:
|
||||||
@ -121,7 +125,7 @@ class Ffat_fs::File : public Node
|
|||||||
Genode::error("f_read() failed with error code FR_NOT_READY");
|
Genode::error("f_read() failed with error code FR_NOT_READY");
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
Genode::error("f_read() returned an unexpected error code");
|
Genode::error("f_read() returned an unexpected error code");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -129,14 +133,18 @@ class Ffat_fs::File : public Node
|
|||||||
|
|
||||||
size_t write(char const *src, size_t len, seek_off_t seek_offset) override
|
size_t write(char const *src, size_t len, seek_off_t seek_offset) override
|
||||||
{
|
{
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
UINT result;
|
UINT result;
|
||||||
|
|
||||||
if (seek_offset == (seek_off_t)(~0))
|
if (seek_offset == (seek_off_t)(~0)) {
|
||||||
seek_offset = _ffat_fil.fsize;
|
FILINFO file_info;
|
||||||
|
f_stat(name(), &file_info);
|
||||||
|
|
||||||
FRESULT res = f_lseek(&_ffat_fil, seek_offset);
|
seek_offset = file_info.fsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
FRESULT res = f_lseek(&_fatfs_fil, seek_offset);
|
||||||
|
|
||||||
switch(res) {
|
switch(res) {
|
||||||
case FR_OK:
|
case FR_OK:
|
||||||
@ -154,12 +162,12 @@ class Ffat_fs::File : public Node
|
|||||||
Genode::error("f_lseek() failed with error code FR_NOT_READY");
|
Genode::error("f_lseek() failed with error code FR_NOT_READY");
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
Genode::error("f_lseek() returned an unexpected error code");
|
Genode::error("f_lseek() returned an unexpected error code");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = f_write(&_ffat_fil, src, len, &result);
|
res = f_write(&_fatfs_fil, src, len, &result);
|
||||||
|
|
||||||
switch(res) {
|
switch(res) {
|
||||||
case FR_OK:
|
case FR_OK:
|
||||||
@ -180,7 +188,7 @@ class Ffat_fs::File : public Node
|
|||||||
Genode::error("f_write() failed with error code FR_NOT_READY");
|
Genode::error("f_write() failed with error code FR_NOT_READY");
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
Genode::error("f_write() returned an unexpected error code");
|
Genode::error("f_write() returned an unexpected error code");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -188,7 +196,7 @@ class Ffat_fs::File : public Node
|
|||||||
|
|
||||||
void truncate(file_size_t size) override
|
void truncate(file_size_t size) override
|
||||||
{
|
{
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This macro is defined in later versions of the FatFs lib, but not in the
|
* This macro is defined in later versions of the FatFs lib, but not in the
|
||||||
@ -198,12 +206,12 @@ class Ffat_fs::File : public Node
|
|||||||
|
|
||||||
/* 'f_truncate()' truncates to the current seek pointer */
|
/* 'f_truncate()' truncates to the current seek pointer */
|
||||||
|
|
||||||
FRESULT res = f_lseek(&_ffat_fil, size);
|
FRESULT res = f_lseek(&_fatfs_fil, size);
|
||||||
|
|
||||||
switch(res) {
|
switch(res) {
|
||||||
case FR_OK:
|
case FR_OK:
|
||||||
/* according to the FatFs documentation this can happen */
|
/* according to the FatFs documentation this can happen */
|
||||||
if (f_tell(&_ffat_fil) != size) {
|
if (f_tell(&_fatfs_fil) != size) {
|
||||||
error("f_lseek() could not seek to offset ", size);
|
error("f_lseek() could not seek to offset ", size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -221,12 +229,12 @@ class Ffat_fs::File : public Node
|
|||||||
error("f_lseek() failed with error code FR_INVALID_OBJECT");
|
error("f_lseek() failed with error code FR_INVALID_OBJECT");
|
||||||
throw Invalid_handle();
|
throw Invalid_handle();
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
error("f_lseek() returned an unexpected error code");
|
error("f_lseek() returned an unexpected error code");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = f_truncate(&_ffat_fil);
|
res = f_truncate(&_fatfs_fil);
|
||||||
|
|
||||||
switch(res) {
|
switch(res) {
|
||||||
case FR_OK:
|
case FR_OK:
|
||||||
@ -247,7 +255,7 @@ class Ffat_fs::File : public Node
|
|||||||
error("f_truncate() failed with error code FR_TIMEOUT");
|
error("f_truncate() failed with error code FR_TIMEOUT");
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
error("f_truncate() returned an unexpected error code");
|
error("f_truncate() returned an unexpected error code");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* \brief FFAT file system
|
* \brief FATFS file system
|
||||||
* \author Christian Prochaska
|
* \author Christian Prochaska
|
||||||
* \date 2012-07-03
|
* \date 2012-07-03
|
||||||
*/
|
*/
|
||||||
@ -28,11 +28,11 @@
|
|||||||
#include <util.h>
|
#include <util.h>
|
||||||
|
|
||||||
/* Genode block backend */
|
/* Genode block backend */
|
||||||
#include <ffat/block.h>
|
#include <fatfs/block.h>
|
||||||
|
|
||||||
/* ffat includes */
|
/* fatfs includes */
|
||||||
namespace Ffat { extern "C" {
|
namespace Fatfs { extern "C" {
|
||||||
#include <ffat/ff.h>
|
#include <fatfs/ff.h>
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ namespace Ffat { extern "C" {
|
|||||||
** File-system service **
|
** File-system service **
|
||||||
*************************/
|
*************************/
|
||||||
|
|
||||||
namespace Ffat_fs {
|
namespace Fatfs_fs {
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
using File_system::Exception;
|
using File_system::Exception;
|
||||||
@ -52,7 +52,7 @@ namespace Ffat_fs {
|
|||||||
struct Main;
|
struct Main;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Ffat_fs::Session_component : public Session_rpc_object
|
class Fatfs_fs::Session_component : public Session_rpc_object
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -222,23 +222,23 @@ class Ffat_fs::Session_component : public Session_rpc_object
|
|||||||
|
|
||||||
auto file_fn = [&] (Open_node &open_node) {
|
auto file_fn = [&] (Open_node &open_node) {
|
||||||
|
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
FIL ffat_fil;
|
FIL fatfs_fil;
|
||||||
BYTE ffat_flags = 0;
|
BYTE fatfs_flags = 0;
|
||||||
|
|
||||||
if (!_writable)
|
if (!_writable)
|
||||||
if (create || (mode != STAT_ONLY && mode != READ_ONLY))
|
if (create || (mode != STAT_ONLY && mode != READ_ONLY))
|
||||||
throw Permission_denied();
|
throw Permission_denied();
|
||||||
|
|
||||||
if (create)
|
if (create)
|
||||||
ffat_flags |= FA_CREATE_NEW;
|
fatfs_flags |= FA_CREATE_NEW;
|
||||||
|
|
||||||
if ((mode == READ_ONLY) || (mode == READ_WRITE))
|
if ((mode == READ_ONLY) || (mode == READ_WRITE))
|
||||||
ffat_flags |= FA_READ;
|
fatfs_flags |= FA_READ;
|
||||||
|
|
||||||
if ((mode == WRITE_ONLY) || (mode == READ_WRITE))
|
if ((mode == WRITE_ONLY) || (mode == READ_WRITE))
|
||||||
ffat_flags |= FA_WRITE;
|
fatfs_flags |= FA_WRITE;
|
||||||
|
|
||||||
Absolute_path absolute_path(_root.name());
|
Absolute_path absolute_path(_root.name());
|
||||||
|
|
||||||
@ -250,12 +250,12 @@ class Ffat_fs::Session_component : public Session_rpc_object
|
|||||||
throw Invalid_name();
|
throw Invalid_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
FRESULT res = f_open(&ffat_fil, absolute_path.base(), ffat_flags);
|
FRESULT res = f_open(&fatfs_fil, absolute_path.base(), fatfs_flags);
|
||||||
|
|
||||||
switch(res) {
|
switch(res) {
|
||||||
case FR_OK: {
|
case FR_OK: {
|
||||||
File *file_node = new (&_heap) File(absolute_path.base());
|
File *file_node = new (&_heap) File(absolute_path.base());
|
||||||
file_node->ffat_fil(ffat_fil);
|
file_node->fatfs_fil(fatfs_fil);
|
||||||
|
|
||||||
Open_node *open_file =
|
Open_node *open_file =
|
||||||
new (_heap) Open_node(*file_node, _open_node_registry);
|
new (_heap) Open_node(*file_node, _open_node_registry);
|
||||||
@ -289,7 +289,7 @@ class Ffat_fs::Session_component : public Session_rpc_object
|
|||||||
error("f_open() failed with error code FR_NO_FILESYSTEM");
|
error("f_open() failed with error code FR_NO_FILESYSTEM");
|
||||||
throw Lookup_failed();
|
throw Lookup_failed();
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
error("f_open() returned an unexpected error code");
|
error("f_open() returned an unexpected error code");
|
||||||
throw Lookup_failed();
|
throw Lookup_failed();
|
||||||
}
|
}
|
||||||
@ -323,7 +323,7 @@ class Ffat_fs::Session_component : public Session_rpc_object
|
|||||||
*/
|
*/
|
||||||
Directory *dir_node = new (&_heap) Directory(path.string());
|
Directory *dir_node = new (&_heap) Directory(path.string());
|
||||||
|
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
Absolute_path absolute_path(_root.name());
|
Absolute_path absolute_path(_root.name());
|
||||||
|
|
||||||
@ -372,7 +372,7 @@ class Ffat_fs::Session_component : public Session_rpc_object
|
|||||||
error("f_mkdir() failed with error code FR_NO_FILESYSTEM");
|
error("f_mkdir() failed with error code FR_NO_FILESYSTEM");
|
||||||
throw Lookup_failed();
|
throw Lookup_failed();
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
error("f_mkdir() returned an unexpected error code");
|
error("f_mkdir() returned an unexpected error code");
|
||||||
throw Lookup_failed();
|
throw Lookup_failed();
|
||||||
}
|
}
|
||||||
@ -382,13 +382,13 @@ class Ffat_fs::Session_component : public Session_rpc_object
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ffat::DIR ffat_dir;
|
Fatfs::DIR fatfs_dir;
|
||||||
FRESULT f_opendir_res = f_opendir(&ffat_dir, absolute_path.base());
|
FRESULT f_opendir_res = f_opendir(&fatfs_dir, absolute_path.base());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
switch(f_opendir_res) {
|
switch(f_opendir_res) {
|
||||||
case FR_OK: {
|
case FR_OK: {
|
||||||
dir_node->ffat_dir(ffat_dir);
|
dir_node->fatfs_dir(fatfs_dir);
|
||||||
|
|
||||||
Open_node *open_dir =
|
Open_node *open_dir =
|
||||||
new (_heap) Open_node(*dir_node, _open_node_registry);
|
new (_heap) Open_node(*dir_node, _open_node_registry);
|
||||||
@ -417,7 +417,7 @@ class Ffat_fs::Session_component : public Session_rpc_object
|
|||||||
error("f_opendir() failed with error code FR_NO_FILESYSTEM");
|
error("f_opendir() failed with error code FR_NO_FILESYSTEM");
|
||||||
throw Lookup_failed();
|
throw Lookup_failed();
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
error("f_opendir() returned an unexpected error code");
|
error("f_opendir() returned an unexpected error code");
|
||||||
throw Lookup_failed();
|
throw Lookup_failed();
|
||||||
}
|
}
|
||||||
@ -446,12 +446,9 @@ class Ffat_fs::Session_component : public Session_rpc_object
|
|||||||
/* f_stat() does not work for "/" */
|
/* f_stat() does not work for "/" */
|
||||||
if (!is_root(node->name())) {
|
if (!is_root(node->name())) {
|
||||||
|
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
FILINFO file_info;
|
FILINFO file_info;
|
||||||
/* the long file name is not used in this function */
|
|
||||||
file_info.lfname = 0;
|
|
||||||
file_info.lfsize = 0;
|
|
||||||
|
|
||||||
FRESULT res = f_stat(node->name(), &file_info);
|
FRESULT res = f_stat(node->name(), &file_info);
|
||||||
|
|
||||||
@ -481,7 +478,7 @@ class Ffat_fs::Session_component : public Session_rpc_object
|
|||||||
error("f_stat() failed with error code FR_NO_FILESYSTEM");
|
error("f_stat() failed with error code FR_NO_FILESYSTEM");
|
||||||
throw Lookup_failed();
|
throw Lookup_failed();
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
error("f_stat() returned an unexpected error code");
|
error("f_stat() returned an unexpected error code");
|
||||||
throw Lookup_failed();
|
throw Lookup_failed();
|
||||||
}
|
}
|
||||||
@ -523,17 +520,14 @@ class Ffat_fs::Session_component : public Session_rpc_object
|
|||||||
|
|
||||||
Node &node = open_node.node();
|
Node &node = open_node.node();
|
||||||
|
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
/* f_stat() does not work for the '/' directory */
|
/* f_stat() does not work for the '/' directory */
|
||||||
if (!is_root(node.name())) {
|
if (!is_root(node.name())) {
|
||||||
|
|
||||||
FILINFO ffat_file_info;
|
FILINFO fatfs_file_info;
|
||||||
/* the long file name is not used in this function */
|
|
||||||
ffat_file_info.lfname = 0;
|
|
||||||
ffat_file_info.lfsize = 0;
|
|
||||||
|
|
||||||
FRESULT res = f_stat(node.name(), &ffat_file_info);
|
FRESULT res = f_stat(node.name(), &fatfs_file_info);
|
||||||
|
|
||||||
switch(res) {
|
switch(res) {
|
||||||
case FR_OK:
|
case FR_OK:
|
||||||
@ -566,16 +560,16 @@ class Ffat_fs::Session_component : public Session_rpc_object
|
|||||||
error("f_stat() failed with error code FR_NO_FILESYSTEM");
|
error("f_stat() failed with error code FR_NO_FILESYSTEM");
|
||||||
return status;
|
return status;
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
error("f_stat() returned an unexpected error code");
|
error("f_stat() returned an unexpected error code");
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ffat_file_info.fattrib & AM_DIR) == AM_DIR) {
|
if ((fatfs_file_info.fattrib & AM_DIR) == AM_DIR) {
|
||||||
status.mode = File_system::Status::MODE_DIRECTORY; }
|
status.mode = File_system::Status::MODE_DIRECTORY; }
|
||||||
else {
|
else {
|
||||||
status.mode = File_system::Status::MODE_FILE;
|
status.mode = File_system::Status::MODE_FILE;
|
||||||
status.size = ffat_file_info.fsize;
|
status.size = fatfs_file_info.fsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -586,24 +580,21 @@ class Ffat_fs::Session_component : public Session_rpc_object
|
|||||||
|
|
||||||
/* determine the number of directory entries */
|
/* determine the number of directory entries */
|
||||||
|
|
||||||
Ffat::DIR ffat_dir;
|
Fatfs::DIR fatfs_dir;
|
||||||
FRESULT f_opendir_res = f_opendir(&ffat_dir, node.name());
|
FRESULT f_opendir_res = f_opendir(&fatfs_dir, node.name());
|
||||||
|
|
||||||
if (f_opendir_res != FR_OK)
|
if (f_opendir_res != FR_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
FILINFO ffat_file_info;
|
FILINFO fatfs_file_info;
|
||||||
/* the long file name is not used in this function */
|
|
||||||
ffat_file_info.lfname = 0;
|
|
||||||
ffat_file_info.lfsize = 0;
|
|
||||||
|
|
||||||
int num_direntries = -1;
|
int num_direntries = -1;
|
||||||
do {
|
do {
|
||||||
++num_direntries;
|
++num_direntries;
|
||||||
FRESULT res = f_readdir(&ffat_dir, &ffat_file_info);
|
FRESULT res = f_readdir(&fatfs_dir, &fatfs_file_info);
|
||||||
if (res != FR_OK)
|
if (res != FR_OK)
|
||||||
return status;
|
return status;
|
||||||
} while (ffat_file_info.fname[0] != 0);
|
} while (fatfs_file_info.fname[0] != 0);
|
||||||
|
|
||||||
status.size = num_direntries * sizeof(Directory_entry);
|
status.size = num_direntries * sizeof(Directory_entry);
|
||||||
}
|
}
|
||||||
@ -630,7 +621,7 @@ class Ffat_fs::Session_component : public Session_rpc_object
|
|||||||
|
|
||||||
auto unlink_fn = [&] (Open_node &open_node) {
|
auto unlink_fn = [&] (Open_node &open_node) {
|
||||||
|
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
Absolute_path absolute_path(_root.name());
|
Absolute_path absolute_path(_root.name());
|
||||||
|
|
||||||
@ -672,7 +663,7 @@ class Ffat_fs::Session_component : public Session_rpc_object
|
|||||||
error("f_unlink() failed with error code FR_NO_FILESYSTEM");
|
error("f_unlink() failed with error code FR_NO_FILESYSTEM");
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
error("f_unlink() returned an unexpected error code");
|
error("f_unlink() returned an unexpected error code");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -731,10 +722,16 @@ class Ffat_fs::Session_component : public Session_rpc_object
|
|||||||
throw Invalid_name();
|
throw Invalid_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
FRESULT res = f_rename(absolute_from_path.base(), absolute_to_path.base());
|
FRESULT res = f_rename(absolute_from_path.base(), absolute_to_path.base());
|
||||||
|
|
||||||
|
/* if newpath already exists - try to unlink it once */
|
||||||
|
if (res == FR_EXIST) {
|
||||||
|
f_unlink(absolute_to_path.base());
|
||||||
|
res = f_rename(absolute_from_path.base(), absolute_to_path.base());
|
||||||
|
}
|
||||||
|
|
||||||
switch(res) {
|
switch(res) {
|
||||||
case FR_OK:
|
case FR_OK:
|
||||||
break;
|
break;
|
||||||
@ -766,7 +763,7 @@ class Ffat_fs::Session_component : public Session_rpc_object
|
|||||||
error("f_rename() failed with error code FR_NO_FILESYSTEM");
|
error("f_rename() failed with error code FR_NO_FILESYSTEM");
|
||||||
throw Lookup_failed();
|
throw Lookup_failed();
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
error("f_rename() returned an unexpected error code");
|
error("f_rename() returned an unexpected error code");
|
||||||
throw Lookup_failed();
|
throw Lookup_failed();
|
||||||
}
|
}
|
||||||
@ -793,7 +790,7 @@ class Ffat_fs::Session_component : public Session_rpc_object
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Ffat_fs::Root : public Root_component<Session_component>
|
class Fatfs_fs::Root : public Root_component<Session_component>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -841,7 +838,7 @@ class Ffat_fs::Root : public Root_component<Session_component>
|
|||||||
|
|
||||||
/* Check if the root path exists */
|
/* Check if the root path exists */
|
||||||
|
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
FRESULT res = f_chdir(root);
|
FRESULT res = f_chdir(root);
|
||||||
|
|
||||||
@ -869,7 +866,7 @@ class Ffat_fs::Root : public Root_component<Session_component>
|
|||||||
error("f_chdir() failed with error code FR_NO_FILESYSTEM");
|
error("f_chdir() failed with error code FR_NO_FILESYSTEM");
|
||||||
throw Service_denied();
|
throw Service_denied();
|
||||||
default:
|
default:
|
||||||
/* not supposed to occur according to the libffat documentation */
|
/* not supposed to occur according to the fatfs documentation */
|
||||||
error("f_chdir() returned an unexpected error code");
|
error("f_chdir() returned an unexpected error code");
|
||||||
throw Service_denied();
|
throw Service_denied();
|
||||||
}
|
}
|
||||||
@ -940,7 +937,7 @@ class Ffat_fs::Root : public Root_component<Session_component>
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Ffat_fs::Main
|
struct Fatfs_fs::Main
|
||||||
{
|
{
|
||||||
Genode::Env &_env;
|
Genode::Env &_env;
|
||||||
Genode::Heap _heap { _env.ram(), _env.rm() };
|
Genode::Heap _heap { _env.ram(), _env.rm() };
|
||||||
@ -949,24 +946,24 @@ struct Ffat_fs::Main
|
|||||||
Directory _root_dir { "/" };
|
Directory _root_dir { "/" };
|
||||||
Root _root { _env, _sliced_heap, _heap, _root_dir };
|
Root _root { _env, _sliced_heap, _heap, _root_dir };
|
||||||
|
|
||||||
Ffat::FATFS _fatfs;
|
Fatfs::FATFS _fatfs;
|
||||||
|
|
||||||
Main(Genode::Env &env) : _env(env)
|
Main(Genode::Env &env) : _env(env)
|
||||||
{
|
{
|
||||||
Ffat::block_init(_env, _heap);
|
Fatfs::block_init(_env, _heap);
|
||||||
|
|
||||||
using namespace File_system;
|
using namespace File_system;
|
||||||
using namespace Ffat;
|
using namespace Fatfs;
|
||||||
|
|
||||||
/* mount the file system */
|
/* mount the file system */
|
||||||
if (f_mount(0, &_fatfs) != Ffat::FR_OK) {
|
if (f_mount(&_fatfs, "", 0) != Fatfs::FR_OK) {
|
||||||
error("mount failed");
|
error("mount failed");
|
||||||
|
|
||||||
struct Mount_failed : Genode::Exception { };
|
struct Mount_failed : Genode::Exception { };
|
||||||
throw Mount_failed();
|
throw Mount_failed();
|
||||||
}
|
}
|
||||||
|
|
||||||
Genode::log("--- Starting Ffat_fs ---");
|
Genode::log("--- Starting Fatfs_fs ---");
|
||||||
|
|
||||||
_env.parent().announce(_env.ep().manage(_root));
|
_env.parent().announce(_env.ep().manage(_root));
|
||||||
}
|
}
|
||||||
@ -978,5 +975,5 @@ void Component::construct(Genode::Env &env)
|
|||||||
/* XXX execute constructors of global statics */
|
/* XXX execute constructors of global statics */
|
||||||
env.exec_static_constructors();
|
env.exec_static_constructors();
|
||||||
|
|
||||||
static Ffat_fs::Main main(env);
|
static Fatfs_fs::Main main(env);
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* \brief FFAT file-system node
|
* \brief FATFS file-system node
|
||||||
* \author Christian Prochaska
|
* \author Christian Prochaska
|
||||||
* \date 2012-07-04
|
* \date 2012-07-04
|
||||||
*/
|
*/
|
||||||
@ -19,21 +19,21 @@
|
|||||||
#include <base/log.h>
|
#include <base/log.h>
|
||||||
#include <os/path.h>
|
#include <os/path.h>
|
||||||
|
|
||||||
/* ffat includes */
|
/* fatfs includes */
|
||||||
namespace Ffat { extern "C" {
|
namespace Fatfs { extern "C" {
|
||||||
#include <ffat/ff.h>
|
#include <fatfs/ff.h>
|
||||||
} }
|
} }
|
||||||
|
|
||||||
namespace Ffat_fs {
|
namespace Fatfs_fs {
|
||||||
using namespace File_system;
|
using namespace File_system;
|
||||||
|
|
||||||
typedef Genode::Path<_MAX_LFN + 1> Absolute_path;
|
typedef Genode::Path<FF_MAX_LFN + 1> Absolute_path;
|
||||||
|
|
||||||
class Node;
|
class Node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Ffat_fs::Node : public Node_base
|
class Fatfs_fs::Node : public Node_base
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
4
repos/libports/src/server/fatfs_fs/target.mk
Normal file
4
repos/libports/src/server/fatfs_fs/target.mk
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
TARGET = fatfs_fs
|
||||||
|
SRC_CC = main.cc
|
||||||
|
LIBS = base fatfs_block
|
||||||
|
INC_DIR += $(PRG_DIR)
|
@ -1,4 +0,0 @@
|
|||||||
TARGET = ffat_fs
|
|
||||||
SRC_CC = main.cc
|
|
||||||
LIBS = base ffat_block
|
|
||||||
INC_DIR += $(PRG_DIR)
|
|
17
repos/libports/src/test/fatfs_blkio/component.cc
Normal file
17
repos/libports/src/test/fatfs_blkio/component.cc
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#include <fatfs/block.h>
|
||||||
|
#include <base/heap.h>
|
||||||
|
#include <libc/component.h>
|
||||||
|
|
||||||
|
extern int main (int argc, char* argv[]);
|
||||||
|
|
||||||
|
void Libc::Component::construct(Libc::Env &env)
|
||||||
|
{
|
||||||
|
env.exec_static_constructors();
|
||||||
|
|
||||||
|
Genode::Heap heap(env.ram(), env.rm());
|
||||||
|
Fatfs::block_init(env, heap);
|
||||||
|
|
||||||
|
int r = 0;
|
||||||
|
Libc::with_libc([&r] () { r = main(0, 0); });
|
||||||
|
env.parent().exit(r);
|
||||||
|
}
|
13
repos/libports/src/test/fatfs_blkio/target.mk
Normal file
13
repos/libports/src/test/fatfs_blkio/target.mk
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
TARGET = test-fatfs_blkio
|
||||||
|
LIBS = fatfs_block libc
|
||||||
|
SRC_C = app4.c
|
||||||
|
SRC_CC = component.cc
|
||||||
|
|
||||||
|
CC_DEF += -D_MAX_SS=FF_MAX_SS
|
||||||
|
CC_WARN += -Wno-pointer-to-int-cast
|
||||||
|
|
||||||
|
FATFS_PORT_DIR = $(call select_from_ports,fatfs)
|
||||||
|
|
||||||
|
INC_DIR += $(FATFS_PORT_DIR)/include/fatfs
|
||||||
|
|
||||||
|
vpath %.c $(FATFS_PORT_DIR)/src/lib/fatfs/documents/res
|
@ -1,5 +1,5 @@
|
|||||||
TARGET = test-libc_ffat
|
TARGET = test-libc_fatfs
|
||||||
LIBS = libc libc_ffat
|
LIBS = libc libc_fatfs
|
||||||
SRC_CC = main.cc
|
SRC_CC = main.cc
|
||||||
|
|
||||||
# we re-use the libc_vfs test
|
# we re-use the libc_vfs test
|
@ -162,10 +162,12 @@ static void test(Genode::Xml_node node)
|
|||||||
/* move file (target does not exist) */
|
/* move file (target does not exist) */
|
||||||
CALL_AND_CHECK(fd, open(file_name5, O_CREAT | O_WRONLY), fd >= 0, "file_name=%s", file_name5);
|
CALL_AND_CHECK(fd, open(file_name5, O_CREAT | O_WRONLY), fd >= 0, "file_name=%s", file_name5);
|
||||||
CALL_AND_CHECK(ret, rename(file_name5, "x"), ret == 0, "file_name=%s", file_name5);
|
CALL_AND_CHECK(ret, rename(file_name5, "x"), ret == 0, "file_name=%s", file_name5);
|
||||||
|
CALL_AND_CHECK(ret, close(fd), ret == 0, "");
|
||||||
|
|
||||||
/* move file (target already exists) */
|
/* move file (target already exists) */
|
||||||
CALL_AND_CHECK(fd, open(file_name5, O_CREAT | O_WRONLY), fd >= 0, "file_name=%s", file_name5);
|
CALL_AND_CHECK(fd, open(file_name5, O_CREAT | O_WRONLY), fd >= 0, "file_name=%s", file_name5);
|
||||||
CALL_AND_CHECK(ret, rename(file_name5, "x"), ret == 0, "file_name=%s", file_name5);
|
CALL_AND_CHECK(ret, rename(file_name5, "x"), ret == 0, "file_name=%s", file_name5);
|
||||||
|
CALL_AND_CHECK(ret, close(fd), ret == 0, "");
|
||||||
|
|
||||||
/* test 'pread()' and 'pwrite()' */
|
/* test 'pread()' and 'pwrite()' */
|
||||||
CALL_AND_CHECK(fd, open(file_name2, O_CREAT | O_WRONLY), fd >= 0, "file_name=%s", file_name2);
|
CALL_AND_CHECK(fd, open(file_name2, O_CREAT | O_WRONLY), fd >= 0, "file_name=%s", file_name2);
|
||||||
|
@ -7,7 +7,7 @@ rom_blk
|
|||||||
tar_rom
|
tar_rom
|
||||||
noux
|
noux
|
||||||
noux_net_netcat
|
noux_net_netcat
|
||||||
libc_ffat
|
libc_fatfs
|
||||||
libc_getenv
|
libc_getenv
|
||||||
libc_pipe
|
libc_pipe
|
||||||
libc_vfs
|
libc_vfs
|
||||||
|
Loading…
Reference in New Issue
Block a user