From ae9c2198b691272ba4a4279ca1c330067bacd6f1 Mon Sep 17 00:00:00 2001 From: Ivan Baravy Date: Sat, 10 Oct 2020 02:30:52 +0300 Subject: [PATCH] Make umka_os use scheduler from KolibriOS kernel! Also, * Add more syscall wrappers; * Replace puts(usage) with fputs(usage, fout); * Remove some dead code. --- .gitignore | 1 + linux/thread.c | 47 +++++------- linux/thread.h | 8 -- makefile | 13 +++- shell.c | 94 +++++++++++------------ umka.asm | 164 +++++++++++++++++++++------------------ umka.h | 96 ++++++++++++++++++++++- umka_os.c | 48 +++--------- umka_ping.c | 204 +++++++++++++++++++++++++++++++++++++++++++++++++ vnet.c | 16 +++- vnet.h | 4 +- 11 files changed, 486 insertions(+), 209 deletions(-) delete mode 100644 linux/thread.h create mode 100644 umka_ping.c diff --git a/.gitignore b/.gitignore index 3a2137e..920372e 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ umka_shell umka_fuse umka_os +umka_ping mkdirrange mkfilepattern *.img diff --git a/linux/thread.c b/linux/thread.c index e84eca4..5691597 100644 --- a/linux/thread.c +++ b/linux/thread.c @@ -1,35 +1,24 @@ -#include #include +#define __USE_GNU +#include +#include #include -#include -#include "../umka.h" +#include -sigjmp_buf trampoline; +sigset_t mask; +struct itimerval timeout = {.it_value = {.tv_sec = 0, .tv_usec = 10000}}; -__attribute__((__stdcall__)) -uint32_t umka_sched_add_thread(appdata_t *app) { -// fprintf(stderr, "umka_new_sys_threads before\n"); -// fprintf(stderr, "kos_task_count: %d\n", kos_task_count); - if (!sigsetjmp(trampoline, 1)) { - __asm__ __inline__ __volatile__ ( - "pushfd;" - "bts dword ptr [esp], 21;" - "popfd;" - "mov esp, eax" - : - : "a"(app->saved_esp) - : "memory"); - if (!sigsetjmp(*app->fpu_state, 1)) { - longjmp(trampoline, 1); - } else { - __asm__ __inline__ __volatile__ ( - "ret" - : - : - : "memory"); - } - } -// fprintf(stderr, "umka_new_sys_threads after\n"); - return 0; +void reset_procmask(void) { + sigemptyset (&mask); + sigaddset (&mask, SIGPROF); + sigprocmask(SIG_UNBLOCK, &mask, NULL); } +int get_fake_if(ucontext_t *ctx) { + // we fake IF with id flag + return ctx->uc_mcontext.__gregs[REG_EFL] & (1 << 21); +} + +void restart_timer(void) { + setitimer(ITIMER_PROF, &timeout, NULL); +} diff --git a/linux/thread.h b/linux/thread.h deleted file mode 100644 index 6ef8c18..0000000 --- a/linux/thread.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef THREAD_H_INCLUDED -#define THREAD_H_INCLUDED - -#include - -uint32_t umka_new_sys_threads(void (*func)(void), void *stack, int type); - -#endif // THREAD_H_INCLUDED diff --git a/makefile b/makefile index 4f585ca..10d5b90 100644 --- a/makefile +++ b/makefile @@ -1,4 +1,4 @@ -FASM=fasm +FASM=fasm -dUEFI=1 -dextended_primary_loader=1 CC=gcc WARNINGS=-Wall -Wextra -Wduplicated-cond -Wduplicated-branches -Wlogical-op \ -Wrestrict -Wnull-dereference -Wjump-misses-init -Wshadow -Wformat=2 \ @@ -11,7 +11,7 @@ CFLAGS_32=$(CFLAGS) -m32 LDFLAGS= LDFLAGS_32=$(LDFLAGS) -m32 -all: umka_shell umka_fuse umka_os umka.sym umka.prp umka.lst tags \ +all: umka_shell umka_fuse umka_os umka_ping umka.sym umka.prp umka.lst tags \ tools/mkdirrange tools/mkfilepattern covpreproc default.skn skin.skn covpreproc: covpreproc.c @@ -25,7 +25,11 @@ umka_fuse: umka_fuse.o umka.o trace.o trace_lbr.o vdisk.o pci.o thread.o $(CC) $(LDFLAGS_32) $^ -o $@ `pkg-config fuse3 --libs` umka_os: umka_os.o umka.o shell.o lodepng.o vdisk.o vnet.o trace.o trace_lbr.o \ - vdisk.o pci.o thread.o + pci.o thread.o + $(CC) $(LDFLAGS_32) $^ -o $@ -static + +umka_ping: umka_ping.o umka.o shell.o lodepng.o vdisk.o vnet.o trace.o \ + trace_lbr.o pci.o thread.o $(CC) $(LDFLAGS_32) $^ -o $@ -static umka.o umka.fas: umka.asm @@ -83,6 +87,9 @@ umka_fuse.o: umka_fuse.c umka.h umka_os.o: umka_os.c umka.h $(CC) $(CFLAGS_32) -c $< +umka_ping.o: umka_ping.c umka.h + $(CC) $(CFLAGS_32) -D_DEFAULT_SOURCE -c $< + tools/mkdirrange: tools/mkdirrange.c $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ diff --git a/shell.c b/shell.c index e55d040..be1dadd 100644 --- a/shell.c +++ b/shell.c @@ -54,7 +54,7 @@ FILE *fin, *fout; -net_device_t vnet = { +static net_device_t vnet = { .device_type = NET_TYPE_ETH, .mtu = 1514, .name = "UMK0770", @@ -294,7 +294,7 @@ void shell_ramdisk_init(int argc, char **argv) { "usage: ramdisk_init \n" " absolute or relative path"; if (argc != 2) { - puts(usage); + fputs(usage, fout); return; } const char *fname = argv[1]; @@ -326,7 +326,7 @@ void shell_disk_add(int argc, char **argv) { " disk name, e.g. hd0 or rd\n" " -c cache size size of disk cache in bytes"; if (argc < 3) { - puts(usage); + fputs(usage, fout); return; } size_t cache_size = 0; @@ -342,7 +342,7 @@ void shell_disk_add(int argc, char **argv) { adjust_cache_size = 1; break; default: - puts(usage); + fputs(usage, fout); return; } } @@ -935,7 +935,7 @@ void shell_ls(int argc, char **argv, const char *usage, f70or80_t f70or80) { path_enc = parse_encoding(optarg); break; default: - puts(usage); + fputs(usage, fout); return; } } @@ -1131,7 +1131,7 @@ void shell_acpi_set_usage(int argc, char **argv) { "usage: acpi_set_usage \n" " num one of ACPI_USAGE_*"; if (argc != 2) { - puts(usage); + fputs(usage, fout); return; } uint32_t acpi_usage = strtoul(argv[1], NULL, 0); @@ -1143,7 +1143,7 @@ void shell_acpi_get_usage(int argc, char **argv) { const char *usage = \ "usage: acpi_get_usage"; if (argc != 1) { - puts(usage); + fputs(usage, fout); return; } fprintf(fout, "ACPI usage: %" PRIu32 "\n", kos_acpi_usage); @@ -1155,11 +1155,11 @@ void shell_acpi_call(int argc, char **argv) { " method name of acpi method to call, e.g. \\_SB_PCI0_PRT"; if (argc > 2) { puts("arguments are not supported / not implemented!"); - puts(usage); + fputs(usage, fout); return; } if (argc < 2) { - puts(usage); + fputs(usage, fout); return; } const char *method = argv[1]; @@ -1175,7 +1175,7 @@ void shell_pci_set_path(int argc, char **argv) { "usage: pci_set_path \n" " path where aaaa:bb:cc.d dirs are"; if (argc != 2) { - puts(usage); + fputs(usage, fout); return; } strcpy(pci_path, argv[1]); @@ -1186,7 +1186,7 @@ void shell_pci_get_path(int argc, char **argv) { const char *usage = \ "usage: pci_get_path"; if (argc != 1) { - puts(usage); + fputs(usage, fout); return; } fprintf(fout, "pci path: %s\n", pci_path); @@ -1217,7 +1217,7 @@ void shell_net_get_dev_type(int argc, char **argv) { "usage: net_get_dev_type \n" " dev_num device number as returned by net_add_device"; if (argc != 2) { - puts(usage); + fputs(usage, fout); return; } uint8_t dev_num = strtoul(argv[1], NULL, 0); @@ -1233,7 +1233,7 @@ void shell_net_get_dev_name(int argc, char **argv) { "usage: net_get_dev_name \n" " dev_num device number as returned by net_add_device"; if (argc != 2) { - puts(usage); + fputs(usage, fout); return; } char dev_name[64]; @@ -1250,7 +1250,7 @@ void shell_net_dev_reset(int argc, char **argv) { "usage: net_dev_reset \n" " dev_num device number as returned by net_add_device"; if (argc != 2) { - puts(usage); + fputs(usage, fout); return; } uint8_t dev_num = strtoul(argv[1], NULL, 0); @@ -1263,7 +1263,7 @@ void shell_net_dev_stop(int argc, char **argv) { "usage: net_dev_stop \n" " dev_num device number as returned by net_add_device"; if (argc != 2) { - puts(usage); + fputs(usage, fout); return; } uint8_t dev_num = strtoul(argv[1], NULL, 0); @@ -1276,7 +1276,7 @@ void shell_net_get_dev(int argc, char **argv) { "usage: net_get_dev \n" " dev_num device number as returned by net_add_device"; if (argc != 2) { - puts(usage); + fputs(usage, fout); return; } uint8_t dev_num = strtoul(argv[1], NULL, 0); @@ -1292,7 +1292,7 @@ void shell_net_get_packet_tx_count(int argc, char **argv) { "usage: net_get_packet_tx_count \n" " dev_num device number as returned by net_add_device"; if (argc != 2) { - puts(usage); + fputs(usage, fout); return; } uint8_t dev_num = strtoul(argv[1], NULL, 0); @@ -1309,7 +1309,7 @@ void shell_net_get_packet_rx_count(int argc, char **argv) { "usage: net_get_packet_rx_count \n" " dev_num device number as returned by net_add_device"; if (argc != 2) { - puts(usage); + fputs(usage, fout); return; } uint8_t dev_num = strtoul(argv[1], NULL, 0); @@ -1326,7 +1326,7 @@ void shell_net_get_byte_tx_count(int argc, char **argv) { "usage: net_get_byte_tx_count \n" " dev_num device number as returned by net_add_device"; if (argc != 2) { - puts(usage); + fputs(usage, fout); return; } uint8_t dev_num = strtoul(argv[1], NULL, 0); @@ -1343,7 +1343,7 @@ void shell_net_get_byte_rx_count(int argc, char **argv) { "usage: net_get_byte_rx_count \n" " dev_num device number as returned by net_add_device"; if (argc != 2) { - puts(usage); + fputs(usage, fout); return; } uint8_t dev_num = strtoul(argv[1], NULL, 0); @@ -1392,7 +1392,7 @@ void shell_net_get_link_status(int argc, char **argv) { "usage: net_get_link_status \n" " dev_num device number as returned by net_add_device"; if (argc != 2) { - puts(usage); + fputs(usage, fout); return; } uint8_t dev_num = strtoul(argv[1], NULL, 0); @@ -1413,7 +1413,7 @@ void shell_net_open_socket(int argc, char **argv) { " type type\n" " protocol protocol"; if (argc != 4) { - puts(usage); + fputs(usage, fout); return; } uint32_t domain = strtoul(argv[1], NULL, 0); @@ -1430,7 +1430,7 @@ void shell_net_close_socket(int argc, char **argv) { "usage: net_close_socket \n" " socket number socket number"; if (argc != 2) { - puts(usage); + fputs(usage, fout); return; } uint32_t fd = strtoul(argv[1], NULL, 0); @@ -1446,7 +1446,7 @@ void shell_net_bind(int argc, char **argv) { " port port\n" " addr addr"; if (argc != 4) { - puts(usage); + fputs(usage, fout); return; } uint32_t fd = strtoul(argv[1], NULL, 0); @@ -1470,7 +1470,7 @@ void shell_net_listen(int argc, char **argv) { " fd socket number\n" " backlog max queue length"; if (argc != 3) { - puts(usage); + fputs(usage, fout); return; } uint32_t fd = strtoul(argv[1], NULL, 0); @@ -1487,7 +1487,7 @@ void shell_net_connect(int argc, char **argv) { " port port\n" " addr addr"; if (argc != 4) { - puts(usage); + fputs(usage, fout); return; } uint32_t fd = strtoul(argv[1], NULL, 0); @@ -1512,7 +1512,7 @@ void shell_net_accept(int argc, char **argv) { " port port\n" " addr addr"; if (argc != 4) { - puts(usage); + fputs(usage, fout); return; } uint32_t fd = strtoul(argv[1], NULL, 0); @@ -1535,7 +1535,7 @@ void shell_net_eth_read_mac(int argc, char **argv) { "usage: net_eth_read_mac \n" " dev_num device number as returned by net_add_device"; if (argc != 2) { - puts(usage); + fputs(usage, fout); return; } uint32_t dev_num = strtoul(argv[1], NULL, 0); @@ -1555,7 +1555,7 @@ void shell_net_ipv4_get_addr(int argc, char **argv) { "usage: net_ipv4_get_addr \n" " dev_num device number as returned by net_add_device"; if (argc != 2) { - puts(usage); + fputs(usage, fout); return; } uint32_t dev_num = strtoul(argv[1], NULL, 0); @@ -1575,7 +1575,7 @@ void shell_net_ipv4_set_addr(int argc, char **argv) { " dev_num device number as returned by net_add_device\n" " addr a.b.c.d"; if (argc != 3) { - puts(usage); + fputs(usage, fout); return; } uint32_t dev_num = strtoul(argv[1], NULL, 0); @@ -1594,7 +1594,7 @@ void shell_net_ipv4_get_dns(int argc, char **argv) { "usage: net_ipv4_get_dns \n" " dev_num device number as returned by net_add_device"; if (argc != 2) { - puts(usage); + fputs(usage, fout); return; } uint32_t dev_num = strtoul(argv[1], NULL, 0); @@ -1614,7 +1614,7 @@ void shell_net_ipv4_set_dns(int argc, char **argv) { " dev_num device number as returned by net_add_device\n" " dns a.b.c.d"; if (argc != 3) { - puts(usage); + fputs(usage, fout); return; } uint32_t dev_num = strtoul(argv[1], NULL, 0); @@ -1632,7 +1632,7 @@ void shell_net_ipv4_get_subnet(int argc, char **argv) { "usage: net_ipv4_get_subnet \n" " dev_num device number as returned by net_add_device"; if (argc != 2) { - puts(usage); + fputs(usage, fout); return; } uint32_t dev_num = strtoul(argv[1], NULL, 0); @@ -1652,7 +1652,7 @@ void shell_net_ipv4_set_subnet(int argc, char **argv) { " dev_num device number as returned by net_add_device\n" " subnet a.b.c.d"; if (argc != 3) { - puts(usage); + fputs(usage, fout); return; } uint32_t dev_num = strtoul(argv[1], NULL, 0); @@ -1671,7 +1671,7 @@ void shell_net_ipv4_get_gw(int argc, char **argv) { "usage: net_ipv4_get_gw \n" " dev_num device number as returned by net_add_device"; if (argc != 2) { - puts(usage); + fputs(usage, fout); return; } uint32_t dev_num = strtoul(argv[1], NULL, 0); @@ -1691,7 +1691,7 @@ void shell_net_ipv4_set_gw(int argc, char **argv) { " dev_num device number as returned by net_add_device\n" " gw a.b.c.d"; if (argc != 3) { - puts(usage); + fputs(usage, fout); return; } uint32_t dev_num = strtoul(argv[1], NULL, 0); @@ -1710,7 +1710,7 @@ void shell_net_arp_get_count(int argc, char **argv) { "usage: net_arp_get_count \n" " dev_num device number as returned by net_add_device"; if (argc != 2) { - puts(usage); + fputs(usage, fout); return; } uint32_t dev_num = strtoul(argv[1], NULL, 0); @@ -1728,7 +1728,7 @@ void shell_net_arp_get_entry(int argc, char **argv) { " dev_num device number as returned by net_add_device\n" " arp_num arp number as returned by net_add_device"; if (argc != 3) { - puts(usage); + fputs(usage, fout); return; } uint32_t dev_num = strtoul(argv[1], NULL, 0); @@ -1761,7 +1761,7 @@ void shell_net_arp_add_entry(int argc, char **argv) { " status see ARP.inc\n" " ttl Time to live"; if (argc != 6) { - puts(usage); + fputs(usage, fout); return; } arp_entry_t arp; @@ -1785,7 +1785,7 @@ void shell_net_arp_del_entry(int argc, char **argv) { " dev_num device number as returned by net_add_device\n" " arp_num arp number as returned by net_add_device"; if (argc != 3) { - puts(usage); + fputs(usage, fout); return; } uint32_t dev_num = strtoul(argv[1], NULL, 0); @@ -1802,7 +1802,7 @@ void shell_bg_set_size(int argc, char **argv) { " xsize in pixels\n" " ysize in pixels"; if (argc != 3) { - puts(usage); + fputs(usage, fout); return; } uint32_t xsize = strtoul(argv[1], NULL, 0); @@ -1816,7 +1816,7 @@ void shell_bg_put_pixel(int argc, char **argv) { " offset in bytes, (x+y*xsize)*3\n" " color in hex"; if (argc != 3) { - puts(usage); + fputs(usage, fout); return; } size_t offset = strtoul(argv[1], NULL, 0); @@ -1829,7 +1829,7 @@ void shell_bg_redraw(int argc, char **argv) { const char *usage = \ "usage: bg_redraw"; if (argc != 1) { - puts(usage); + fputs(usage, fout); return; } umka_sys_bg_redraw(); @@ -1840,7 +1840,7 @@ void shell_bg_set_mode(int argc, char **argv) { "usage: bg_set_mode \n" " mode 1 = tile, 2 = stretch"; if (argc != 3) { - puts(usage); + fputs(usage, fout); return; } uint32_t mode = strtoul(argv[1], NULL, 0); @@ -1853,7 +1853,7 @@ void shell_bg_put_img(int argc, char **argv) { " image file\n" " offset in bytes, (x+y*xsize)*3\n"; if (argc != 4) { - puts(usage); + fputs(usage, fout); return; } FILE *f = fopen(argv[1], "r"); @@ -1872,7 +1872,7 @@ void shell_bg_map(int argc, char **argv) { const char *usage = \ "usage: bg_map"; if (argc != 1) { - puts(usage); + fputs(usage, fout); return; } void *addr = umka_sys_bg_map(); @@ -1884,7 +1884,7 @@ void shell_bg_unmap(int argc, char **argv) { "usage: bg_unmap \n" " addr return value of bg_map"; if (argc != 2) { - puts(usage); + fputs(usage, fout); return; } void *addr = (void*)strtoul(argv[1], NULL, 0); diff --git a/umka.asm b/umka.asm index 6eff5de..bec9e79 100644 --- a/umka.asm +++ b/umka.asm @@ -58,22 +58,22 @@ public net_add_device public draw_data public img_background -public BgrDataWidth -public BgrDataHeight public mem_BACKGROUND public sys_background public REDRAW_BACKGROUND -public background_defined +public scheduler_add_thread +public new_sys_threads +public osloop macro cli { pushfd - btr dword[esp], 21 + bts dword[esp], 21 popfd } macro sti { pushfd - bts dword[esp], 21 + btr dword[esp], 21 popfd } @@ -89,8 +89,6 @@ macro int n { end if } -UEFI = 1 - MAX_PRIORITY = 0 ; highest, used for kernel tasks USER_PRIORITY = 1 ; default IDLE_PRIORITY = 2 ; lowest, only IDLE thread goes here @@ -111,6 +109,13 @@ macro BOOT_LO a {} macro BOOT a {} window_data equ twer CURRENT_TASK equ twer2 +TASK_BASE equ twer3 +TASK_DATA equ twer4 +TASK_EVENT equ twer5 +CDDataBuf equ twer6 +idts equ twer7 +WIN_STACK equ twer8 +WIN_POS equ twer9 TASK_COUNT equ gyads SLOT_BASE equ gfdskh ;macro OS_BASE [x] { @@ -119,6 +124,7 @@ SLOT_BASE equ gfdskh include 'const.inc' restore window_data restore CURRENT_TASK +restore TASK_BASE,TASK_DATA,TASK_EVENT,CDDataBuf,idts,WIN_STACK,WIN_POS restore TASK_COUNT restore SLOT_BASE purge BOOT_LO,BOOT @@ -128,13 +134,13 @@ LFB_BASE = lfb_base ;window_data = os_base + 0x00001000 ;CURRENT_TASK = os_base + 0x00003000 ;TASK_COUNT = os_base + 0x00003004 -TASK_BASE = os_base + 0x00003010 -TASK_DATA = os_base + 0x00003020 -TASK_EVENT = os_base + 0x00003020 -CDDataBuf = os_base + 0x00005000 -idts = os_base + 0x0000B100 -WIN_STACK = os_base + 0x0000C000 -WIN_POS = os_base + 0x0000C400 +;TASK_BASE = os_base + 0x00003010 +;TASK_DATA = os_base + 0x00003020 +;TASK_EVENT = os_base + 0x00003020 +;CDDataBuf = os_base + 0x00005000 +;idts = os_base + 0x0000B100 +;WIN_STACK = os_base + 0x0000C000 +;WIN_POS = os_base + 0x0000C400 FDD_BUFF = os_base + 0x0000D000 WIN_TEMP_XY = os_base + 0x0000F300 KEY_COUNT = os_base + 0x0000F400 @@ -166,8 +172,8 @@ macro add r, v { shr r, 3 neg r add r, CURRENT_TASK - add r, [esp] add esp, 4 + add r, [esp-4] else add r, v end if @@ -178,7 +184,18 @@ include 'fdo.inc' include 'core/sync.inc' ;include 'core/sys32.inc' +macro call target { + if target eq do_change_task + call _do_change_task + else + call target + end if +} +do_change_task equ hjk +irq0 equ jhg include 'core/sched.inc' +restore do_change_task +restore irq0 include 'core/syscall.inc' ;include 'core/fpu.inc' ;include 'core/memory.inc' @@ -388,7 +405,7 @@ proc kos_init c uses ebx esi edi ebp mov eax, [edx+APPDATA.saved_esp] mov dword[eax], idle mov ecx, IDLE_PRIORITY - call sched_add_thread + call scheduler_add_thread mov eax, [xsave_area_size] add eax, RING0_STACK_SIZE @@ -401,7 +418,7 @@ proc kos_init c uses ebx esi edi ebp mov eax, [edx+APPDATA.saved_esp] mov dword[eax], 0 xor ecx, ecx - call sched_add_thread + call scheduler_add_thread mov dword[CURRENT_TASK], 2 mov dword[TASK_COUNT], 2 @@ -427,8 +444,6 @@ proc kos_init c uses ebx esi edi ebp mov word[cur_dir.path], '/' mov [ebx+APPDATA.cur_dir], cur_dir - ;call stack_init - ret endp @@ -444,36 +459,6 @@ proc idle uses ebx esi edi ret endp -extrn raise -public umka_os -proc umka_os uses ebx esi edi - call kos_init - - call stack_init - - mov edx, SLOT_BASE+256*3 - xor ecx, ecx - call sched_add_thread - - mov edx, SLOT_BASE+256*4 - xor ecx, ecx - call sched_add_thread - - mov edx, SLOT_BASE+256*5 - xor ecx, ecx - call sched_add_thread - - mov dword[TASK_COUNT], 5 - - stdcall umka_install_thread, [monitor_thread] - - ccall raise, SIGPROF - - jmp osloop - - ret -endp - extrn pci_read proc pci_read_reg uses ebx esi edi mov ecx, eax @@ -511,36 +496,55 @@ proc sys_msg_board ret endp -proc map_io_mem _base, _size, _flags - mov eax, [_base] +proc delay_ms + ret endp -extrn umka_sched_add_thread -sched_add_thread: - stdcall umka_sched_add_thread, edx - ret -public umka_install_thread -proc umka_install_thread _func - ; fpu_state = sigsetjmp - mov eax, [xsave_area_size] - add eax, RING0_STACK_SIZE - stdcall kernel_alloc, eax - mov ebx, eax - mov edx, [TASK_COUNT] - inc edx - shl edx, 8 - add edx, SLOT_BASE - call setup_os_slot - mov dword [edx], 'USER' - sub [edx+APPDATA.saved_esp], 4 - mov eax, [edx+APPDATA.saved_esp] - mov ecx, [_func] - mov dword[eax], ecx - xor ecx, ecx - call sched_add_thread - inc dword[TASK_COUNT] +extrn reset_procmask +extrn get_fake_if +extrn restart_timer +public irq0 +proc irq0 c, _signo, _info, _context + pushfd + pushad + + ccall reset_procmask + ccall get_fake_if, [_context] + test eax, eax + jz .done + + mov bl, SCHEDULE_ANY_PRIORITY + call find_next_task + jz .done ; if there is only one running process + call do_change_task +.done: + ccall restart_timer + popad + popfd + ret +endp + +proc _do_change_task + mov eax, [current_slot] + sub eax, SLOT_BASE + shr eax, 8 + mov ecx, ebx + sub ecx, SLOT_BASE + shr ecx, 8 + DEBUGF 2, "### switching task from %d to %d\n",eax,ecx + + mov esi, ebx + xchg esi, [current_slot] +; set new stack after saving old + mov [esi+APPDATA.saved_esp], esp + mov esp, [ebx+APPDATA.saved_esp] + ret +endp + +proc map_io_mem _base, _size, _flags + mov eax, [_base] ret endp @@ -605,6 +609,7 @@ map_memEx: HEAP_BASE equ include 'init.inc' sys_msg_board equ __pew +delay_ms equ __pew8 include fix pew macro pew x {} @@ -634,7 +639,7 @@ include 'kernel.asm' purge lea,add,org,mov restore lea,add,org,mov -purge sys_msg_board,HEAP_BASE +purge sys_msg_board,HEAP_BASE,__pew8 coverage_end: @@ -670,6 +675,13 @@ os_base: rb 0x1000 window_data: rb 0x2000 CURRENT_TASK: rb 4 TASK_COUNT: rb 12 +TASK_BASE rd 4 +TASK_DATA rd 0x7f8 +TASK_EVENT = TASK_DATA +CDDataBuf: rd 0x1840 +idts rd 0x3c0 +WIN_STACK rw 0x200 +WIN_POS rw 0x600 rb 0x1000000 BOOT_LO boot_data BOOT boot_data diff --git a/umka.h b/umka.h index 5dba18f..edbcf7f 100644 --- a/umka.h +++ b/umka.h @@ -6,6 +6,8 @@ #include #include #include +#define __USE_GNU +#include #define BDFE_LEN_CP866 304 #define BDFE_LEN_UNICODE 560 @@ -299,7 +301,7 @@ struct net_device_t { // ptrs to driver functions __attribute__((__stdcall__)) void (*unload) (void); __attribute__((__stdcall__)) void (*reset) (void); - __attribute__((__stdcall__)) void (*transmit) (net_buff_t *); + __attribute__((__stdcall__)) int (*transmit) (net_buff_t *); uint64_t bytes_tx; // statistics, updated by the driver uint64_t bytes_rx; @@ -319,8 +321,9 @@ typedef struct { uint16_t ttl; } arp_entry_t; -void umka_os(void); -void umka_install_thread(void *func) __attribute__((__stdcall__)); +void osloop(void); +void irq0(int signo, siginfo_t *info, void *context); + void kos_init(void); void i40(void); uint32_t kos_time_to_epoch(uint32_t *time); @@ -339,6 +342,18 @@ extern uint8_t ntfs_user_functions[]; extern uint8_t kos_ramdisk[2880*512]; disk_t *kos_ramdisk_init(void); +static inline void umka_new_sys_threads(uint32_t flags, void (*entry)(), void *stack) { + __asm__ __inline__ __volatile__ ( + "pushad;" + "call new_sys_threads;" + "popad" + : + : "b"(flags), + "c"(entry), + "d"(stack) + : "memory", "cc"); +} + static inline void kos_enable_acpi() { __asm__ __inline__ __volatile__ ( "pushad;" @@ -499,6 +514,9 @@ extern taskdata_t *kos_task_base; extern taskdata_t kos_task_data[]; extern appdata_t kos_slot_base[]; extern void (*monitor_thread)(void); +extern void umka_do_change_task(appdata_t *new); +extern void scheduler_add_thread(void); +extern void find_next_task(void); extern uint32_t kos_lfb_base[]; extern uint16_t kos_win_stack[]; extern uint16_t kos_win_pos[]; @@ -509,6 +527,44 @@ extern void *acpi_ctx; extern uint32_t kos_acpi_usage; extern disk_t disk_list; +static inline void umka_scheduler_add_thread(appdata_t *thread, int32_t priority) { + __asm__ __inline__ __volatile__ ( + "call do_change_thread" + : + : "c"(priority), + "d"(thread) + : "memory", "cc"); + +} + +#define MAX_PRIORITY 0 +#define USER_PRIORITY 1 +#define IDLE_PRIORITY 2 +#define NR_SCHED_QUEUES 3 + +#define SCHEDULE_ANY_PRIORITY 0 +#define SCHEDULE_HIGHER_PRIORITY 1 + +typedef struct { + appdata_t *appdata; + taskdata_t *taskdata; + int same; +} find_next_task_t; + +static inline find_next_task_t umka_find_next_task(int32_t priority) { + find_next_task_t fnt; + __asm__ __inline__ __volatile__ ( + "call find_next_task;" + "setz al;" + "movzx eax, al" + : "=b"(fnt.appdata), + "=D"(fnt.taskdata), + "=a"(fnt.same) + : "b"(priority) + : "memory", "cc"); + return fnt; +} + static inline void umka_i40(pushad_t *regs) { __asm__ __inline__ __volatile__ ( @@ -1212,6 +1268,40 @@ static inline f75ret_t umka_sys_net_accept(uint32_t fd, void *sockaddr, return r; } +static inline f75ret_t umka_sys_net_send(uint32_t fd, void *buf, + size_t buf_len, uint32_t flags) { + f75ret_t r; + __asm__ __inline__ __volatile__ ( + "call i40" + : "=a"(r.value), + "=b"(r.errorcode) + : "a"(75), + "b"(6), + "c"(fd), + "d"(buf), + "S"(buf_len), + "D"(flags) + : "memory"); + return r; +} + +static inline f75ret_t umka_sys_net_receive(uint32_t fd, void *buf, + size_t buf_len, uint32_t flags) { + f75ret_t r; + __asm__ __inline__ __volatile__ ( + "call i40" + : "=a"(r.value), + "=b"(r.errorcode) + : "a"(75), + "b"(7), + "c"(fd), + "d"(buf), + "S"(buf_len), + "D"(flags) + : "memory"); + return r; +} + static inline f76ret_t umka_sys_net_eth_read_mac(uint32_t dev_num) { f76ret_t r; __asm__ __inline__ __volatile__ ( diff --git a/umka_os.c b/umka_os.c index a6bdb3c..b752136 100644 --- a/umka_os.c +++ b/umka_os.c @@ -1,5 +1,3 @@ -#include -#define __USE_GNU #include #include #include @@ -9,34 +7,9 @@ #include #include #include "umka.h" -#include "thread.h" #include "shell.h" -struct itimerval timeout = {.it_value = {.tv_sec = 0, .tv_usec = 10000}}; - - -void scheduler(int signo, siginfo_t *info, void *context) { - (void)signo; - (void)info; - (void)context; -// printf("##### switching from task %u\n", kos_current_task); - ucontext_t *ctx = context; - if (!sigsetjmp(*kos_slot_base[kos_current_task].fpu_state, 1)) { - if (ctx->uc_mcontext.__gregs[REG_EFL] & (1 << 21)) { - kos_current_task += 1; - if (kos_current_task > kos_task_count) { - kos_current_task = 1; - } - } else { -// printf("########## cli ############\n"); - } - kos_current_slot = kos_slot_base + kos_current_task; - kos_task_base = ((taskdata_t*)&kos_current_task) + kos_current_task; -// printf("##### kos_current_task: %u\n", kos_current_task); - setitimer(ITIMER_PROF, &timeout, NULL); - siglongjmp(*kos_slot_base[kos_current_task].fpu_state, 1); - } -} +#define MONITOR_THREAD_STACK_SIZE 0x100000 void monitor() { fprintf(stderr, "Start monitor thread\n"); @@ -49,19 +22,13 @@ void monitor() { return; } run_test(fin, fout, 0); -/* - while (1) { - for (int i = 0; i < 10000000; i++) {} - printf("6 monitor\n"); - } -*/ } int main() { umka_tool = UMKA_OS; - struct sigaction sa; - sa.sa_sigaction = scheduler; + struct sigaction sa; + sa.sa_sigaction = irq0; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_SIGINFO; @@ -72,7 +39,14 @@ int main() { monitor_thread = monitor; - umka_os(); + kos_init(); + kos_stack_init(); + uint8_t *monitor_stack = malloc(MONITOR_THREAD_STACK_SIZE); + umka_new_sys_threads(1, monitor, monitor_stack + MONITOR_THREAD_STACK_SIZE); + + raise(SIGPROF); + + osloop(); // doesn't return return 0; } diff --git a/umka_ping.c b/umka_ping.c new file mode 100644 index 0000000..70b9a98 --- /dev/null +++ b/umka_ping.c @@ -0,0 +1,204 @@ +/* + umka_shell: User-Mode KolibriOS developer tools, the ping + Copyright (C) 2020 Ivan Baravy + + 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 + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "shell.h" +#include "umka.h" +#include "trace.h" +#include "vnet.h" + +// tap +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static net_device_t vnet = { + .device_type = NET_TYPE_ETH, + .mtu = 1514, + .name = "UMK0770", + + .unload = vnet_unload, + .reset = vnet_reset, + .transmit = vnet_transmit, + + .bytes_tx = 0, + .bytes_rx = 0, + .packets_tx = 0, + .packets_rx = 0, + + .link_state = ETH_LINK_FD + ETH_LINK_10M, + .hwacc = 0, + .mac = {0x80, 0x2b, 0xf9, 0x3b, 0x6c, 0xca}, + }; + +uint8_t packet[4096] = {8, 0, 0, 0, 0, 0, 0, 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5'}; + +int tap_alloc(char *dev) +{ + int flags = IFF_TAP | IFF_NO_PI; + struct ifreq ifr; + int fd, err; + char *clonedev = "/dev/net/tun"; + + if( (fd = open(clonedev , O_RDWR)) < 0 ) + { + perror("Opening /dev/net/tun"); + return fd; + } + + memset(&ifr, 0, sizeof(ifr)); + + ifr.ifr_flags = flags; + + if(*dev) + { + strncpy(ifr.ifr_name, dev, IFNAMSIZ); + } + + if( (err = ioctl(fd, TUNSETIFF, (void *)&ifr)) < 0 ) + { + perror("ioctl(TUNSETIFF)"); + close(fd); + return err; + } + + strcpy(dev, ifr.ifr_name); + + return fd; +} + +int main(int argc, char **argv) { + umka_tool = UMKA_SHELL; + const char *usage = \ + "usage: umka_shell [-c]\n" + " -c collect coverage"; + int opt; + while ((opt = getopt(argc, argv, "c")) != -1) { + switch (opt) { + case 'c': + coverage = 1; + break; + default: + puts(usage); + return 1; + } + } + + if (coverage) + trace_begin(); + + COVERAGE_ON(); + kos_init(); + COVERAGE_OFF(); + + kos_stack_init(); + char tapdev[IFNAMSIZ] = "tap0"; + int tapfd = tap_alloc(tapdev); + vnet_init(tapfd); + + kos_net_add_device(&vnet); + char devname[64]; + umka_sys_net_dev_reset(1); + for (size_t i = 0; i < umka_sys_net_get_dev_count(); i++) { +// umka_sys_net_dev_reset(i); + umka_sys_net_get_dev_name(i, devname); + uint32_t devtype = umka_sys_net_get_dev_type(i); + printf("device %i: %s %u\n", i, devname, devtype); + } + + f76ret_t r76; + r76 = umka_sys_net_ipv4_set_subnet(1, inet_addr("0.0.0.0")); + if (r76.eax == (uint32_t)-1) { + fprintf(stderr, "error\n"); + exit(1); + } + + r76 = umka_sys_net_ipv4_set_gw(1, inet_addr("192.168.1.1")); + if (r76.eax == (uint32_t)-1) { + fprintf(stderr, "error\n"); + exit(1); + } + + r76 = umka_sys_net_ipv4_set_dns(1, inet_addr("217.10.36.5")); + if (r76.eax == (uint32_t)-1) { + fprintf(stderr, "error\n"); + exit(1); + } + + r76 = umka_sys_net_ipv4_set_addr(1, inet_addr("192.168.1.27")); + if (r76.eax == (uint32_t)-1) { + fprintf(stderr, "error\n"); + exit(1); + } + + f75ret_t r75; + r75 = umka_sys_net_open_socket(AF_INET4, SOCK_RAW, IPPROTO_ICMP); + if (r75.errorcode == (uint32_t)-1) { + fprintf(stderr, "error\n"); + exit(1); + } + uint32_t sockfd = r75.value; + +// uint32_t addr = inet_addr("127.0.0.1"); +// uint32_t addr = inet_addr("192.243.108.5"); + uint32_t addr = inet_addr("10.50.0.1"); + uint16_t port = 0; + + struct sockaddr_in sa; + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET4; + sa.sin_port = htons(port); + sa.sin_addr.s_addr = addr; + + r75 = umka_sys_net_connect(sockfd, &sa, sizeof(struct sockaddr_in)); + if (r75.errorcode == (uint32_t)-1) { + fprintf(stderr, "error %u\n", r75.errorcode); + exit(1); + } + + r75 = umka_sys_net_send(sockfd, packet, 64, 0); + if (r75.errorcode == (uint32_t)-1) { + fprintf(stderr, "error %u\n", r75.errorcode); + exit(1); + } + + if (coverage) + trace_end(); + + return 0; +} diff --git a/vnet.c b/vnet.c index 5ce5537..581a0df 100644 --- a/vnet.c +++ b/vnet.c @@ -1,19 +1,23 @@ #include #include #include +#include #include #include #include "umka.h" #include "trace.h" +int tapfd; + typedef struct { - unsigned x; + int fd; } vnet_t; -void *vnet_init() { +void *vnet_init(int fd) { printf("vnet_init\n"); vnet_t *vnet = (vnet_t*)malloc(sizeof(vnet_t)); - *vnet = (vnet_t){.x = 0,}; + *vnet = (vnet_t){.fd = fd,}; + tapfd = fd; return vnet; } @@ -39,10 +43,14 @@ static void dump_net_buff(net_buff_t *buf) { } __attribute__((__stdcall__)) -void vnet_transmit(net_buff_t *buf) { +int vnet_transmit(net_buff_t *buf) { printf("vnet_transmit: %d bytes\n", buf->length); dump_net_buff(buf); + write(tapfd, buf->data, buf->length); + buf->length = 0; COVERAGE_OFF(); COVERAGE_ON(); + printf("vnet_transmit: done\n"); + return 0; } diff --git a/vnet.h b/vnet.h index 14a6465..e8f74c9 100644 --- a/vnet.h +++ b/vnet.h @@ -5,7 +5,7 @@ #include #include "umka.h" -void *vnet_init(void); +void *vnet_init(int fd); __attribute__((__stdcall__)) void vnet_unload(void); @@ -14,6 +14,6 @@ __attribute__((__stdcall__)) void vnet_reset(void); __attribute__((__stdcall__)) -void vnet_transmit(net_buff_t *buf); +int vnet_transmit(net_buff_t *buf); #endif // VNET_H_INCLUDED