Use fuse3, rewrite no-fuse version in C.

This commit is contained in:
Ivan Baravy 2017-10-18 23:19:53 +03:00
parent 54fe4859ee
commit c162146abb
9 changed files with 313 additions and 506 deletions

6
.gitignore vendored
View File

@ -1,3 +1,5 @@
*.swp
.vim
*.o *.o
xfskos kofu
xfskosfuse kofuse

202
kocdecl.asm Normal file
View File

@ -0,0 +1,202 @@
format ELF
__DEBUG__ = 1
__DEBUG_LEVEL__ = 2
include 'proc32.inc'
include 'struct.inc'
include 'macros.inc'
include 'const.inc'
include 'system.inc'
include 'debug-fdo.inc'
include 'disk.inc'
include 'fs_common.inc'
ERROR_SUCCESS = 0
ERROR_DISK_BASE = 1
ERROR_UNSUPPORTED_FS = 2
ERROR_UNKNOWN_FS = 3
ERROR_PARTITION = 4
ERROR_FILE_NOT_FOUND = 5
ERROR_END_OF_FILE = 6
ERROR_MEMORY_POINTER = 7
ERROR_DISK_FULL = 8
ERROR_FS_FAIL = 9
ERROR_ACCESS_DENIED = 10
ERROR_DEVICE = 11
ERROR_OUT_OF_MEMORY = 12
purge section,mov,add,sub
section '.text' executable align 16
public kos_fuse_init
kos_fuse_init:
push ebx esi edi ebp
mov eax, [esp + 0x14]
mov [fd], eax
mov eax, 0
mov ebx, mbr_buffer
mov ebp, partition
call fs_read32_sys
mov esi, disk
mov [esi + DISK.MediaInfo.SectorSize], 512
mov ebp, partition
mov [ebp + PARTITION.Disk], esi
mov ebx, mbr_buffer
call xfs_create_partition
test eax, eax
jnz @f
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, msg_not_xfs_partition
mov edx, msg_not_xfs_partition.size
int 0x80
@@:
mov [fs_struct], eax
pop ebp edi esi ebx
ret
;char *hello_readdir(const char *path, off_t offset)
public kos_fuse_readdir
kos_fuse_readdir:
push ebx esi edi ebp
mov edx, sf70_params
mov dword[edx + 0x00], 1
mov eax, [esp + 0x18] ; offset
mov [edx + 0x04], eax
mov dword[edx + 0x08], 1
mov dword[edx + 0x0c], 100
mov dword[edx + 0x10], sf70_buffer
mov eax, [esp + 0x14] ; path
inc eax ; skip '/'
mov [edx + 0x14], eax
mov ebp, [fs_struct]
mov ebx, sf70_params
mov esi, eax
push 0
call xfs_ReadFolder
pop eax
pop ebp edi esi ebx
mov eax, sf70_buffer
ret
; in: eax = sector, ebx = buffer, ebp = pointer to PARTITION structure
fs_read32_sys:
pushad
imul ecx, eax, 512
add ecx, 2048*512
mov eax, SYS_LSEEK
mov ebx, [fd]
mov edx, SEEK_SET
int 0x80
;DEBUGF 1, "lseek: %x\n", eax
popad
pushad
mov eax, SYS_READ
mov ecx, ebx
mov ebx, [fd]
mov edx, 512
int 0x80
;DEBUGF 1, "read: %d\n", eax
popad
xor eax, eax
ret
fs_read32_app:
ret
fs_read64_sys:
pushad
imul ecx, eax, 512
add ecx, 2048*512
mov eax, SYS_LSEEK
mov ebx, [fd]
mov edx, SEEK_SET
int 0x80
;DEBUGF 1, "lseek: %x\n", eax
popad
pushad
mov eax, SYS_READ
imul edx, ecx, 512
mov ecx, ebx
mov ebx, [fd]
int 0x80
;DEBUGF 1, "read: %d\n", eax
popad
xor eax, eax
ret
fs_read64_app:
ret
malloc:
push [alloc_pos]
add [alloc_pos], eax
pop eax
ret
free:
ret
kernel_free:
ret
mutex_init:
mutex_lock:
mutex_unlock:
ret
put_board:
pushad
mov eax, SYS_WRITE
mov ebx, STDOUT
push ecx
mov ecx, esp
mov edx, 1
int 0x80
pop ecx
popad
ret
include 'xfs.asm'
section '.data' writeable align 16
include_debug_strings
partition_offset dd 2048*512
alloc_pos dd alloc_base
sf70_params rd 6
msg_not_xfs_partition db 'not xfs partition',0x0a ; TODO: return codes, report in C
msg_not_xfs_partition.size = $ - msg_not_xfs_partition
IncludeIGlobals
section '.bss' writeable align 16
mbr_buffer rb 4096*3
fd rd 1
partition PARTITION
disk DISK
alloc_base rb 1024*1024
fs_struct rd 1
sf70_buffer rb 1024*1024

