Rewrite kos_disk_* procs in C, define more blk/fs related structures.

This commit is contained in:
Ivan Baravy 2020-02-21 02:18:40 +03:00
parent 126802f61f
commit e5ad82ffd5
6 changed files with 181 additions and 111 deletions

View File

@ -51,7 +51,7 @@ typedef enum {
F80 = 80, F80 = 80,
} f70or80_t; } f70or80_t;
typedef enum { enum {
ERROR_SUCCESS, ERROR_SUCCESS,
ERROR_DISK_BASE, ERROR_DISK_BASE,
ERROR_UNSUPPORTED_FS, ERROR_UNSUPPORTED_FS,
@ -65,7 +65,19 @@ typedef enum {
ERROR_ACCESS_DENIED, ERROR_ACCESS_DENIED,
ERROR_DEVICE, ERROR_DEVICE,
ERROR_OUT_OF_MEMORY, ERROR_OUT_OF_MEMORY,
} f70status_t; };
typedef struct lhead lhead_t;
struct lhead {
lhead_t *next;
lhead_t *prev;
};
typedef struct {
lhead_t wait_list;
uint32_t count;
} mutex_t;
typedef struct { typedef struct {
uint32_t flags; uint32_t flags;
@ -73,6 +85,24 @@ typedef struct {
uint64_t capacity; // in sectors uint64_t capacity; // in sectors
} diskmediainfo_t; } diskmediainfo_t;
typedef struct {
uintptr_t pointer;
uint32_t data_size;
uintptr_t data;
uint32_t sad_size;
uint32_t search_start;
uint32_t sector_size_log;
} disk_cache_t;
typedef struct {
uint64_t first_sector;
uint64_t length; // in sectors
void *disk;
void *fs_user_functions;
} partition_t;
typedef struct disk_t disk_t;
typedef struct { typedef struct {
uint32_t strucsize; uint32_t strucsize;
void (*close)(void *userdata) __attribute__((__stdcall__)); void (*close)(void *userdata) __attribute__((__stdcall__));
@ -84,6 +114,28 @@ typedef struct {
unsigned int (*adjust_cache_size)(uint32_t suggested_size) __attribute__((__stdcall__)); unsigned int (*adjust_cache_size)(uint32_t suggested_size) __attribute__((__stdcall__));
} diskfunc_t; } diskfunc_t;
struct disk_t {
disk_t *next;
disk_t *prev;
diskfunc_t *functions;
const char *name;
void *userdata;
uint32_t driver_flags;
uint32_t ref_count;
mutex_t media_lock;
uint8_t media_inserted;
uint8_t media_used;
uint16_t padding;
uint32_t media_ref_count;
diskmediainfo_t media_info;
uint32_t num_partitions;
partition_t **partitions;
uint32_t cache_size;
mutex_t cache_lock;
disk_cache_t sys_cache;
disk_cache_t app_cache;
};
typedef struct { typedef struct {
uint32_t attr; uint32_t attr;
uint32_t enc; uint32_t enc;
@ -176,19 +228,26 @@ typedef struct {
uint8_t opaque[1024-HASH_SIZE]; uint8_t opaque[1024-HASH_SIZE];
} hash_context; } hash_context;
uint32_t kos_time_to_epoch(uint32_t *time);
void kos_init(void); void kos_init(void);
void i40(void); void i40(void);
void *kos_disk_add(const char *file_name, const char *disk_name); uint32_t kos_time_to_epoch(uint32_t *time);
int kos_disk_del(const char *name); void set_eflags_tf(int x);
void *disk_add(diskfunc_t *disk, const char *name, void *userdata, uint32_t flags) __attribute__((__stdcall__));
void *disk_media_changed(diskfunc_t *disk, int inserted) __attribute__((__stdcall__));
void disk_del(disk_t *disk) __attribute__((__stdcall__));
void hash_oneshot(void *ctx, void *data, size_t len); void hash_oneshot(void *ctx, void *data, size_t len);
void set_eflags_tf(int x); void xfs_user_functions(void);
void ext_user_functions(void);
void fat_user_functions(void);
void ntfs_user_functions(void);
void coverage_begin(void); void coverage_begin(void);
void coverage_end(void); void coverage_end(void);
extern uint32_t *kos_lfb_base; extern uint32_t *kos_lfb_base;
extern uint16_t *kos_win_stack; extern uint16_t *kos_win_stack;
extern uint16_t *kos_win_pos; extern uint16_t *kos_win_pos;
extern disk_t disk_list;
#endif #endif

111
umka.asm
View File

@ -5,7 +5,30 @@ __DEBUG_LEVEL__ = 1
extrn 'malloc' as libc_malloc extrn 'malloc' as libc_malloc
extrn 'free' as libc_free extrn 'free' as libc_free
extrn vdisk_functions
public disk_add
public disk_del
public disk_list
public disk_media_changed
public xfs._.user_functions as 'xfs_user_functions'
public ext_user_functions
public fat_user_functions
public ntfs_user_functions
public i40
public coverage_begin
public coverage_end
public sha3_256_oneshot as 'hash_oneshot'
public set_eflags_tf
public kos_time_to_epoch
public kos_init
public win_stack_addr as 'kos_win_stack'
public win_pos_addr as 'kos_win_pos'
public lfb_base_addr as 'kos_lfb_base'
cli equ nop cli equ nop
iretd equ retd iretd equ retd
@ -30,10 +53,7 @@ purge mov,add,sub
purge mov,add,sub purge mov,add,sub
section '.text' executable align 32 section '.text' executable align 32
public i40
coverage_begin: coverage_begin:
public coverage_begin
include 'macros.inc' include 'macros.inc'
macro diff16 msg,blah2,blah3 { macro diff16 msg,blah2,blah3 {
@ -123,14 +143,12 @@ struct VDISK
SectSize dd ? ; sector size SectSize dd ? ; sector size
ends ends
public sha3_256_oneshot as 'hash_oneshot'
proc sha3_256_oneshot c uses ebx esi edi ebp, _ctx, _data, _len proc sha3_256_oneshot c uses ebx esi edi ebp, _ctx, _data, _len
stdcall sha3_256.oneshot, [_ctx], [_data], [_len] stdcall sha3_256.oneshot, [_ctx], [_data], [_len]
ret ret
endp endp
; TODO: move to trace_lbr ; TODO: move to trace_lbr
public set_eflags_tf
set_eflags_tf: set_eflags_tf:
pushfd pushfd
pop eax pop eax
@ -143,7 +161,6 @@ set_eflags_tf:
popfd popfd
ret ret
public kos_time_to_epoch
proc kos_time_to_epoch c uses ebx esi edi ebp, _time proc kos_time_to_epoch c uses ebx esi edi ebp, _time
mov esi, [_time] mov esi, [_time]
call fsCalculateTime call fsCalculateTime
@ -151,7 +168,6 @@ proc kos_time_to_epoch c uses ebx esi edi ebp, _time
ret ret
endp endp
public kos_init
proc kos_init c uses ebx esi edi ebp proc kos_init c uses ebx esi edi ebp
mov edi, endofcode mov edi, endofcode
mov ecx, uglobals_size mov ecx, uglobals_size
@ -255,79 +271,6 @@ proc kos_init c uses ebx esi edi ebp
ret ret
endp endp
public kos_disk_add
proc kos_disk_add c uses ebx esi edi ebp, _file_name, _disk_name
extrn vdisk_init
ccall vdisk_init, [_file_name]
stdcall disk_add, vdisk_functions, [_disk_name], eax, DISK_NO_INSERT_NOTIFICATION
push eax
stdcall disk_media_changed, eax, 1
pop edx
movi ecx, 1
mov esi, [edx+DISK.Partitions]
.next_part:
cmp ecx, [edx+DISK.NumPartitions]
ja .part_done
DEBUGF 1, "/%s/%d: ", [edx+DISK.Name], ecx
lodsd
inc ecx
cmp [eax+PARTITION.FSUserFunctions], xfs._.user_functions
jnz @f
DEBUGF 1, "xfs\n"
jmp .next_part
@@:
cmp [eax+PARTITION.FSUserFunctions], ext_user_functions
jnz @f
DEBUGF 1, "ext\n"
jmp .next_part
@@:
cmp [eax+PARTITION.FSUserFunctions], fat_user_functions
jnz @f
DEBUGF 1, "fat\n"
jmp .next_part
@@:
cmp [eax+PARTITION.FSUserFunctions], ntfs_user_functions
jnz @f
DEBUGF 1, "ntfs\n"
jmp .next_part
@@:
DEBUGF 1, "???\n"
jmp .next_part
.part_done:
xor eax, eax
ret
.error:
movi eax, 1
ret
endp
public kos_disk_del
proc kos_disk_del c uses ebx esi edi ebp, _name
mov eax, [disk_list+LHEAD.next]
.next_disk:
cmp eax, disk_list
jz .not_found
mov esi, [eax+DISK.Name]
mov edi, [_name]
@@:
movzx ecx, byte[esi]
cmpsb
jnz .skip
jecxz .found
jmp @b
.skip:
mov eax, [eax+LHEAD.next]
jmp .next_disk
.found:
stdcall disk_del, eax
xor eax, eax
ret
.not_found:
movi eax, 1
ret
endp
proc alloc_page proc alloc_page
ret ret
push ecx edx push ecx edx
@ -462,7 +405,6 @@ macro pew x, y {
end if end if
} }
1FFFFFFFh fix 0
include fix pew include fix pew
HEAP_BASE equ HEAP_BASE equ
macro org x {} macro org x {}
@ -497,7 +439,6 @@ purge HEAP_BASE
restore pew restore pew
coverage_end: coverage_end:
public coverage_end
section '.data' writeable align 64 section '.data' writeable align 64
@ -506,11 +447,8 @@ section '.data' writeable align 64
timer_ticks dd 0 timer_ticks dd 0
fpu_owner dd ? fpu_owner dd ?
public win_stack_addr as 'kos_win_stack'
win_stack_addr dd WIN_STACK win_stack_addr dd WIN_STACK
public win_pos_addr as 'kos_win_pos'
win_pos_addr dd WIN_POS win_pos_addr dd WIN_POS
public lfb_base_addr as 'kos_lfb_base'
lfb_base_addr dd lfb_base lfb_base_addr dd lfb_base
uglobal uglobal
@ -539,7 +477,6 @@ window_data: rb 0x2000
CURRENT_TASK: rb 4 CURRENT_TASK: rb 4
TASK_COUNT: rb 12 TASK_COUNT: rb 12
rb 0x1000000 rb 0x1000000
;os_base rb 0x1000000
BOOT_LO boot_data BOOT_LO boot_data
BOOT boot_data BOOT boot_data
lfb_base rd MAX_SCREEN_WIDTH*MAX_SCREEN_HEIGHT lfb_base rd MAX_SCREEN_WIDTH*MAX_SCREEN_HEIGHT

View File

@ -31,6 +31,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include "vdisk.h"
#include "kolibri.h" #include "kolibri.h"
#include "syscalls.h" #include "syscalls.h"
@ -122,12 +123,25 @@ static struct fuse_operations umka_oper = {
.read = umka_read, .read = umka_read,
}; };
diskfunc_t vdisk_functions = {
.strucsize = sizeof(diskfunc_t),
.close = vdisk_close,
.closemedia = NULL,
.querymedia = vdisk_querymedia,
.read = vdisk_read,
.write = vdisk_write,
.flush = NULL,
.adjust_cache_size = NULL,
};
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
if (argc != 3) { if (argc != 3) {
printf("usage: umka_fuse dir img\n"); printf("usage: umka_fuse dir img\n");
exit(1); exit(1);
} }
kos_init(); kos_init();
kos_disk_add(argv[2], "hd0"); void *userdata = vdisk_init(argv[2]);
void *vdisk = disk_add(&vdisk_functions, "hd0", userdata, 0);
disk_media_changed(vdisk, 1);
return fuse_main(argc-1, argv, &umka_oper, NULL); return fuse_main(argc-1, argv, &umka_oper, NULL);
} }

View File

@ -30,6 +30,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <assert.h> #include <assert.h>
#include <time.h> #include <time.h>
#include "vdisk.h"
#include "kolibri.h" #include "kolibri.h"
#include "syscalls.h" #include "syscalls.h"
#include "trace.h" #include "trace.h"
@ -53,6 +54,16 @@
} \ } \
} while (0) } while (0)
diskfunc_t vdisk_functions = {
.strucsize = sizeof(diskfunc_t),
.close = vdisk_close,
.closemedia = NULL,
.querymedia = vdisk_querymedia,
.read = vdisk_read,
.write = vdisk_write,
.flush = NULL,
.adjust_cache_size = NULL,
};
char cur_dir[PATH_MAX] = "/"; char cur_dir[PATH_MAX] = "/";
const char *last_dir = cur_dir; const char *last_dir = cur_dir;
bool cur_dir_changed = true; bool cur_dir_changed = true;
@ -76,7 +87,7 @@ const char *f70_status_name[] = {
"out_of_memory" "out_of_memory"
}; };
const char *get_f70_status_name(f70status_t s) { const char *get_f70_status_name(int s) {
switch (s) { switch (s) {
case ERROR_SUCCESS: case ERROR_SUCCESS:
// return ""; // return "";
@ -195,22 +206,55 @@ int split_args(char *s, char **argv) {
return argc; return argc;
} }
void umka_disk_list_partitions(disk_t *d) {
for (size_t i = 0; i < d->num_partitions; i++) {
printf("/%s/%d: ", d->name, i+1);
if (d->partitions[i]->fs_user_functions == xfs_user_functions) {
printf("xfs\n");
} else if (d->partitions[i]->fs_user_functions == ext_user_functions) {
printf("ext\n");
} else if (d->partitions[i]->fs_user_functions == fat_user_functions) {
printf("fat\n");
} else if (d->partitions[i]->fs_user_functions == ntfs_user_functions) {
printf("ntfs\n");
} else {
printf("???\n");
}
}
}
void umka_disk_add(int argc, char **argv) { void umka_disk_add(int argc, char **argv) {
(void)argc; (void)argc;
const char *file_name = argv[1]; const char *file_name = argv[1];
const char *disk_name = argv[2]; const char *disk_name = argv[2];
if (kos_disk_add(file_name, disk_name)) {
printf("[!!] can't add file '%s' as disk '%s'\n", file_name, disk_name); void *userdata = vdisk_init(file_name);
if (userdata) {
void *vdisk = disk_add(&vdisk_functions, disk_name, userdata, 0);
if (vdisk) {
disk_media_changed(vdisk, 1);
umka_disk_list_partitions(vdisk);
return;
}
} }
printf("umka: can't add file '%s' as disk '%s'\n", file_name, disk_name);
return; return;
} }
void umka_disk_del_by_name(const char *name) {
for(disk_t *d = disk_list.next; d != &disk_list; d = d->next) {
if (!strcmp(d->name, name)) {
disk_del(d);
return;
}
}
printf("umka: can't find disk '%s'\n", name);
}
void umka_disk_del(int argc, char **argv) { void umka_disk_del(int argc, char **argv) {
(void)argc; (void)argc;
const char *name = argv[1]; const char *name = argv[1];
if (kos_disk_del(name)) { umka_disk_del_by_name(name);
printf("[!!] can't find or delete disk '%s'\n", name);
}
return; return;
} }

16
vdisk.c
View File

@ -2,6 +2,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <inttypes.h> #include <inttypes.h>
#include <errno.h>
#include "kolibri.h" #include "kolibri.h"
typedef struct { typedef struct {
@ -12,6 +13,10 @@ typedef struct {
void *vdisk_init(const char *fname) { void *vdisk_init(const char *fname) {
FILE *f = fopen(fname, "r+"); FILE *f = fopen(fname, "r+");
if (!f) {
printf("vdisk: can't open file '%s': %s\n", fname, strerror(errno));
return NULL;
}
fseeko(f, 0, SEEK_END); fseeko(f, 0, SEEK_END);
off_t fsize = ftello(f); off_t fsize = ftello(f);
fseeko(f, 0, SEEK_SET); fseeko(f, 0, SEEK_SET);
@ -55,14 +60,3 @@ int vdisk_querymedia(void *userdata, diskmediainfo_t *minfo) {
minfo->capacity = vdisk->sect_cnt; minfo->capacity = vdisk->sect_cnt;
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
diskfunc_t vdisk_functions = {
.strucsize = sizeof(diskfunc_t),
.close = vdisk_close,
.closemedia = NULL,
.querymedia = vdisk_querymedia,
.read = vdisk_read,
.write = vdisk_write,
.flush = NULL,
.adjust_cache_size = NULL,
};

22
vdisk.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef VDISK_H_INCLUDED
#define VDISK_H_INCLUDED
#include <stdio.h>
#include <inttypes.h>
#include "kolibri.h"
void *vdisk_init(const char *fname);
__attribute__((__stdcall__))
void vdisk_close(void *userdata);
__attribute__((__stdcall__))
int vdisk_read(void *userdata, void *buffer, off_t startsector, size_t *numsectors);
__attribute__((__stdcall__))
int vdisk_write(void *userdata, void *buffer, off_t startsector, size_t *numsectors);
__attribute__((__stdcall__))
int vdisk_querymedia(void *userdata, diskmediainfo_t *minfo);
#endif // VDISK_H_INCLUDED