Implement disk_add, disk_del commands, fix tests.

This commit is contained in:
Ivan Baravy 2019-10-13 04:17:29 +03:00
parent 1bb4c6f8d7
commit cfdd6a2820
14 changed files with 1568 additions and 622 deletions

42
cio.c Normal file
View File

@ -0,0 +1,42 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include "kolibri.h"
typedef struct {
FILE *file;
uint32_t sect_cnt;
uint32_t sect_size;
} vdisk_t;
void *cio_disk_init(const char *fname) {
FILE *f = fopen(fname, "r+");
fseeko(f, 0, SEEK_END);
off_t fsize = ftello(f);
fseeko(f, 0, SEEK_SET);
size_t sect_size = 512;
if (strstr(fname, "s4096") != NULL || strstr(fname, "s4k") != NULL) {
sect_size = 4096;
}
vdisk_t *vdisk = (vdisk_t*)malloc(sizeof(vdisk_t));
*vdisk = (vdisk_t){f, fsize / sect_size, sect_size};
return vdisk;
}
void cio_disk_free(vdisk_t *vdisk) {
fclose(vdisk->file);
free(vdisk);
}
f70status cio_disk_read(vdisk_t *vdisk, uint8_t *buffer, off_t startsector, uint32_t *numsectors) {
fseeko(vdisk->file, startsector * vdisk->sect_size, SEEK_SET);
fread(buffer, *numsectors * vdisk->sect_size, 1, vdisk->file);
return F70_SUCCESS;
}
f70status cio_disk_write(vdisk_t *vdisk, uint8_t *buffer, off_t startsector, uint32_t *numsectors) {
fseeko(vdisk->file, startsector * vdisk->sect_size, SEEK_SET);
fwrite(buffer, *numsectors * vdisk->sect_size, 1, vdisk->file);
return F70_SUCCESS;
}

View File