7
kocdecl.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef KOS_H_INCLUDED
#define KOS_H_INCLUDED
void kos_fuse_init(int fd);
char *kos_fuse_readdir(const char *path, off_t offset);
#endif

37
kofu.c Normal file
View File

@ -0,0 +1,37 @@
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "kocdecl.h"
void prompt() {
printf("> ");
fflush(stdout);
}
int main(int argc, char **argv) {
char cmd_buf[4096];
int fd = open(argv[1], O_RDONLY);
kos_fuse_init(fd);
//msg_few_args db 'usage: xfskos image [offset]',0x0a
//msg_file_not_found db 'file not found: '
//msg_unknown_command db 'unknown command',0x0a
//msg_not_xfs_partition db 'not xfs partition',0x0a
while(true) {
prompt();
scanf("%s", cmd_buf);
char *bdfe = kos_fuse_readdir("", 0);
uint32_t file_cnt = *(uint32_t*)(bdfe + 4);
bdfe += 0x20;
for (; file_cnt > 0; file_cnt--) {
printf("%s\n", bdfe + 0x28);
bdfe += 304;
}
}
return 0;
}

View File

@ -1,45 +1,36 @@
/* #define FUSE_USE_VERSION 31
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
gcc -Wall hello.c `pkg-config fuse --cflags --libs` -o hello
*/
#define FUSE_USE_VERSION 26
#include <fuse.h> #include <fuse.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <stdlib.h> #include <assert.h>
#include <unistd.h> #include "kocdecl.h"
char *kos_fuse_readdir(const char *path, off_t offset); static void *hello_init(struct fuse_conn_info *conn,
void kos_fuse_init(int fd); struct fuse_config *cfg)
static const char *hello_str = "Hello World!\n";
static const char *hello_path = "/hello";
static int hello_getattr(const char *path, struct stat *stbuf)
{ {
(void) conn;
cfg->kernel_cache = 1;
return NULL;
}
static int hello_getattr(const char *path, struct stat *stbuf,
struct fuse_file_info *fi)
{
(void) fi;
int res = 0; int res = 0;
memset(stbuf, 0, sizeof(struct stat)); memset(stbuf, 0, sizeof(struct stat));
if (strcmp(path, "/") == 0) { if (strcmp(path, "/") == 0) {
stbuf->st_mode = S_IFDIR | 0755; stbuf->st_mode = S_IFDIR | 0755;
stbuf->st_nlink = 2; stbuf->st_nlink = 2;
} else if (strcmp(path, hello_path) == 0) { } else if (strcmp(path+1, "blah") == 0) {
stbuf->st_mode = S_IFREG | 0444; stbuf->st_mode = S_IFREG | 0444;
stbuf->st_nlink = 1; stbuf->st_nlink = 1;
stbuf->st_size = strlen(hello_str); stbuf->st_size = strlen("blah");
} else } else
res = -ENOENT; res = -ENOENT;
@ -47,10 +38,12 @@ static int hello_getattr(const char *path, struct stat *stbuf)
} }
static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler, static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi) off_t offset, struct fuse_file_info *fi,
enum fuse_readdir_flags flags)
{ {
(void) offset; (void) offset;
(void) fi; (void) fi;
(void) flags;
char *bdfe = kos_fuse_readdir(path, offset); char *bdfe = kos_fuse_readdir(path, offset);
@ -63,7 +56,7 @@ static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
// close(f); // close(f);
bdfe += 0x20; bdfe += 0x20;
for(; i>0; i--) { for(; i>0; i--) {
filler(buf, bdfe + 0x28, NULL, 0); filler(buf, bdfe + 0x28, NULL, 0, 0);
bdfe += 304; bdfe += 304;
} }
@ -72,10 +65,10 @@ static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
static int hello_open(const char *path, struct fuse_file_info *fi) static int hello_open(const char *path, struct fuse_file_info *fi)
{ {
if (strcmp(path, hello_path) != 0) if (strcmp(path+1, "blah") != 0)
return -ENOENT; return -ENOENT;
if ((fi->flags & 3) != O_RDONLY) if ((fi->flags & O_ACCMODE) != O_RDONLY)
return -EACCES; return -EACCES;
return 0; return 0;
@ -86,14 +79,14 @@ static int hello_read(const char *path, char *buf, size_t size, off_t offset,
{ {
size_t len; size_t len;
(void) fi; (void) fi;
if(strcmp(path, hello_path) != 0) if(strcmp(path+1, "blah") != 0)
return -ENOENT; return -ENOENT;
len = strlen(hello_str); len = strlen("blah");
if (offset < len) { if (offset < len) {
if (offset + size > len) if (offset + size > len)
size = len - offset; size = len - offset;
memcpy(buf, hello_str + offset, size); memcpy(buf, "blah" + offset, size);
} else } else
size = 0; size = 0;
@ -101,6 +94,7 @@ static int hello_read(const char *path, char *buf, size_t size, off_t offset,
} }
static struct fuse_operations hello_oper = { static struct fuse_operations hello_oper = {
.init = hello_init,
.getattr = hello_getattr, .getattr = hello_getattr,
.readdir = hello_readdir, .readdir = hello_readdir,
.open = hello_open, .open = hello_open,

View File

@ -1,25 +1,26 @@
FASM=fasm FASM=fasm
CC=gcc -m32
CFLAGS=-Wall -g3 -O0 -D_FILE_OFFSET_BITS=64
all: xfskosfuse all: kofu kofuse
#xfskos: xfskos.o kofu: kofu.o kocdecl.o
# ld *.o -o $@ -m elf_i386 -nostdlib $(CC) $^ -o $@
# strip $@
xfskos.o: xfskos.asm xfs.inc xfs.asm kofuse: kofuse.o kocdecl.o
$(CC) $^ -o $@ `pkg-config fuse3 --libs`
kocdecl.o: kocdecl.asm xfs.inc xfs.asm
$(FASM) $< $@ $(FASM) $< $@
xfskosfuse: xfskosfuse.o xfskos.o kofu.o: kofu.c
gcc -m32 -Wall $^ -o $@ -D_FILE_OFFSET_BITS=64 -lfuse -g3 -O0 $(CC) $(CFLAGS) -c $<
xfskosfuse.o: xfskosfuse.c kofuse.o: kofuse.c
gcc -m32 -Wall -c $< -D_FILE_OFFSET_BITS=64 -g3 -O0 $(CC) $(CFLAGS) `pkg-config fuse3 --cflags` -c $<
.PHONY: all clean check .PHONY: all clean
clean: clean:
rm -f *.o xfskos rm -f *.o kofu kofuse
check: xfskos
echo ok

53
xfs.asm
View File

@ -14,7 +14,7 @@ $Revision: 6462 $
; [esi]+[[esp+4]] = name ; [esi]+[[esp+4]] = name
; out: ; out:
; eax, ebx = return values for sysfunc 70 ; eax, ebx = return values for sysfunc 70
;iglobal iglobal
align 4 align 4
xfs_user_functions: xfs_user_functions:
dd xfs_free dd xfs_free
@ -30,7 +30,7 @@ xfs_user_functions:
dd 0;xfs_Delete dd 0;xfs_Delete
dd 0;xfs_CreateFolder dd 0;xfs_CreateFolder
xfs_user_functions_end: xfs_user_functions_end:
;endg endg
include 'xfs.inc' include 'xfs.inc'
@ -263,8 +263,8 @@ endp
;--------------------------------------------------------------- ;---------------------------------------------------------------
; block number (AG relative) ; block number (AG relative)
; eax -- block_lo ; eax -- inode_lo
; edx -- block_hi ; edx -- inode_hi
; ebx -- buffer ; ebx -- buffer
;--------------------------------------------------------------- ;---------------------------------------------------------------
xfs_read_block: xfs_read_block:
@ -294,7 +294,7 @@ xfs_read_block:
add eax, ecx add eax, ecx
adc edx, esi adc edx, esi
DEBUGF 1,"read block: 0x%x%x\n",edx,eax ;DEBUGF 1,"read block: 0x%x%x\n",edx,eax
; there is no way to read file system block at once, therefore we ; there is no way to read file system block at once, therefore we
; 1. calculate the number of sectors first ; 1. calculate the number of sectors first
; 2. and then read them in series ; 2. and then read them in series
@ -384,7 +384,7 @@ xfs_read_dirblock:
; test eax, eax ; test eax, eax
;--------------------------------------------------------------- ;---------------------------------------------------------------
xfs_read_inode: xfs_read_inode:
DEBUGF 1,"reading inode: 0x%x%x\n",[esp+8],[esp+4] ;DEBUGF 1,"reading inode: 0x%x%x\n",[esp+8],[esp+4]
push ebx push ebx
mov eax, [esp + 8] ; inode_lo mov eax, [esp + 8] ; inode_lo
mov edx, [esp + 12] ; inode_hi mov edx, [esp + 12] ; inode_hi
@ -416,25 +416,8 @@ DEBUGF 1,"reading inode: 0x%x%x\n",[esp+8],[esp+4]
shl eax, cl shl eax, cl
add ebx, eax add ebx, eax
;DEBUGF 1,"dinode: %x\n", ebx
;DEBUGF 1," %x\n",[ebx+0x00]
;DEBUGF 1," %x\n",[ebx+0x04]
;DEBUGF 1," %x\n",[ebx+0x08]
;DEBUGF 1," %x\n",[ebx+0x0c]
;DEBUGF 1," %x\n",[ebx+0x10]
;DEBUGF 1," %x\n",[ebx+0x14]
;DEBUGF 1," %x\n",[ebx+0x18]
;DEBUGF 1," %x\n",[ebx+0x1c]
;DEBUGF 1," %x\n",[ebx+0x20]
;DEBUGF 1," %x\n",[ebx+0x24]
;DEBUGF 1," %x\n",[ebx+0x28]
;DEBUGF 1," %x\n",[ebx+0x2c]
;DEBUGF 1," %x\n",[ebx+0x30]
;DEBUGF 1," %x\n",[ebx+0x34]
;DEBUGF 1," %x\n",[ebx+0x38]
;DEBUGF 1," %x\n",[ebx+0x3c]
cmp word[ebx], XFS_DINODE_MAGIC ; test signature cmp word[ebx], XFS_DINODE_MAGIC ; test signature
jnz .error jne .error
.quit: .quit:
xor eax, eax xor eax, eax
mov edx, ebx mov edx, ebx
@ -1111,7 +1094,7 @@ xfs_get_inode_short:
; this function searches for the file in _current_ dir ; this function searches for the file in _current_ dir
; it is called recursively for all the subdirs /path/to/my/file ; it is called recursively for all the subdirs /path/to/my/file
DEBUGF 1, "xfs_get_inode_short: %s\n", [esp+4] ;DEBUGF 1,"xfs_get_inode_short: %s\n",[esp+4]
mov esi, [esp + 4] ; name mov esi, [esp + 4] ; name
movzx eax, word[esi] movzx eax, word[esi]
cmp eax, '.' ; current dir; it is already read, just return cmp eax, '.' ; current dir; it is already read, just return
@ -1135,7 +1118,7 @@ DEBUGF 1, "xfs_get_inode_short: %s\n", [esp+4]
mov [ebp + XFS.cur_inode_save], ebx mov [ebp + XFS.cur_inode_save], ebx
cmp byte[ebx + xfs_inode.di_core.di_format], XFS_DINODE_FMT_LOCAL cmp byte[ebx + xfs_inode.di_core.di_format], XFS_DINODE_FMT_LOCAL
jne .not_shortdir jne .not_shortdir
DEBUGF 1, "dir: shortdir\n" ;DEBUGF 1,"dir: shortdir\n"
jmp .shortdir jmp .shortdir
.not_shortdir: .not_shortdir:
cmp byte[ebx + xfs_inode.di_core.di_format], XFS_DINODE_FMT_EXTENTS cmp byte[ebx + xfs_inode.di_core.di_format], XFS_DINODE_FMT_EXTENTS
@ -1171,9 +1154,9 @@ DEBUGF 1,"NOT IMPLEMENTED: DIR FORMAT\n"
mov eax, [esi] mov eax, [esi]
and eax, 0x00ffffff and eax, 0x00ffffff
cmp eax, '..' cmp eax, '..'
jz .shortdir.parent2 je .shortdir.parent2
cmp eax, '../' cmp eax, '../'
jz .shortdir.parent3 je .shortdir.parent3
jmp .shortdir.common jmp .shortdir.common
.shortdir.parent3: .shortdir.parent3:
inc esi inc esi
@ -1181,7 +1164,7 @@ DEBUGF 1,"NOT IMPLEMENTED: DIR FORMAT\n"
add esi, 2 add esi, 2
add ebx, xfs_inode.di_u add ebx, xfs_inode.di_u
stdcall xfs_get_inode_number_sf, dword[ebx + xfs_dir2_sf_hdr.count], dword[ebx + xfs_dir2_sf_hdr.parent + 4], dword[ebx + xfs_dir2_sf_hdr.parent] stdcall xfs_get_inode_number_sf, dword[ebx + xfs_dir2_sf_hdr.count], dword[ebx + xfs_dir2_sf_hdr.parent + 4], dword[ebx + xfs_dir2_sf_hdr.parent]
DEBUGF 1,"found inode: 0x%x%x\n",edx,eax ;DEBUGF 1,"found inode: 0x%x%x\n",edx,eax
jmp .quit jmp .quit
; not a parent inode? ; not a parent inode?
@ -1201,8 +1184,8 @@ DEBUGF 1,"found inode: 0x%x%x\n",edx,eax
movzx ecx, byte[edi + xfs_dir2_sf_entry.namelen] movzx ecx, byte[edi + xfs_dir2_sf_entry.namelen]
add edi, xfs_dir2_sf_entry.name add edi, xfs_dir2_sf_entry.name
mov esi, [esp + 4] mov esi, [esp + 4]
DEBUGF 1,"esi: %s\n",esi ;DEBUGF 1,"esi: %s\n",esi
DEBUGF 1,"edi: %s\n",edi ;DEBUGF 1,"edi: %s\n",edi
repe cmpsb repe cmpsb
jne @f jne @f
cmp byte[esi], 0 ; HINT: use adc here? cmp byte[esi], 0 ; HINT: use adc here?
@ -1596,7 +1579,7 @@ DEBUGF 1,"found inode: 0x%x%x\n",edx,eax
xfs_get_inode: xfs_get_inode:
; call xfs_get_inode_short until file is found / error returned ; call xfs_get_inode_short until file is found / error returned
DEBUGF 1,"getting inode of: %s\n",[esp+4] ;DEBUGF 1,"getting inode of: %s\n",[esp+4]
push ebx esi edi push ebx esi edi
; start from the root inode ; start from the root inode
@ -1607,7 +1590,7 @@ DEBUGF 1,"getting inode of: %s\n",[esp+4]
.next_dir: .next_dir:
cmp byte[esi], 0 cmp byte[esi], 0
jz .found je .found
;DEBUGF 1,"next_level: |%s|\n",esi ;DEBUGF 1,"next_level: |%s|\n",esi
stdcall xfs_get_inode_short, esi, eax, edx stdcall xfs_get_inode_short, esi, eax, edx
@ -1619,7 +1602,6 @@ DEBUGF 1,"getting inode of: %s\n",[esp+4]
jmp .next_dir ; file name found, go to next directory level jmp .next_dir ; file name found, go to next directory level
.found: .found:
DEBUGF 1, "inode found: 0x%x%x\n", edx, eax
.quit: .quit:
pop edi esi ebx pop edi esi ebx
@ -1654,14 +1636,13 @@ xfs_ReadFolder:
; 2. ; 2.
push ebx esi edi push ebx esi edi
add esi, [esp + 32] ; directory name add esi, [esp + 32] ; directory name
DEBUGF 1,"xfs_ReadFolder: |%s|\n",esi ;DEBUGF 1,"xfs_ReadFolder: |%s|\n",esi
stdcall xfs_get_inode, esi stdcall xfs_get_inode, esi
pop edi esi ebx pop edi esi ebx
mov ecx, edx mov ecx, edx
or ecx, eax or ecx, eax
jnz @f jnz @f
movi eax, ERROR_FILE_NOT_FOUND movi eax, ERROR_FILE_NOT_FOUND
jmp .error
@@: @@:
; 3. ; 3.

11
xfs.inc
View File

@ -42,7 +42,7 @@ XFS_ABTC_MAGIC = 'ABTC'
XFS_IBT_MAGIC = 'IABT' XFS_IBT_MAGIC = 'IABT'
XFS_DINODE_MAGIC = 'IN' XFS_DINODE_MAGIC = 'IN'
XFS_BMAP_MAGIC = 'BMAP' XFS_BMAP_MAGIC = 'BMAP'
XFS_DA_NODE_MAGIC = 0xbefe ; these are little endian here XFS_DA_NODE_MAGIC = 0xbefe ; those are little endian here
XFS_ATTR_LEAF_MAGIC = 0xeefb ; but big endian in docs XFS_ATTR_LEAF_MAGIC = 0xeefb ; but big endian in docs
XFS_DIR2_LEAF1_MAGIC = 0xf1d2 ; pay attention! XFS_DIR2_LEAF1_MAGIC = 0xf1d2 ; pay attention!
XFS_DIR2_LEAFN_MAGIC = 0xffd2 ; XFS_DIR2_LEAFN_MAGIC = 0xffd2 ;
@ -64,11 +64,11 @@ BMBT_BLOCKCOUNT_BITLEN = 21
; they are magic infile offsets for directories ; they are magic infile offsets for directories
XFS_DIR2_DATA_ALIGN_LOG = 3 ; i.e., 8 bytes XFS_DIR2_DATA_ALIGN_LOG = 3 ; i.e., 8 bytes
XFS_DIR2_LEAF_SPACE = 1 XFS_DIR2_LEAF_SPACE = 1
XFS_DIR2_SPACE_SIZE = 1 SHL (32 + XFS_DIR2_DATA_ALIGN_LOG) XFS_DIR2_SPACE_SIZE = (1 SHL (32 + XFS_DIR2_DATA_ALIGN_LOG))
XFS_DIR2_LEAF_OFFSET = XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE XFS_DIR2_LEAF_OFFSET = (XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE)
XFS_DIR2_FREE_SPACE = 2 XFS_DIR2_FREE_SPACE = 2
XFS_DIR2_SPACE_SIZE = 1 SHL (32 + XFS_DIR2_DATA_ALIGN_LOG) XFS_DIR2_SPACE_SIZE = (1 SHL (32 + XFS_DIR2_DATA_ALIGN_LOG))
XFS_DIR2_FREE_OFFSET = XFS_DIR2_FREE_SPACE * XFS_DIR2_SPACE_SIZE XFS_DIR2_FREE_OFFSET = (XFS_DIR2_FREE_SPACE * XFS_DIR2_SPACE_SIZE)
; data section magic constants for directories (xfs_dir2_data.h) ; data section magic constants for directories (xfs_dir2_data.h)
@ -526,4 +526,3 @@ struct XFS PARTITION
buffer_pos dd ? buffer_pos dd ?
eof dd ? eof dd ?
ends ends

View File

@ -1,416 +0,0 @@
; lib
;
; Copyright (C) 2012-2013,2016 Ivan Baravy (dunkaist)
;
; This program is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <http://www.gnu.org/licenses/>.
format ELF
__DEBUG__ = 1
__DEBUG_LEVEL__ = 2
include 'proc32.inc'
include 'struct.inc'
include 'macros.inc'
include 'const.inc'
include 'system.inc'
;include 'fdo.inc'
include 'debug-fdo.inc'
include 'disk.inc'
;include 'fs_lfn.inc'
include 'fs_common.inc'
ERROR_SUCCESS = 0
ERROR_DISK_BASE = 1
ERROR_UNSUPPORTED_FS = 2
ERROR_UNKNOWN_FS = 3
ERROR_PARTITION = 4
ERROR_FILE_NOT_FOUND = 5
ERROR_END_OF_FILE = 6
ERROR_MEMORY_POINTER = 7
ERROR_DISK_FULL = 8
ERROR_FS_FAIL = 9
ERROR_ACCESS_DENIED = 10
ERROR_DEVICE = 11
ERROR_OUT_OF_MEMORY = 12
purge section,mov,add,sub
section '.text' executable align 16
;public _start
_start:
; pushfd
; pop eax
; or eax, 1 SHL 18 ; Alignment Check flag
; push eax
; popfd
pop eax
cmp eax, 2
jz .params_ok
.few_arguments:
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, msg_few_args
mov edx, msg_few_args.size
int 0x80
jmp .error_quit
.params_ok:
pop eax
pop ebx
mov [filename], ebx
mov eax, SYS_OPEN
mov ecx, O_RDONLY OR O_LARGEFILE
int 0x80
cmp eax, -2 ; FIXME RETURN VALUE
je .file_not_found
mov [fd], eax
mov eax, 0
mov ebx, mbr_buffer
mov ebp, partition
call fs_read32_sys
mov esi, disk
mov [esi + DISK.MediaInfo.SectorSize], 512
mov ebp, partition
mov [ebp + PARTITION.Disk], esi
mov ebx, mbr_buffer
call xfs_create_partition
test eax, eax
jz .not_xfs_partition
mov [fs_struct], eax
.next_cmd:
call prompt
call read_cmd
mov eax, dword[cmd_buf]
cmp eax, dword 'exit'
jnz @f
jmp .quit
@@:
cmp ax, word 'ls'
jnz @f
call cmd_ls
jmp .next_cmd
@@:
.unknown:
call unknown_command
jmp .next_cmd
.quit:
mov eax, SYS_EXIT
xor ebx, ebx
int 0x80
.not_xfs_partition:
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, msg_not_xfs_partition
mov edx, msg_not_xfs_partition.size
int 0x80
jmp .error_quit
.file_not_found:
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, msg_file_not_found
mov edx, msg_file_not_found.size
int 0x80
stdcall print_filename, [filename]
jmp .error_quit
.error_quit:
mov eax, SYS_EXIT
mov ebx, 1
int 0x80
cmd_ls:
mov ebp, [fs_struct]
mov ebx, sf70_params
mov esi, cmd_buf
mov edi, esi
mov al, ' '
mov ecx, 100
repnz scasb
mov [ebx + 0x14], edi
mov eax, edi
sub eax, esi
push eax
mov al, 0x0a
repnz scasb
mov byte[edi-1], 0
call xfs_ReadFolder
pop eax
mov eax, sf70_buffer
mov ecx, [eax + 4] ; read bdfes
add eax, 0x20 ; skip header
.next_bdfe:
lea edx, [eax + 0x28]
push eax ecx
stdcall print_filename, edx
pop ecx eax
add eax, 304
dec ecx
jnz .next_bdfe
ret
public kos_fuse_init
kos_fuse_init:
push ebx esi edi ebp
mov eax, [esp + 0x14]
mov [fd], eax
mov eax, 0
mov ebx, mbr_buffer
mov ebp, partition
call fs_read32_sys
mov esi, disk
mov [esi + DISK.MediaInfo.SectorSize], 512
mov ebp, partition
mov [ebp + PARTITION.Disk], esi
mov ebx, mbr_buffer
call xfs_create_partition
test eax, eax
jnz @f
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, msg_not_xfs_partition
mov edx, msg_not_xfs_partition.size
int 0x80
@@:
mov [fs_struct], eax
pop ebp edi esi ebx
ret
;char *hello_readdir(const char *path, off_t offset)
public kos_fuse_readdir
kos_fuse_readdir:
push ebx esi edi ebp
mov edx, sf70_params
mov dword[edx + 0x00], 1
mov eax, [esp + 0x18] ; offset
mov [edx + 0x04], eax
mov dword[edx + 0x08], 1
mov dword[edx + 0x0c], 100
mov dword[edx + 0x10], sf70_buffer
mov eax, [esp + 0x14] ; path
inc eax ; skip '/'
mov [edx + 0x14], eax
mov ebp, [fs_struct]
mov ebx, sf70_params
mov esi, eax
push 0
call xfs_ReadFolder
pop eax
pop ebp edi esi ebx
mov eax, sf70_buffer
ret
unknown_command:
pushad
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, msg_unknown_command
mov edx, msg_unknown_command.size
int 0x80
popad
ret
prompt:
pushad
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, endl_prompt
mov edx, 2
int 0x80
popad
ret
read_cmd:
pushad
mov eax, SYS_READ
mov ebx, STDIN
mov ecx, cmd_buf
mov edx, 4096
int 0x80
popad
ret
; in: eax = sector, ebx = buffer, ebp = pointer to PARTITION structure
fs_read32_sys:
pushad
imul ecx, eax, 512
add ecx, 2048*512
mov eax, SYS_LSEEK
mov ebx, [fd]
mov edx, SEEK_SET
int 0x80
;DEBUGF 1, "lseek: %x\n", eax
popad
pushad
mov eax, SYS_READ
mov ecx, ebx
mov ebx, [fd]
mov edx, 512
int 0x80
;DEBUGF 1, "read: %d\n", eax
popad
xor eax, eax
ret
fs_read32_app:
ret
fs_read64_sys:
pushad
imul ecx, eax, 512
add ecx, 2048*512
mov eax, SYS_LSEEK
mov ebx, [fd]
mov edx, SEEK_SET
int 0x80
;DEBUGF 1, "lseek: %x\n", eax
popad
pushad
mov eax, SYS_READ
imul edx, ecx, 512
mov ecx, ebx
mov ebx, [fd]
int 0x80
;DEBUGF 1, "read: %d\n", eax
popad
xor eax, eax
ret
fs_read64_app:
ret
malloc:
push [alloc_pos]
add [alloc_pos], eax
pop eax
ret
free:
ret
kernel_free:
ret
mutex_init:
ret
mutex_lock:
ret
mutex_unlock:
ret
put_board:
pushad
mov eax, SYS_WRITE
mov ebx, STDOUT
push ecx
mov ecx, esp
mov edx, 1
int 0x80
pop ecx
popad
ret
proc print_filename _filename
stdcall strlen, [_filename]
mov byte[edi - 1], 0x0a
inc edx
mov ecx, [_filename]
mov eax, SYS_WRITE
mov ebx, STDOUT
int 0x80
ret
endp
proc strlen _str
mov edi, [_str]
mov ecx, -1
xor eax, eax
repnz scasb
not ecx
dec ecx
mov edx, ecx
ret
endp
include 'xfs.asm'
section '.data' writeable align 16
msg_few_args db 'usage: xfskos image [offset]',0x0a
msg_few_args.size = $ - msg_few_args
msg_file_not_found db 'file not found: '
msg_file_not_found.size = $ - msg_file_not_found
msg_unknown_command db 'unknown command',0x0a
msg_unknown_command.size = $ - msg_unknown_command
msg_not_xfs_partition db 'not xfs partition',0x0a
msg_not_xfs_partition.size = $ - msg_not_xfs_partition
endl_prompt db '> '
include_debug_strings
partition_offset dd 2048*512
alloc_pos dd alloc_base
sf70_params dd 1, 0, 1, 100, sf70_buffer, -1
section '.bss' writeable align 16
mbr_buffer rb 4096*3
filename rd 1
fd rd 1
cmd_buf rb 4096
partition PARTITION
disk DISK
alloc_base rb 1024*1024
fs_struct rd 1
sf70_buffer rb 1024*1024