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,
} f70or80_t;
typedef enum {
enum {
ERROR_SUCCESS,
ERROR_DISK_BASE,
ERROR_UNSUPPORTED_FS,
@ -65,7 +65,19 @@ typedef enum {
ERROR_ACCESS_DENIED,
ERROR_DEVICE,
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 {
uint32_t flags;
@ -73,6 +85,24 @@ typedef struct {
uint64_t capacity; // in sectors
} 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 {
uint32_t strucsize;
void (*close)(void *userdata) __attribute__((__stdcall__));
@ -84,6 +114,28 @@ typedef struct {
unsigned int (*adjust_cache_size)(uint32_t suggested_size) __attribute__((__stdcall__));
} 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 {
uint32_t attr;
uint32_t enc;
@ -176,19 +228,26 @@ typedef struct {
uint8_t opaque[1024-HASH_SIZE];
} hash_context;
uint32_t kos_time_to_epoch(uint32_t *time);
void kos_init(void);
void i40(void);
void *kos_disk_add(const char *file_name, const char *disk_name);
int kos_disk_del(const char *name);
uint32_t kos_time_to_epoch(uint32_t *time);
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 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_end(void);
extern uint32_t *kos_lfb_base;
extern uint16_t *kos_win_stack;
extern uint16_t *kos_win_pos;
extern disk_t disk_list;
#endif

111
umka.asm
View File

@ -5,7 +5,30 @@ __DEBUG_LEVEL__ = 1
extrn 'malloc' as libc_malloc
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
iretd equ retd
@ -30,10 +53,7 @@ purge mov,add,sub
purge mov,add,sub
section '.text' executable align 32
public i40
coverage_begin:
public coverage_begin
include 'macros.inc'
macro diff16 msg,blah2,blah3 {
@ -123,14 +143,12 @@ struct VDISK
SectSize dd ? ; sector size
ends
public sha3_256_oneshot as 'hash_oneshot'
proc sha3_256_oneshot c uses ebx esi edi ebp, _ctx, _data, _len
stdcall sha3_256.oneshot, [_ctx], [_data], [_len]
ret
endp
; TODO: move to trace_lbr
public set_eflags_tf
set_eflags_tf:
pushfd
pop eax
@ -143,7 +161,6 @@ set_eflags_tf:
popfd
ret
public kos_time_to_epoch
proc kos_time_to_epoch c uses ebx esi edi ebp, _time
mov esi, [_time]
call fsCalculateTime
@ -151,7 +168,6 @@ proc kos_time_to_epoch c uses ebx esi edi ebp, _time
ret
endp
public kos_init
proc kos_init c uses ebx esi edi ebp
mov edi, endofcode
mov ecx, uglobals_size
@ -255,79 +271,6 @@ proc kos_init c uses ebx esi edi ebp
ret
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
ret
push ecx edx
@ -462,7 +405,6 @@ macro pew x, y {
end if
}
1FFFFFFFh fix 0
include fix pew
HEAP_BASE equ
macro org x {}
@ -497,7 +439,6 @@ purge HEAP_BASE
restore pew
coverage_end:
public coverage_end
section '.data' writeable align 64
@ -506,11 +447,8 @@ section '.data' writeable align 64
timer_ticks dd 0
fpu_owner dd ?
public win_stack_addr as 'kos_win_stack'
win_stack_addr dd WIN_STACK
public win_pos_addr as 'kos_win_pos'
win_pos_addr dd WIN_POS
public lfb_base_addr as 'kos_lfb_base'
lfb_base_addr dd lfb_base
uglobal
@ -539,7 +477,6 @@ window_data: rb 0x2000
CURRENT_TASK: rb 4
TASK_COUNT: rb 12
rb 0x1000000
;os_base rb 0x1000000
BOOT_LO boot_data
BOOT boot_data
lfb_base rd MAX_SCREEN_WIDTH*MAX_SCREEN_HEIGHT

View File

@ -31,6 +31,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include "vdisk.h"
#include "kolibri.h"
#include "syscalls.h"
@ -122,12 +123,25 @@ static struct fuse_operations umka_oper = {
.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[]) {
if (argc != 3) {
printf("usage: umka_fuse dir img\n");
exit(1);
}
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);
}

View File

@ -30,6 +30,7 @@
#include <fcntl.h>
#include <assert.h>
#include <time.h>
#include "vdisk.h"
#include "kolibri.h"
#include "syscalls.h"
#include "trace.h"
@ -53,6 +54,16 @@
} \
} 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] = "/";
const char *last_dir = cur_dir;
bool cur_dir_changed = true;
@ -76,7 +87,7 @@ const char *f70_status_name[] = {
"out_of_memory"
};
const char *get_f70_status_name(f70status_t s) {
const char *get_f70_status_name(int s) {
switch (s) {
case ERROR_SUCCESS:
// return "";
@ -195,22 +206,55 @@ int split_args(char *s, char **argv) {
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)argc;
const char *file_name = argv[1];
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;
}
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)argc;
const char *name = argv[1];
if (kos_disk_del(name)) {
printf("[!!] can't find or delete disk '%s'\n", name);
}
umka_disk_del_by_name(name);
return;
}

16
vdisk.c
View File

@ -2,6 +2,7 @@
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <errno.h>
#include "kolibri.h"
typedef struct {
@ -12,6 +13,10 @@ typedef struct {
void *vdisk_init(const char *fname) {
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);
off_t fsize = ftello(f);
fseeko(f, 0, SEEK_SET);
@ -55,14 +60,3 @@ int vdisk_querymedia(void *userdata, diskmediainfo_t *minfo) {
minfo->capacity = vdisk->sect_cnt;
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