diff --git a/.gitignore b/.gitignore index 4664212..78be7a0 100644 --- a/.gitignore +++ b/.gitignore @@ -41,5 +41,6 @@ t.d *.exe colors.dtp .tup -board_hello -board_cycle +apps/board_hello +apps/board_cycle +apps/readdir diff --git a/apps/makefile b/apps/makefile index 6d21e8f..95cb1aa 100644 --- a/apps/makefile +++ b/apps/makefile @@ -11,7 +11,7 @@ else $(error your OS is not supported) endif -all: board_hello board_cycle +all: board_hello board_cycle readdir %: %.asm $(FASM) $< $@ @@ -20,4 +20,4 @@ all: board_hello board_cycle .PHONY: all clean clean: - rm -f board_hello board_cycle + rm -f board_hello board_cycle readdir diff --git a/apps/readdir.asm b/apps/readdir.asm new file mode 100644 index 0000000..3ec49a4 --- /dev/null +++ b/apps/readdir.asm @@ -0,0 +1,45 @@ +use32 + org 0 + db 'MENUET01' + dd 1, start, i_end, e_end, e_end, 0, 0 + +__DEBUG__ = 1 +__DEBUG_LEVEL__ = 1 + +include 'proc32.inc' +include 'macros.inc' +include 'debug-fdo.inc' + +EFLAGS.ID = 1 SHL 21 + +start: + pushfd + btr dword[esp], BSF EFLAGS.ID + popfd + + DEBUGF 1, "abcde\n" + mcall 70, fs70 + DEBUGF 1, "files in dir: %d\n", ebx + mcall -1 +exit: +; mcall 18, 9, 2 + mcall -1 + mcall -2 ; just to check it's unreachable + +include_debug_strings +fs70: +.sf dd 1 + dd 0 + dd 0 + dd 42 + dd dir_buf + db 0 + dd dir_name + +dir_name db '/hd0/1/',0 +i_end: +dir_buf: +rb 0x10000 + +rb 0x100 ; stack +e_end: diff --git a/makefile b/makefile index 9811687..bb05fe4 100644 --- a/makefile +++ b/makefile @@ -66,7 +66,7 @@ umka_fuse: umka_fuse.o umka.o trace.o trace_lbr.o vdisk.o vdisk/raw.o \ umka_os: umka_os.o umka.o shell.o lodepng.o vdisk.o vdisk/raw.o vdisk/qcow2.o \ vdisk/miniz/miniz.a vnet.o trace.o trace_lbr.o $(HOST)/pci.o \ - $(HOST)/thread.o util.o bestline.o + $(HOST)/thread.o util.o bestline.o optparse.o $(CC) $(LDFLAGS_32) $^ -o $@ -T umka.ld umka_gen_devices_dat: umka_gen_devices_dat.o umka.o $(HOST)/pci.o \ diff --git a/umka.asm b/umka.asm index 6555c24..4b3d25e 100644 --- a/umka.asm +++ b/umka.asm @@ -175,6 +175,11 @@ pubsym acpi_dev_size, "kos_acpi_dev_size" pubsym acpi_dev_next, "kos_acpi_dev_next" pubsym kernel_alloc, "kos_kernel_alloc" +pubsym create_event, "_kos_create_event" +pubsym destroy_event, "_kos_destroy_event" +pubsym wait_event, "_kos_wait_event" +pubsym Wait_events, "_kos_wait_events" + pubsym window._.set_screen, 'kos_window_set_screen' pubsym _display, 'kos_display' diff --git a/umka.h b/umka.h index 7239e7f..4bc7b81 100644 --- a/umka.h +++ b/umka.h @@ -63,6 +63,24 @@ enum kos_lang { #define EVENT_NETWORK2 0x0200 #define EVENT_EXTENDED 0x0400 +#define KOS_APP_BASE 0 +#define MENUET01_MAGIC "MENUET01" + +struct app_hdr { + union { + struct { + char magic[8]; + uint32_t version; + uint32_t start; + uint32_t i_end; + uint32_t mem_size; + uint32_t stack_top; + uint32_t i_param; + uint32_t i_icon; + } menuet; + }; +}; + struct point16s { int16_t y, x; }; @@ -567,6 +585,69 @@ kos_attach_int_handler(int irq, int (*handler)(void*), void *user_data); void kos_irq_serv_irq10(void); +struct ret_create_event { + uint32_t event; // (=0 => fail) + uint32_t uid; +}; + +static inline struct ret_create_event +kos_create_event(void *data, uint32_t flags) { + struct ret_create_event ret; + __asm__ __inline__ __volatile__ ( + "push ebx esi edi ebp;" + "call _kos_create_event;" + "pop ebp edi esi ebx" + : "=a"(ret.event), + "=d"(ret.uid) + : "S"(data), + "c"(flags) + : "memory", "cc"); + return ret; +} + +static inline void* +kos_destroy_event(void *event, uint32_t uid) { + void *ret; + __asm__ __inline__ __volatile__ ( + "push ebx esi edi ebp;" + "call _kos_destroy_event;" + "pop ebp edi esi ebx" + : "=a"(ret) + : "a"(event), + "b"(uid) + : "memory", "cc"); + return ret; + +} + +static inline void +kos_wait_event(void *event, uint32_t uid) { + __asm__ __inline__ __volatile__ ( + "push ebx esi edi ebp;" + "call _kos_wait_event;" + "pop ebp edi esi ebx" + : + : "a"(event), + "b"(uid) + : "memory", "cc"); +} + +typedef uint32_t (*wait_test_t)(void *); + +static inline void* +kos_wait_events(wait_test_t wait_test, void *wait_param) { + void *res; + __asm__ __inline__ __volatile__ ( + "push ebx esi edi ebp;" + "call _kos_wait_events;" + "pop ebp edi esi ebx" + : "=a"(res) + : "c"(wait_param), + "d"(wait_test) + : "memory", "cc"); + return res; +} + static inline int32_t umka_fs_execute(const char *filename) { // edx Flags diff --git a/umka_os.c b/umka_os.c index de1b5f3..5f6e090 100644 --- a/umka_os.c +++ b/umka_os.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #define __USE_GNU #include @@ -24,27 +25,43 @@ #include #include #include "umka.h" +#include "optparse.h" #include "shell.h" #include "trace.h" #include "vnet.h" +#define HIST_FILE_BASENAME ".umka_shell.history" #define UMKA_DEFAULT_DISPLAY_WIDTH 400 #define UMKA_DEFAULT_DISPLAY_HEIGHT 300 #define THREAD_STACK_SIZE 0x100000 +char history_filename[PATH_MAX]; + +void build_history_filename() { + const char *dir_name; + if (!(dir_name = getenv("HOME"))) { + dir_name = "."; + } + sprintf(history_filename, "%s/%s", dir_name, HIST_FILE_BASENAME); +} + +/* static void monitor(void) { umka_sti(); fprintf(stderr, "Start monitor thread\n"); __asm__ __inline__ __volatile__ ("jmp $"); } +*/ void umka_thread_net_drv(void); struct itimerval timeout = {.it_value = {.tv_sec = 0, .tv_usec = 10000}, .it_interval = {.tv_sec = 0, .tv_usec = 10000}}; +typedef void (*kos_thread_t)(void); + static void thread_start(int is_kernel, void (*entry)(void), size_t stack_size) { fprintf(stderr, "### thread_start: %p\n", (void*)(uintptr_t)entry); @@ -55,7 +72,7 @@ thread_start(int is_kernel, void (*entry)(void), size_t stack_size) { static void dump_procs() { for (int i = 0; i < NR_SCHED_QUEUES; i++) { - printf("sched queue #%i:", i); + fprintf(stderr, "sched queue #%i:", i); appdata_t *p_begin = kos_scheduler_current[i]; appdata_t *p = p_begin; do { @@ -73,7 +90,7 @@ load_app_host(const char *fname, void *base) { perror("Can't open app file"); exit(1); } - fread(base, 1, 0x4000, f); + fread(base, 1, 0x100000, f); fclose(f); for (size_t i = 0; i < 0x64; i++) { @@ -113,20 +130,56 @@ void handle_irq_net(int signo, siginfo_t *info, void *context) { } int -main() { - if (coverage) +main(int argc, char *argv[]) { + (void)argc; + const char *usage = "umka_os [-i ] [-o ]\n"; + if (coverage) { trace_begin(); + } umka_tool = UMKA_OS; umka_sti(); + const char *infile = NULL, *outfile = NULL; + struct shell_ctx ctx = {.reproducible = 0, .hist_file = history_filename, + .var = NULL}; + build_history_filename(); + + struct optparse options; + int opt; + optparse_init(&options, argv); + + while ((opt = optparse(&options, "i:o:")) != -1) { + switch (opt) { + case 'i': + infile = options.optarg; + break; + case 'o': + outfile = options.optarg; + break; + default: + fprintf(stderr, "bad option: %c\n", opt); + fputs(usage, stderr); + exit(1); + } + } + + if (infile && !freopen(infile, "r", stdin)) { + fprintf(stderr, "[!] can't open file for reading: %s\n", infile); + exit(1); + } + if (outfile && !freopen(outfile, "w", stdout)) { + fprintf(stderr, "[!] can't open file for writing: %s\n", outfile); + exit(1); + } + struct sigaction sa; sa.sa_sigaction = irq0; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_SIGINFO; if (sigaction(SIGPROF, &sa, NULL) == -1) { - printf("Can't install SIGPROF handler!\n"); + fprintf(stderr, "Can't install SIGPROF handler!\n"); return 1; } @@ -135,7 +188,7 @@ main() { sa.sa_flags = SA_SIGINFO; if (sigaction(SIGSEGV, &sa, NULL) == -1) { - printf("Can't install SIGSEGV handler!\n"); + fprintf(stderr, "Can't install SIGSEGV handler!\n"); return 1; } @@ -144,14 +197,13 @@ main() { sa.sa_flags = SA_SIGINFO; if (sigaction(SIGUSR1, &sa, NULL) == -1) { - printf("Can't install SIGUSR1 handler!\n"); + fprintf(stderr, "Can't install SIGUSR1 handler!\n"); return 1; } - void *app_base = mmap((void*)0, 16*0x100000, PROT_READ | PROT_WRITE | - PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, - -1, 0); - if (app_base == MAP_FAILED) { + struct app_hdr *app = mmap(KOS_APP_BASE, 16*0x100000, PROT_READ | PROT_WRITE | + PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (app == MAP_FAILED) { perror("mmap failed"); exit(1); } @@ -163,15 +215,11 @@ main() { kos_boot.y_res = UMKA_DEFAULT_DISPLAY_HEIGHT; kos_boot.pitch = UMKA_DEFAULT_DISPLAY_WIDTH*4; // 32bpp - umka_init(); + run_test(&ctx); // umka_stack_init(); - FILE *f = fopen("../img/kolibri.raw", "r"); - fread(kos_ramdisk, 2880*512, 1, f); - fclose(f); - kos_ramdisk_init(); -// load_app_host("../apps/board_cycle", app_base); - load_app_host("../apps/lsdir", app_base); +// load_app_host("../apps/board_cycle", app); + load_app_host("../apps/readdir", app); // load_app("/rd/1/loader"); // net_device_t *vnet = vnet_init(); @@ -214,7 +262,8 @@ main() { */ // thread_start(0, monitor, THREAD_STACK_SIZE); - thread_start(0, app_base, THREAD_STACK_SIZE); + kos_thread_t start = (kos_thread_t)(KOS_APP_BASE + app->menuet.start); + thread_start(0, start, THREAD_STACK_SIZE); dump_procs(); diff --git a/umka_os.us b/umka_os.us new file mode 100644 index 0000000..23d7e11 --- /dev/null +++ b/umka_os.us @@ -0,0 +1,3 @@ +umka_init +ramdisk_init ../img/kolibri.raw +disk_add ../img/xfs_samehash_s05k.raw hd0 -c 0