From d479f8a1210c186ab16751c175f88bd19838e917 Mon Sep 17 00:00:00 2001 From: Ivan Baravy Date: Tue, 24 May 2022 23:22:12 +0400 Subject: [PATCH] umka_os: Load very basic userspace KolibriOS app --- .gitignore | 1 + apps/hello_board.asm | 23 ++++++++++++++++++ apps/makefile | 23 ++++++++++++++++++ linux/thread.c | 7 +++++- makefile | 8 +++--- shell.c | 6 +---- umka.asm | 18 +++++++++----- umka.ld | 23 +++++++++++++++--- umka_os.c | 58 +++++++++++++++++++++++++++++++++++++++++--- umka_ping.c | 1 + 10 files changed, 145 insertions(+), 23 deletions(-) create mode 100644 apps/hello_board.asm create mode 100644 apps/makefile diff --git a/.gitignore b/.gitignore index ea32504..2f5bac2 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,4 @@ t.d *.exe colors.dtp .tup +hello_board diff --git a/apps/hello_board.asm b/apps/hello_board.asm new file mode 100644 index 0000000..bf06885 --- /dev/null +++ b/apps/hello_board.asm @@ -0,0 +1,23 @@ +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' + +start: + DEBUGF 1, "Hello board\n" +exit: + mcall 18, 9, 2 + mcall -1 + mcall -2 ; just to check it's unreachable + +include_debug_strings +i_end: +rb 0x100 ;stack +e_end: diff --git a/apps/makefile b/apps/makefile new file mode 100644 index 0000000..69b6aea --- /dev/null +++ b/apps/makefile @@ -0,0 +1,23 @@ +FASM_EXE ?= fasm +FASM_FLAGS=-dUMKA=1 + +ifeq ($(HOST),linux) + FASM_INCLUDE=$(KOLIBRIOS)/programs + FASM=INCLUDE="$(FASM_INCLUDE)" $(FASM_EXE) $(FASM_FLAGS) +else ifeq ($(HOST),windows) + FASM_INCLUDE=$(KOLIBRIOS)\programs + FASM=set "INCLUDE=$(FASM_INCLUDE)" && $(FASM_EXE) $(FASM_FLAGS) +else + $(error your OS is not supported) +endif + +all: hello_board + +%: %.asm + $(FASM) $< $@ + + +.PHONY: all clean + +clean: + rm -f hello_board diff --git a/linux/thread.c b/linux/thread.c index ea7d59d..3390d08 100644 --- a/linux/thread.c +++ b/linux/thread.c @@ -2,6 +2,7 @@ #define __USE_GNU #include #include +#include sigset_t mask; @@ -12,6 +13,10 @@ void reset_procmask(void) { } int get_fake_if(ucontext_t *ctx) { - // we fake IF with id flag + // we fake IF with ID flag return !(ctx->uc_mcontext.__gregs[REG_EFL] & (1 << 21)); } + +void system_shutdown() { + exit(0); +} diff --git a/makefile b/makefile index 9fd57f1..20c34e1 100644 --- a/makefile +++ b/makefile @@ -7,7 +7,6 @@ ifndef HOST endif FASM_EXE ?= fasm -FASM_INCLUDE=$(KOLIBRIOS)/kernel/trunk;$(KOLIBRIOS)/programs/develop/libraries/libcrash/hash FASM_FLAGS=-dUEFI=1 -dextended_primary_loader=1 -dUMKA=1 -dHOST=$(HOST) -m 2000000 CC ?= gcc @@ -78,7 +77,7 @@ umka_gen_devices_dat: umka_gen_devices_dat.o umka.o pci.o thread.o util.o umka.o umka.fas: umka.asm $(FASM) $< umka.o -s umka.fas -shell.o: shell.c +shell.o: shell.c lodepng.h $(CC) $(CFLAGS_32) -c $< thread.o: $(HOST)/thread.c @@ -90,6 +89,9 @@ pci.o: $(HOST)/pci.c lodepng.o: lodepng.c lodepng.h $(CC) $(CFLAGS_32) -c $< +#bestline.o: bestline.c bestline.h +# $(CC) $(CFLAGS_32) -U_POSIX_C_SOURCE -Wno-logical-op -Wno-switch-enum -c $< + getopt.o: getopt.c getopt.h $(CC) $(CFLAGS_32) -c $< @@ -136,7 +138,7 @@ umka_fuse.o: umka_fuse.c umka.h $(CC) $(CFLAGS_32) `pkg-config fuse3 --cflags` -c $< umka_os.o: umka_os.c umka.h - $(CC) $(CFLAGS_32) -c $< -D_XOPEN_SOURCE=600 + $(CC) $(CFLAGS_32) -c $< umka_gen_devices_dat.o: umka_gen_devices_dat.c umka.h $(CC) $(CFLAGS_32) -c $< diff --git a/shell.c b/shell.c index 9c213cc..03c0442 100644 --- a/shell.c +++ b/shell.c @@ -223,13 +223,9 @@ next_line(int is_tty, int block) { FD_SET(fileno(fin), &readfds); struct timeval timeout = {.tv_sec = 0, .tv_usec = 0}; int sr = select(fileno(fin)+1, &readfds, NULL, NULL, &timeout); + cmd_buf[0] = '\0'; if (sr > 0) { fgets(cmd_buf, FGETS_BUF_LEN, fin); - if (cmd_buf[0] == EOF) { - cmd_buf[0] = '\0'; - } - } else { - cmd_buf[0] = '\0'; } return 1; } diff --git a/umka.asm b/umka.asm index c32db39..de54beb 100644 --- a/umka.asm +++ b/umka.asm @@ -164,15 +164,17 @@ pubsym _display, 'kos_display' pubsym BOOT, 'kos_boot' +EFLAGS.ID = 1 SHL 21 + macro cli { pushfd - bts dword[esp], 21 + bts dword[esp], BSF EFLAGS.ID popfd } macro sti { pushfd - btr dword[esp], 21 + btr dword[esp], BSF EFLAGS.ID popfd } @@ -188,6 +190,9 @@ macro int n { end if } +section '.app' executable writable align 64 +rb 64*1024 + section '.text' executable align 64 coverage_begin: @@ -286,7 +291,7 @@ include 'core/taskman.inc' include 'core/dll.inc' macro call target { if target eq pci_read_reg - call _pci_read_reg + call _pci_read_reg else call target end if @@ -603,7 +608,7 @@ proc umka_init c uses ebx esi edi ebp sub [edx+APPDATA.saved_esp], 4 mov eax, [edx+APPDATA.saved_esp] mov dword[eax], 0 - xor ecx, ecx + movi ecx, MAX_PRIORITY call scheduler_add_thread mov [current_slot_idx], 2 @@ -720,7 +725,7 @@ proc irq0 c, _signo, _info, _context inc [timer_ticks] call updatecputimes - ccall reset_procmask + ccall reset_procmask ; kind of irq_eoi:ta ccall get_fake_if, [_context] test eax, eax jnz @f @@ -760,6 +765,8 @@ proc map_io_mem _base, _size, _flags ret endp +extrn system_shutdown + sysfn_saveramdisk: sysfn_meminfo: check_fdd_motor_status: @@ -767,7 +774,6 @@ check_ATAPI_device_event: check_fdd_motor_status_has_work?: check_ATAPI_device_event_has_work?: request_terminate: -system_shutdown: terminate: LoadMedium: clear_CD_cache: diff --git a/umka.ld b/umka.ld index 4aea2ad..9b6cc39 100644 --- a/umka.ld +++ b/umka.ld @@ -1,7 +1,23 @@ +/* +MEMORY +{ + pew : ORIGIN = 0, LENGTH = 64K +} + SECTIONS { - . = ALIGN(65536); - .data.aligned : + .aou 0: + { + *(.app) + } : NONE + +} +INSERT BEFORE .interp; +*/ + +SECTIONS +{ + .data.aligned BLOCK(65536) : { *(SORT_BY_NAME(.data.align*)) } @@ -11,8 +27,7 @@ INSERT AFTER .data; SECTIONS { - . = ALIGN(65536); - .bss.aligned : + .bss.aligned BLOCK(65536) : { *(SORT_BY_NAME(.bss.align*)) } diff --git a/umka_os.c b/umka_os.c index 238a8b3..de773ba 100644 --- a/umka_os.c +++ b/umka_os.c @@ -19,10 +19,12 @@ #include #include +#define __USE_GNU #include #include #include #include +#define __USE_MISC #include #include #include @@ -97,6 +99,43 @@ void new_monitor(void) { } */ +struct app_menuet { + char signature[8]; // MENUETXX + uint32_t version; // 1 + void (*start) (void); // start +}; + +int +load_app(const char *fname, void *base) { + FILE *f = fopen(fname, "r"); + if (!f) { + perror("Can't open app file"); + exit(1); + } + fread(base, 1, 0x4000, f); + fclose(f); + + for (size_t i = 0; i < 0x64; i++) { + fprintf(stderr, "%2.2hx ", ((uint8_t*)base)[i]); + } + fprintf(stderr, "\n"); + + return 0; +} + +void handle_i40(int signo, siginfo_t *info, void *context) { + (void)signo; + (void)info; + ucontext_t *ctx = context; + void *ip = (void*)ctx->uc_mcontext.__gregs[REG_EIP]; + int eax = ctx->uc_mcontext.__gregs[REG_EAX]; + if (*(uint16_t*)ip == 0x40cd) { + ctx->uc_mcontext.__gregs[REG_EIP] += 2; // skip int 0x40 + } + printf("i40: %i %p\n", eax, ip); + umka_i40((pushad_t*)(ctx->uc_mcontext.__gregs + REG_EDI)); +} + int main() { if (coverage) @@ -111,19 +150,29 @@ main() { sa.sa_flags = SA_SIGINFO; if (sigaction(SIGPROF, &sa, NULL) == -1) { - printf("Can't install signal handler!\n"); + printf("Can't install SIGPROF handler!\n"); return 1; } -/* - void *app_base = mmap((void*)0x000000, 16*0x100000, PROT_READ | PROT_WRITE | + sa.sa_sigaction = handle_i40; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + + if (sigaction(SIGSEGV, &sa, NULL) == -1) { + printf("Can't install SIGSEGV 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) { perror("mmap failed"); exit(1); } -*/ + + load_app("../apps/hello_board", app_base); + printf("pid=%d, kos_lfb_base=%p\n", getpid(), (void*)kos_lfb_base); kos_boot.bpp = 32; @@ -136,6 +185,7 @@ main() { thread_start(0, monitor, THREAD_STACK_SIZE); thread_start(0, umka_thread_net_drv, THREAD_STACK_SIZE); + thread_start(0, ((struct app_menuet*)app_base)->start, THREAD_STACK_SIZE); // thread_start(0, umka_thread_ping, THREAD_STACK_SIZE); setitimer(ITIMER_PROF, &timeout, NULL); diff --git a/umka_ping.c b/umka_ping.c index bb74008..917b5cc 100644 --- a/umka_ping.c +++ b/umka_ping.c @@ -84,6 +84,7 @@ int go_ping = 0; void umka_thread_ping(void) { umka_sti(); + fprintf(stderr, "[ping] starting\n"); while (!go_ping) { /* wait until initialized */ } f75ret_t r75;