@ -1,435 +0,0 @@
;
; Formatted Debug Output (FDO)
; Copyright (c) 2005-2006, mike.dld
; Created: 2005-01-29, Changed: 2006-11-10
;
; For questions and bug reports, mail to mike.dld@gmail.com
;
; Available format specifiers are: %s, %d, %u, %x (with partial width support)
;
; to be defined:
; __DEBUG__ equ 1
; __DEBUG_LEVEL__ equ 5
macro debug_func name {
if used name
name@of@func equ name
}
macro debug_beginf {
align 4
name@of@func:
}
debug_endf fix end if
macro DEBUGS _sign,[_str] {
common
local tp
tp equ 0
match _arg:_num,_str \{
DEBUGS_N _sign,_num,_arg
tp equ 1
\}
match =0 _arg,tp _str \{
DEBUGS_N _sign,,_arg
\}
}
macro DEBUGS_N _sign,_num,[_str] {
common
pushf
pushad
local ..str,..label,is_str
is_str = 0
forward
if _str eqtype ''
is_str = 1
end if
common
if is_str = 1
jmp ..label
..str db _str,0
..label:
add esp,4*8+4
mov edx,..str
sub esp,4*8+4
else
mov edx,_str
end if
if ~_num eq
if _num eqtype eax
if _num in <eax,ebx,ecx,edx,edi,ebp,esp>
mov esi,_num
else if ~_num eq esi
movzx esi,_num
end if
else if _num eqtype 0
mov esi,_num
else
local tp
tp equ 0
match [_arg],_num \{
mov esi,dword[_arg]
tp equ 1
\}
match =0 =dword[_arg],tp _num \{
mov esi,dword[_arg]
tp equ 1
\}
match =0 =word[_arg],tp _num \{
movzx esi,word[_arg]
tp equ 1
\}
match =0 =byte[_arg],tp _num \{
movzx esi,byte[_arg]
tp equ 1
\}
match =0,tp \{
'Error: specified string width is incorrect'
\}
end if
else
mov esi,0x7FFFFFFF
end if
call fdo_debug_outstr
popad
popf
}
macro DEBUGD _sign,_dec {
local tp
tp equ 0
match _arg:_num,_dec \{
DEBUGD_N _sign,_num,_arg
tp equ 1
\}
match =0 _arg,tp _dec \{
DEBUGD_N _sign,,_arg
\}
}
macro DEBUGD_N _sign,_num,_dec {
pushf
pushad
if (~_num eq)
if (_dec eqtype eax | _dec eqtype 0)
'Error: precision allowed only for in-memory variables'
end if
if (~_num in <1,2,4>)
if _sign
'Error: 1, 2 and 4 are only allowed for precision in %d'
else
'Error: 1, 2 and 4 are only allowed for precision in %u'
end if
end if
end if
if _dec eqtype eax
if _dec in <ebx,ecx,edx,esi,edi,ebp,esp>
mov eax,_dec
else if ~_dec eq eax
if _sign = 1
movsx eax,_dec
else
movzx eax,_dec
end if
end if
else if _dec eqtype 0
mov eax,_dec
else
add esp,4*8+4
if _num eq
mov eax,dword _dec
else if _num = 1
if _sign = 1
movsx eax,byte _dec
else
movzx eax,byte _dec
end if
else if _num = 2
if _sign = 1
movsx eax,word _dec
else
movzx eax,word _dec
end if
else
mov eax,dword _dec
end if
sub esp,4*8+4
end if
mov cl,_sign
call fdo_debug_outdec
popad
popf
}
macro DEBUGH _sign,_hex {
local tp
tp equ 0
match _arg:_num,_hex \{
DEBUGH_N _sign,_num,_arg
tp equ 1
\}
match =0 _arg,tp _hex \{
DEBUGH_N _sign,,_arg
\}
}
macro DEBUGH_N _sign,_num,_hex {
pushf
pushad
if (~_num eq) & (~_num in <1,2,3,4,5,6,7,8>)
'Error: 1..8 are only allowed for precision in %x'
end if
if _hex eqtype eax
if _hex in <eax,ebx,ecx,edx,esi,edi,ebp,esp>
if ~_hex eq eax
mov eax,_hex
end if
else if _hex in <ax,bx,cx,dx,si,di,bp,sp>
if ~_hex eq ax
movzx eax,_hex
end if
shl eax,16
if (_num eq)
mov edx,4
end if
else if _hex in <al,ah,bl,bh,cl,ch,dl,dh>
if ~_hex eq al
movzx eax,_hex
end if
shl eax,24
if (_num eq)
mov edx,2
end if
end if
else if _hex eqtype 0
mov eax,_hex
else
add esp,4*8+4
mov eax,dword _hex
sub esp,4*8+4
end if
if ~_num eq
mov edx,_num
else
mov edx,8
end if
call fdo_debug_outhex
popad
popf
}
;-----------------------------------------------------------------------------
debug_func fdo_debug_outchar
debug_beginf
pushad
mov cl,al
mov ebx,1
mov eax,63
; mcall
call put_board
popad
ret
debug_endf
debug_func fdo_debug_outstr
debug_beginf
mov eax,63
mov ebx,1
.l1: dec esi
js .l2
mov cl,[edx]
or cl,cl
jz .l2
; mcall
call put_board
inc edx
jmp .l1
.l2: ret
debug_endf
debug_func fdo_debug_outdec
debug_beginf
or cl,cl
jz @f
or eax,eax
jns @f
neg eax
push eax
mov al,'-'
call fdo_debug_outchar
pop eax
@@: push 10
pop ecx
push -'0'
.l1: xor edx,edx
div ecx
push edx
test eax,eax
jnz .l1
.l2: pop eax
add al,'0'
jz .l3
call fdo_debug_outchar
jmp .l2
.l3: ret
debug_endf
debug_func fdo_debug_outhex
__fdo_hexdigits db '0123456789ABCDEF'
debug_beginf
mov cl,dl
neg cl
add cl,8
shl cl,2
rol eax,cl
.l1: rol eax,4
push eax
and eax,0x0000000F
mov al,[__fdo_hexdigits+eax]
call fdo_debug_outchar
pop eax
dec edx
jnz .l1
ret
debug_endf
;-----------------------------------------------------------------------------
macro DEBUGF _level,_format,[_arg] {
common
if __DEBUG__ = 1 & _level >= __DEBUG_LEVEL__
local ..f1,f2,a1,a2,c1,c2,c3,..lbl
_debug_str_ equ __debug_str_ # a1
a1 = 0
c2 = 0
c3 = 0
f2 = 0
repeat ..lbl-..f1
virtual at 0
db _format,0,0
load c1 word from %-1
end virtual
if c1 = '%s'
virtual at 0
db _format,0,0
store word 0 at %-1
load c1 from f2-c2
end virtual
if c1 <> 0
DEBUGS 0,_debug_str_+f2-c2
end if
c2 = c2 + 1
f2 = %+1
DEBUGF_HELPER S,a1,0,_arg
else if c1 = '%x'
virtual at 0
db _format,0,0
store word 0 at %-1
load c1 from f2-c2
end virtual
if c1 <> 0
DEBUGS 0,_debug_str_+f2-c2
end if
c2 = c2 + 1
f2 = %+1
DEBUGF_HELPER H,a1,0,_arg
else if c1 = '%d' | c1 = '%u'
local c4
if c1 = '%d'
c4 = 1
else
c4 = 0
end if
virtual at 0
db _format,0,0
store word 0 at %-1
load c1 from f2-c2
end virtual
if c1 <> 0
DEBUGS 0,_debug_str_+f2-c2
end if
c2 = c2 + 1
f2 = %+1
DEBUGF_HELPER D,a1,c4,_arg
else if c1 = '\n'
c3 = c3 + 1
end if
end repeat
virtual at 0
db _format,0,0
load c1 from f2-c2
end virtual
if (c1<>0)&(f2<>..lbl-..f1-1)
DEBUGS 0,_debug_str_+f2-c2
end if
virtual at 0
..f1 db _format,0
..lbl:
__debug_strings equ __debug_strings,_debug_str_,<_format>,..lbl-..f1-1-c2-c3
end virtual
end if
}
macro DEBUGFG _level, _group, _format, [_arg] {
common
if _group eqtype
DEBUGF _level, _format,_arg
else
if _level >= _group
DEBUGF 999, _format,_arg
end if
end if
}
macro __include_debug_strings dummy,[_id,_fmt,_len] {
common
local c1,a1,a2
forward
if defined _len & ~_len eq
_id:
a1 = 0
a2 = 0
repeat _len
virtual at 0
db _fmt,0,0
load c1 word from %+a2-1
end virtual
if (c1='%s')|(c1='%x')|(c1='%d')|(c1='%u')
db 0
a2 = a2 + 1
else if (c1='\n')
dw $0A0D
a1 = a1 + 1
a2 = a2 + 1
else
db c1 and 0x0FF
end if
end repeat
db 0
end if
}
macro DEBUGF_HELPER _letter,_num,_sign,[_arg] {
common
local num
num = 0
forward
if num = _num
DEBUG#_letter _sign,_arg
end if
num = num+1
common
_num = _num+1
}
macro include_debug_strings {
if __DEBUG__ = 1
match dbg_str,__debug_strings \{
__include_debug_strings dbg_str
\}
end if
}

128
kofu.c
View File

@ -1,10 +1,8 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
@ -14,6 +12,27 @@
#include "kolibri.h"
#include "trace.h"
// http://home.thep.lu.se/~bjorn/crc/
/* Simple public domain implementation of the standard CRC32 checksum.
* Outputs the checksum for each file given as a command line argument.
* Invalid file names and files that cause errors are silently skipped.
* The program reads from stdin if it is called with no arguments. */
uint32_t crc32_for_byte(uint32_t r) {
for(int j = 0; j < 8; ++j)
r = (r & 1? 0: (uint32_t)0xEDB88320L) ^ r >> 1;
return r ^ (uint32_t)0xFF000000L;
}
void crc32(const void *data, size_t n_bytes, uint32_t* crc) {
static uint32_t table[0x100];
if(!*table)
for(size_t i = 0; i < 0x100; ++i)
table[i] = crc32_for_byte(i);
for(size_t i = 0; i < n_bytes; ++i)
*crc = table[(uint8_t)*crc ^ ((uint8_t*)data)[i]] ^ *crc >> 8;
}
#define FGETS_BUF_LEN 4096
#define MAX_COMMAND_ARGS 42
#define PRINT_BYTES_PER_LINE 32
@ -23,6 +42,7 @@
char cmd_buf[FGETS_BUF_LEN];
bool is_tty;
int cmd_num = 0;
bool trace = false;
void prompt() {
printf("#%d> ", cmd_num);
@ -36,12 +56,29 @@ bool next_line() {
return fgets(cmd_buf, FGETS_BUF_LEN, stdin) != NULL;
}
char **split_args(char *s) {
int split_args(char *s, const char **argv) {
int argc = -1;
char **argv = (char**)malloc(sizeof(char*) * (MAX_COMMAND_ARGS + 1));
char *saveptr;
for ( ; (argv[++argc] = strtok_r(s, " \t\n", &saveptr)) != NULL; s = NULL );
return argv;
for ( ; (argv[++argc] = strtok(s, " \t\n")) != NULL; s = NULL );
return argc;
}
void kofu_disk_add(int argc, const 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);
}
return;
}
void kofu_disk_del(int argc, const char **argv) {
(void)argc;
const char *name = argv[1];
if (kos_disk_del(name)) {
printf("[!!] can't find or delete disk '%s'\n", name);
}
return;
}
void ls_range(struct f70s1arg *f70) {
@ -100,13 +137,14 @@ void ls_all(struct f70s1arg *f70) {
}
}
void kofu_ls(char **arg) {
void kofu_ls(int argc, const char **argv) {
(void)argc;
struct f70s1ret *dir = (struct f70s1ret*)malloc(sizeof(struct f70s1ret) + sizeof(struct bdfe) * MAX_DIRENTS_TO_READ);
struct f70s1arg f70 = {1, 0, CP866, MAX_DIRENTS_TO_READ, dir, 0, arg[1]};
if (arg[2]) {
sscanf(arg[2], "%"SCNu32, &f70.size);
if (arg[3]) {
sscanf(arg[3], "%"SCNu32, &f70.offset);
struct f70s1arg f70 = {1, 0, CP866, MAX_DIRENTS_TO_READ, dir, 0, argv[1]};
if (argv[2]) {
sscanf(argv[2], "%"SCNu32, &f70.size);
if (argv[3]) {
sscanf(argv[3], "%"SCNu32, &f70.offset);
}
ls_range(&f70);
} else {
@ -116,10 +154,11 @@ void kofu_ls(char **arg) {
return;
}
void kofu_stat(char **arg) {
void kofu_stat(int argc, const char **argv) {
(void)argc;
f70ret r;
struct bdfe file;
struct f70s5arg f70 = {5, 0, 0, 0, &file, 0, arg[1]};
struct f70s5arg f70 = {5, 0, 0, 0, &file, 0, argv[1]};
kos_fuse_lfn(&f70, &r);
printf("attr: 0x%2.2x\n", file.attr);
printf("size: %llu\n", file.size);
@ -177,13 +216,18 @@ void read_all(struct f70s0arg *f70) {
}
}
void kofu_read(char **arg) {
void kofu_read(int argc, const char **argv) {
(void)argc;
uint8_t *buf = (uint8_t*)malloc(MAX_BYTES_TO_READ);
struct f70s0arg f70 = {0, 0, 0, MAX_BYTES_TO_READ, buf, 0, arg[1]};
if (arg[2]) {
sscanf(arg[2], "%"SCNu32, &f70.size);
if (arg[3]) {
sscanf(arg[3], "%"SCNu32, &f70.offset_lo);
struct f70s0arg f70 = {0, 0, 0, MAX_BYTES_TO_READ, buf, 0, argv[1]};
// optind = 1;
// while ((opt = getopt(argc, argv, "fcshd:")) != -1) {
// switch (opt) {
// case
if (argv[2]) {
sscanf(argv[2], "%"SCNu32, &f70.size);
if (argv[3]) {
sscanf(argv[3], "%"SCNu32, &f70.offset_lo);
}
read_range(&f70);
} else {
@ -195,52 +239,70 @@ void kofu_read(char **arg) {
struct func_table {
char *name;
void (*func) (char **arg);
void (*func) (int, const char **);
};
struct func_table funcs[] = {
{ "disk_add", kofu_disk_add },
{ "disk_del", kofu_disk_del },
{ "ls", kofu_ls },
{ "stat", kofu_stat },
{ "read", kofu_read },
{ NULL, NULL },
};
void crc() {
uint8_t data[] = {1,2,3,4};
uint32_t x = 0;
crc32(data, 4, &x);
printf("crc=%"PRIx32"\n", x);
}
int main(int argc, char **argv) {
(void)argc;
(void)argv;
/*
if (argc != 2) {
printf("usage: kofu <file.xfs>\n");
exit(1);
}
*/
is_tty = isatty(STDIN_FILENO);
int fd = open(argv[1], O_RDONLY);
struct stat st;
fstat(fd, &st);
trace_begin();
if (!kos_fuse_init(fd, st.st_size / 512, 512)) {
exit(1);
if (trace) {
trace_begin();
}
kos_init();
// kos_disk_add(argv[1], "hd0");
// if (cio_init(argv[1])) {
// exit(1);
// }
//msg_file_not_found db 'file not found: '
while(next_line()) {
if (!is_tty) {
prompt();
printf("%s", cmd_buf);
fflush(stdout);
}
char **arg = split_args(cmd_buf);
const char **cargv = (const char**)malloc(sizeof(char*) * (MAX_COMMAND_ARGS + 1));
int cargc = split_args(cmd_buf, cargv);
bool found = false;
for (struct func_table *ft = funcs; ft->name != NULL; ft++) {
if (!strcmp(arg[0], ft->name)) {
if (!strcmp(cargv[0], ft->name)) {
found = true;
ft->func(arg);
ft->func(cargc, cargv);
cmd_num++;
break;
}
}
if (!found) {
printf("unknown command: %s\n", arg[0]);
printf("unknown command: %s\n", cargv[0]);
}
}
trace_end();
if (trace) {
trace_end();
}
return 0;
}

View File

@ -1,6 +1,6 @@
/*
Kofuse: KolibriOS kernel FS code as FUSE in Linux
Copyright (C) 2018 Ivan Baravy <dunkaist@gmail.com>
Copyright (C) 2018--2019 Ivan Baravy <dunkaist@gmail.com>
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
@ -27,6 +27,10 @@
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include "kolibri.h"
#define DIRENTS_TO_READ 100
@ -40,9 +44,9 @@ static void bdfe_to_stat(struct bdfe *kf, struct stat *st) {
st->st_nlink = 1;
st->st_size = kf->size;
}
st->st_atim = (struct timespec){ .tv_sec = kos_time_to_epoch(&(kf->atime)) };
st->st_mtim = (struct timespec){ .tv_sec = kos_time_to_epoch(&(kf->mtime)) };
st->st_ctim = (struct timespec){ .tv_sec = kos_time_to_epoch(&(kf->ctime)) };
st->st_atime = kos_time_to_epoch(&(kf->atime));
st->st_mtime = kos_time_to_epoch(&(kf->mtime));
st->st_ctime = kos_time_to_epoch(&(kf->ctime));
}
static void *kofuse_init(struct fuse_conn_info *conn,
@ -120,9 +124,7 @@ int main(int argc, char *argv[]) {
printf("usage: kofuse dir img\n");
exit(1);
}
int fd = open(argv[2], O_RDONLY);
struct stat st;
fstat(fd, &st);
kos_fuse_init(fd, st.st_size / 512, 512);
kos_init();
kos_disk_add(argv[2], "hd0");
return fuse_main(argc-1, argv, &kofuse_oper, NULL);
}

View File

@ -10,10 +10,7 @@ extrn free
free fix __free
_free fix free
macro coverage_magic_instruction {
nop
int3
}
sys_msg_board equ _sys_msg_board
purge section,mov,add,sub
purge section,mov,add,sub
@ -27,18 +24,19 @@ include 'proc32.inc'
include 'struct.inc'
include 'const.inc'
include 'system.inc'
include 'debug-fdo.inc'
include 'fdo.inc'
include 'blkdev/disk.inc'
include 'blkdev/disk_cache.inc'
include 'fs/fs_lfn.inc'
include 'crc.inc'
struct FILE_DISK
fd dd ?
Sectors dd ?
Logical dd ? ; sector size
struct VDISK
File dd ?
SectCnt dd ? ; FIXME: dq
SectSize dd ? ; sector size
ends
; TODO: move to trace_lbr
public set_eflags_tf
set_eflags_tf:
pushfd
@ -52,6 +50,7 @@ set_eflags_tf:
popfd
ret
; TODO: move to trace_lwp
public get_lwp_event_size
get_lwp_event_size:
mov eax, 0x80000001
@ -69,148 +68,146 @@ get_lwp_event_size:
xor eax, eax
ret
;uint32_t kos_time_to_epoch(uint8_t *time);
public kos_time_to_epoch
kos_time_to_epoch:
push ebx esi edi ebp
mov esi, [esp + 0x14]
public kos_time_to_epoch
proc kos_time_to_epoch c uses ebx esi edi ebp, _time
mov esi, [_time]
call fsCalculateTime
add eax, 978307200 ; epoch to 2001.01.01
pop ebp edi esi ebx
ret
endp
;void *kos_fuse_init(int fd, uint32_t sect_cnt, uint32_t sect_sz);
public kos_fuse_init
kos_fuse_init:
push ebx esi edi ebp
;DEBUGF 1, "coverage begin: 0x%x\n", coverage_begin
;DEBUGF 1, "xfs_create_partition: 0x%x\n", xfs_create_partition
;DEBUGF 1, "coverage end: 0x%x\n", coverage_end
public kos_init
proc kos_init c
MEMORY_BYTES = 128 SHL 20
mov [pg_data.mem_amount], MEMORY_BYTES
mov [pg_data.pages_count], MEMORY_BYTES / PAGE_SIZE
mov [pg_data.pages_free], MEMORY_BYTES / PAGE_SIZE
ret
endp
mov eax, [esp + 0x14]
mov [file_disk.fd], eax
mov eax, [esp + 0x18]
mov [file_disk.Sectors], eax
mov eax, [esp + 0x1c]
mov [file_disk.Logical], eax
stdcall disk_add, disk_functions, disk_name, file_disk, DISK_NO_INSERT_NOTIFICATION
public kos_disk_add
proc kos_disk_add c uses ebx esi edi ebp, _file_name, _disk_name
extrn cio_disk_init
ccall cio_disk_init, [_file_name]
stdcall disk_add, vdisk_functions, [_disk_name], eax, DISK_NO_INSERT_NOTIFICATION
push eax
stdcall disk_media_changed, eax, 1
pop eax
mov eax, [eax + DISK.NumPartitions]
pop ebp edi esi ebx
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
public kos_fuse_lfn
;proc kos_fuse_lfn c, _blah1, _blah2
kos_fuse_lfn:
proc kos_fuse_lfn c uses ebx edx esi edi ebp, _f70arg, _f70ret
push ebx
mov ebx, [esp + 8]
mov ebx, [_f70arg]
pushad ; file_system_lfn writes here
call file_system_lfn
popad
mov ecx, [esp + 12]
mov [ecx + 0], eax
mov [ecx + 4], ebx
mov ecx, [_f70ret]
mov [ecx+0], eax ; status
mov [ecx+4], ebx ; count
pop ebx
ret
;endp
endp
proc disk_read stdcall, userdata, buffer, startsector:qword, numsectors
pushad
mov eax, dword[startsector + 0] ; sector lo
mov edx, dword[startsector + 4] ; sector hi
mov edx, [userdata]
mul [edx + FILE_DISK.Logical]
mov ecx, edx
mov edx, eax
;DEBUGF 1, "lseek to: %x\n", edx
mov eax, [userdata]
mov ebx, [eax + FILE_DISK.fd]
sub esp, 8
mov esi, esp
mov edi, SEEK_SET
mov eax, SYS_LLSEEK
int 0x80
add esp, 8
;DEBUGF 1, "lseek: %x\n",eax
popad
proc vdisk_close stdcall uses ebx esi edi ebp, _userdata
extrn cio_disk_free
ccall cio_disk_free, [_userdata]
ret
endp
pushad
mov eax, [userdata]
mov ebx, [eax + FILE_DISK.fd]
mov ecx, [buffer]
mov edx, [numsectors]
mov edx, [edx]
imul edx, [eax + FILE_DISK.Logical]
mov eax, SYS_READ
int 0x80
;DEBUGF 1, "read: %d\n", eax
popad
proc vdisk_read stdcall uses ebx esi edi ebp, _userdata, _buffer, _startsector:qword, _numsectors
extrn cio_disk_read
ccall cio_disk_read, [_userdata], [_buffer], dword[_startsector+0], dword[_startsector+4], [_numsectors]
movi eax, DISK_STATUS_OK
ret
endp
proc disk_write stdcall, userdata, buffer, startsector:qword, numsectors
pushad
mov eax, dword[startsector + 0] ; sector lo
mov edx, dword[startsector + 4] ; sector hi
mov edx, [userdata]
mul [edx + FILE_DISK.Logical]
mov ecx, edx
mov edx, eax
;DEBUGF 1, "lseek to: %x\n", ecx
mov eax, [userdata]
mov ebx, [eax + FILE_DISK.fd]
sub esp, 8
mov esi, esp
mov edi, SEEK_SET
mov eax, SYS_LLSEEK
int 0x80
add esp, 8
;DEBUGF 1, "lseek: %x\n",eax
popad
pushad
mov eax, [userdata]
mov ebx, [eax + FILE_DISK.fd]
mov ecx, [buffer]
mov edx, [numsectors]
mov edx, [edx]
imul edx, [eax + FILE_DISK.Logical]
mov eax, SYS_WRITE
int 0x80
;DEBUGF 1, "write: %d\n", eax
popad
proc vdisk_write stdcall uses ebx esi edi ebp, userdata, buffer, startsector:qword, numsectors
extrn cio_disk_write
ccall cio_disk_write, [userdata], [buffer], dword[startsector+0], dword[startsector+4], [numsectors]
movi eax, DISK_STATUS_OK
ret
endp
; int querymedia(void* userdata, DISKMEDIAINFO* info);
proc disk_querymedia stdcall, hd_data, mediainfo
proc vdisk_querymedia stdcall uses ebx esi edi ebp, vdisk, mediainfo
mov ecx, [mediainfo]
mov edx, [hd_data]
mov edx, [vdisk]
mov [ecx + DISKMEDIAINFO.Flags], 0
mov eax, [edx + FILE_DISK.Logical]
mov eax, [edx + VDISK.SectSize]
mov [ecx + DISKMEDIAINFO.SectorSize], eax
mov eax, [edx + FILE_DISK.Sectors]
mov dword [ecx + DISKMEDIAINFO.Capacity], eax
mov eax, [edx + VDISK.SectCnt]
mov dword [ecx + DISKMEDIAINFO.Capacity + 0], eax
mov dword [ecx + DISKMEDIAINFO.Capacity + 4], 0
movi eax, DISK_STATUS_OK
@ -218,11 +215,12 @@ proc disk_querymedia stdcall, hd_data, mediainfo
endp
__malloc:
proc __malloc
push ecx edx
ccall _malloc, eax
pop edx ecx
ret
endp
proc kernel_alloc _size
@ -238,6 +236,7 @@ proc alloc_kernel_space _size
ret
endp
proc alloc_pages _cnt
mov eax, [_cnt]
shl eax, 12
@ -246,9 +245,10 @@ proc alloc_pages _cnt
endp
__free:
proc __free
ccall _free, eax
ret
endp
proc kernel_free base
@ -259,7 +259,9 @@ proc kernel_free base
endp
put_board:
proc _sys_msg_board
cmp cl, 0x0d
jz @f
pushad
mov eax, SYS_WRITE
mov ebx, STDOUT
@ -269,7 +271,10 @@ put_board:
int 0x80
pop ecx
popad
ret
@@:
ret
endp
align 16 ;very often call this subrutine
memmove: ; memory move in bytes
@ -329,23 +334,22 @@ public coverage_end
section '.data' writeable align 16
include_debug_strings
disk_functions:
dd disk_functions_end - disk_functions
dd 0
dd 0
dd disk_querymedia
dd disk_read
dd disk_write
dd 0
dd 0
disk_functions_end:
vdisk_functions:
dd vdisk_functions_end - vdisk_functions
dd 0;vdisk_close ; close
dd 0 ; closemedia
dd vdisk_querymedia
dd vdisk_read
dd vdisk_write
dd 0 ; flush
dd 0 ; adjust_cache_size
vdisk_functions_end:
disk_name db 'hd0',0
IncludeIGlobals
section '.bss' writeable align 16
file_disk FILE_DISK
IncludeUGlobals
; crap
DiskNumber db ?

View File

@ -10,7 +10,7 @@ enum encoding {
UTF8,
};
enum f70status {
typedef enum {
F70_SUCCESS,
F70_DISK_BASE,
F70_UNSUPPORTED_FS,
@ -24,7 +24,7 @@ enum f70status {
F70_ACCESS_DENIED,
F70_DEVICE,
F70_OUT_OF_MEMORY,
};
} f70status;
typedef struct {
uint32_t status;
@ -92,6 +92,10 @@ uint32_t kos_time_to_epoch(uint32_t *time);
void *kos_fuse_init(int fd, uint32_t sect_cnt, uint32_t sect_sz);
void kos_fuse_lfn(void *f70arg, f70ret *r);
void kos_init(void);
void *kos_disk_add(const char *file_name, const char *disk_name);
int kos_disk_del(const char *name);
void set_eflags_tf(int x);
void coverage_begin(void);
void coverage_end(void);

View File

@ -1,16 +1,16 @@
FASM=fasm
CC=gcc
CFLAGS=-Wall -Wextra -g -O0 -D_LARGEFILE64_SOURCE
CFLAGS_32=-m32 -D_FILE_OFFSET_BITS=64
CFLAGS=-Wall -Wextra -g -O0 -D_FILE_OFFSET_BITS=64
CFLAGS_32=-m32
LDFLAGS=
LDFLAGS_32=-m32
all: kofu kofuse kolibri.sym kolibri.lst tools/mkdirrange tools/mkfilepattern
kofu: kofu.o kolibri.o trace.o trace_lbr.o trace_lwp.o
kofu: kofu.o kolibri.o trace.o trace_lbr.o trace_lwp.o cio.o
$(CC) $(LDFLAGS) $(LDFLAGS_32) $^ -o $@ -static
kofuse: kofuse.o kolibri.o
kofuse: kofuse.o kolibri.o cio.o
$(CC) $(LDFLAGS) $(LDFLAGS_32) $^ -o $@ `pkg-config fuse3 --libs`
kolibri.o kolibri.fas: kolibri.asm kolibri.h
@ -31,11 +31,14 @@ trace_lbr.o: trace_lbr.c trace_lbr.h kolibri.h
trace_lwp.o: trace_lwp.c trace_lwp.h kolibri.h
$(CC) $(CFLAGS) $(CFLAGS_32) -c $<
kofu.o: kofu.c kolibri.h
cio.o: cio.c
$(CC) $(CFLAGS) $(CFLAGS_32) -c $<
kofu.o: kofu.c kolibri.h trace.h
$(CC) $(CFLAGS) $(CFLAGS_32) -c $< -std=c99
kofuse.o: kofuse.c kolibri.h
$(CC) $(CFLAGS) $(CFLAGS_32) `pkg-config fuse3 --cflags` -c $<
$(CC) $(CFLAGS) $(CFLAGS_32) `pkg-config fuse3 --cflags` -c $< -std=gnu99
tools/mkdirrange: tools/mkdirrange.c
$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@

View File

@ -1,5 +1,7 @@
disk_add ../img/s512_xfs_v4_ftype0.img hd0
ls /hd0/1/sf
ls /hd0/1/block
ls /hd0/1/leaf
ls /hd0/1/node
ls /hd0/1/btree
disk_del hd0

View File

@ -1,11 +1,13 @@
#0> ls /hd0/1/sf
#0> disk_add ../img/s512_xfs_v4_ftype0.img hd0
/hd0/1: xfs
#1> ls /hd0/1/sf
status = 6, count = 5
.
..
d0000000000_
d0000000001_x
d0000000002_xx
#1> ls /hd0/1/block
#2> ls /hd0/1/block
status = 6, count = 22
.
..
@ -29,7 +31,7 @@ d0000000016_xxxxxxxxxxxxxxxx
d0000000017_xxxxxxxxxxxxxxxxx
d0000000018_xxxxxxxxxxxxxxxxxx
d0000000019_xxxxxxxxxxxxxxxxxxx
#2> ls /hd0/1/leaf
#3> ls /hd0/1/leaf
status = 6, count = 72
.
..
@ -103,7 +105,7 @@ d0000000066_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
d0000000067_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
d0000000068_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
d0000000069_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
#3> ls /hd0/1/node
#4> ls /hd0/1/node
status = 0, count = 100
.
..
@ -632,7 +634,7 @@ d0000000516_xxxxxxxxxxxxxxxxxxxxxxxxxxxx
d0000000517_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
d0000000518_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
d0000000519_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
#4> ls /hd0/1/btree
#5> ls /hd0/1/btree
status = 0, count = 100
.
..
@ -1242,3 +1244,4 @@ d0000000597_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
status = 6, count = 2
d0000000598_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
d0000000599_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
#6> disk_del hd0

View File

@ -1,5 +1,7 @@
disk_add ../img/s512_xfs_v4_ftype1.img hd0
ls /hd0/1/sf
ls /hd0/1/block
ls /hd0/1/leaf
ls /hd0/1/node
ls /hd0/1/btree
disk_del hd0

View File

@ -1,11 +1,13 @@
#0> ls /hd0/1/sf
#0> disk_add ../img/s512_xfs_v4_ftype1.img hd0
/hd0/1: xfs
#1> ls /hd0/1/sf
status = 6, count = 5
.
..
d0000000000_
d0000000001_x
d0000000002_xx
#1> ls /hd0/1/block
#2> ls /hd0/1/block
status = 6, count = 22
.
..
@ -29,7 +31,7 @@ d0000000016_xxxxxxxxxxxxxxxx
d0000000017_xxxxxxxxxxxxxxxxx
d0000000018_xxxxxxxxxxxxxxxxxx
d0000000019_xxxxxxxxxxxxxxxxxxx
#2> ls /hd0/1/leaf
#3> ls /hd0/1/leaf
status = 6, count = 72
.
..
@ -103,7 +105,7 @@ d0000000066_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
d0000000067_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
d0000000068_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
d0000000069_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
#3> ls /hd0/1/node
#4> ls /hd0/1/node
status = 0, count = 100
.
..
@ -632,7 +634,7 @@ d0000000516_xxxxxxxxxxxxxxxxxxxxxxxxxxxx
d0000000517_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
d0000000518_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
d0000000519_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
#4> ls /hd0/1/btree
#5> ls /hd0/1/btree
status = 0, count = 100
.
..
@ -1242,3 +1244,4 @@ d0000000597_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
status = 6, count = 2
d0000000598_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
d0000000599_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
#6> disk_del hd0

View File

@ -0,0 +1,7 @@
disk_add ../img/s512_xfs_v4_ftype0_b4k_n2b.img hd0
ls /hd0/1/sf
ls /hd0/1/block
ls /hd0/1/leaf
ls /hd0/1/node
ls /hd0/1/btree
disk_del hd0

File diff suppressed because it is too large Load Diff

View File

@ -25,7 +25,7 @@ int main(int argc, char *argv[])
sscanf(argv[2], "%" SCNi64, &len);
}
int fd = open(path, O_CREAT | O_LARGEFILE | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
int fd = open(path, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd == -1) {
fprintf(stderr, "Can't open %s: %s\n", path, strerror(errno));
exit(1);
@ -36,7 +36,7 @@ int main(int argc, char *argv[])
count = len - pos;
}
off64_t off = 0;
off_t off = 0;
while (off < count) {
if (pos + off < 0x100) {
*(uint8_t*)(buf + off) = (uint8_t)(pos + off);