From f0f8cb8e37773d53a56d63e4c129ce3047d1582a Mon Sep 17 00:00:00 2001 From: Ivan Baravy Date: Mon, 27 Jun 2022 16:32:29 +0400 Subject: [PATCH] Get rid of umka_ping hack! Use vnet_init --- makefile | 5 +- shell.c | 2 +- umka.asm | 33 ++++++- umka.h | 2 +- umka_os.c | 44 ++++++++- umka_ping.c | 174 ----------------------------------- vdisk.h | 20 +--- vnet.c | 256 ++++++++++++++++++++++++++++++++++++++-------------- vnet.h | 17 +--- 9 files changed, 268 insertions(+), 285 deletions(-) delete mode 100644 umka_ping.c diff --git a/makefile b/makefile index 156ec10..5130253 100644 --- a/makefile +++ b/makefile @@ -68,7 +68,7 @@ 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` -T umka.ld umka_os: umka_os.o umka.o shell.o lodepng.o vdisk.o vnet.o trace.o trace_lbr.o \ - pci.o thread.o umka_ping.o util.o bestline.o + pci.o thread.o util.o bestline.o $(CC) $(LDFLAGS_32) $^ -o $@ -T umka.ld umka_gen_devices_dat: umka_gen_devices_dat.o umka.o pci.o thread.o util.o @@ -143,9 +143,6 @@ umka_os.o: umka_os.c umka.h umka_gen_devices_dat.o: umka_gen_devices_dat.c umka.h $(CC) $(CFLAGS_32) -c $< -umka_ping.o: umka_ping.c umka.h - $(CC) $(CFLAGS_32) -D_DEFAULT_SOURCE -c $< - .PHONY: all clean clean: diff --git a/shell.c b/shell.c index a875b0c..05c60ff 100644 --- a/shell.c +++ b/shell.c @@ -2741,7 +2741,7 @@ cmd_net_add_device(struct shell_ctx *ctx, int argc, char **argv) { puts(usage); return; } - net_device_t *vnet = vnet_init(42); // FIXME: tap & list like block devices + net_device_t *vnet = vnet_init(); // FIXME: list like block devices COVERAGE_ON(); int32_t dev_num = kos_net_add_device(vnet); COVERAGE_OFF(); diff --git a/umka.asm b/umka.asm index 416e338..91d5672 100644 --- a/umka.asm +++ b/umka.asm @@ -81,7 +81,7 @@ UMKA_MEMORY_BYTES = 256 SHL 20 pubsym irq_serv.irq_10, 'kos_irq_serv_irq10' pubsym attach_int_handler, 'kos_attach_int_handler', 12 -pubsym fs_execute, 'kos_fs_execute' +pubsym fs_execute, 'kos_fs_execute', 4 pubsym set_keyboard_data, 'kos_set_keyboard_data' pubsym KEY_COUNT as 'kos_key_count' pubsym KEY_BUFF as 'kos_key_buff' @@ -253,7 +253,9 @@ page_tabs equ page_tabs_pew ;macro OS_BASE [x] { ; OS_BASE equ os_base ;} +macro tss pew {} include 'const.inc' +purge tss restore window_data restore CDDataBuf,idts,WIN_STACK,WIN_POS restore FDD_BUFF,WIN_TEMP_XY,KEY_COUNT,KEY_BUFF,BTN_COUNT,BTN_BUFF,BTN_ADDR @@ -338,9 +340,13 @@ macro call target { end if } do_change_task equ hjk -irq0 equ jhg +irq0 equ irq0_pew +tss._io_map_0 equ 0 +tss._io_map_1 equ 0 include 'core/sched.inc' -purge call +restore tss._io_map_0 +restore tss._io_map_1 +;purge mov restore irq0 include 'core/syscall.inc' ;include 'core/fpu.inc' @@ -395,6 +401,7 @@ macro mov dst, src { } include 'core/irq.inc' purge mov +purge call include 'core/apic.inc' include 'core/hpet.inc' include 'core/timers.inc' @@ -1054,6 +1061,7 @@ ide_channel8_mutex MUTEX ioapic_data rb 0x400 lapic_data rb 0x400 +tss TSS lfb_base rd MAX_SCREEN_WIDTH*MAX_SCREEN_HEIGHT @@ -1086,4 +1094,23 @@ macro align x { } macro assert [x] {} +macro dw [x] { +forward + if x eq tss and 0xFFFF + dw 0 + else if x eq (tss shr 16) and 0xFF00 + dw 0 + else + dw x + end if +} + +macro db [x] { +forward + if x eq (tss shr 16) and 0xFF + db 0 + else + db x + end if +} include 'data32.inc' diff --git a/umka.h b/umka.h index 3f742ec..d82a41b 100644 --- a/umka.h +++ b/umka.h @@ -889,7 +889,7 @@ typedef struct { uint32_t dbg_state; // +76 char *cur_dir; // +80 uint32_t wait_timeout; // +84 - uint32_t saved_esp0; // +88 + void *saved_esp0; // +88 uint32_t wait_begin; // +92 int (*wait_test)(void); // +96 void *wait_param; // +100 diff --git a/umka_os.c b/umka_os.c index 6e1129d..0ff45e6 100644 --- a/umka_os.c +++ b/umka_os.c @@ -17,8 +17,10 @@ along with this program. If not, see . */ +#include #include #include +#include #define __USE_GNU #include #include @@ -27,12 +29,14 @@ #define __USE_MISC #include #include +#include #include #include #include #include "umka.h" #include "shell.h" #include "trace.h" +#include "vnet.h" #define UMKA_DEFAULT_DISPLAY_WIDTH 400 #define UMKA_DEFAULT_DISPLAY_HEIGHT 300 @@ -180,8 +184,46 @@ main() { // load_app_host("../apps/board_cycle", app_base); // load_app("/rd/1/loader"); + net_device_t *vnet = vnet_init(); + kos_net_add_device(vnet); + + char devname[64]; + 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); + fprintf(stderr, "[net_drv] device %i: %s %u\n", i, devname, devtype); + } + + f76ret_t r76; + r76 = umka_sys_net_ipv4_set_subnet(1, inet_addr("255.255.255.0")); + if (r76.eax == (uint32_t)-1) { + fprintf(stderr, "[net_drv] set subnet error\n"); + return -1; + } + +// r76 = umka_sys_net_ipv4_set_gw(1, inet_addr("192.168.1.1")); + r76 = umka_sys_net_ipv4_set_gw(1, inet_addr("10.50.0.1")); + if (r76.eax == (uint32_t)-1) { + fprintf(stderr, "set gw error\n"); + return -1; + } + + r76 = umka_sys_net_ipv4_set_dns(1, inet_addr("217.10.36.5")); + if (r76.eax == (uint32_t)-1) { + fprintf(stderr, "[net_drv] set dns error\n"); + return -1; + } + + r76 = umka_sys_net_ipv4_set_addr(1, inet_addr("10.50.0.2")); + if (r76.eax == (uint32_t)-1) { + fprintf(stderr, "[net_drv] set ip addr error\n"); + return -1; + } + + thread_start(0, monitor, THREAD_STACK_SIZE); - thread_start(0, umka_thread_net_drv, THREAD_STACK_SIZE); +// thread_start(0, umka_thread_net_drv, THREAD_STACK_SIZE); dump_procs(); diff --git a/umka_ping.c b/umka_ping.c deleted file mode 100644 index 4c0b14f..0000000 --- a/umka_ping.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "shell.h" -#include "umka.h" -#include "vnet.h" - -#define TAP_DEV "/dev/net/tun" -#define UMKA_TAP_NAME "umka%d" - -static int -tap_alloc() { - struct ifreq ifr = {.ifr_name = UMKA_TAP_NAME, - .ifr_flags = IFF_TAP | IFF_NO_PI}; - int fd, err; - - if( (fd = open(TAP_DEV, O_RDWR | O_NONBLOCK)) < 0 ) { - perror("Opening /dev/net/tun"); - return fd; - } - - if( (err = ioctl(fd, TUNSETIFF, &ifr)) < 0 ) { - perror("ioctl(TUNSETIFF)"); - close(fd); - return err; - } - - ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; - memcpy(ifr.ifr_hwaddr.sa_data, (char[]){0x00, 0x11, 0x00, 0x00, 0x00, 0x00}, 6); - - if( (err = ioctl(fd, SIOCSIFHWADDR, &ifr)) < 0 ) { - perror("ioctl(SIOCSIFHWADDR)"); - close(fd); - return err; - } - - struct sockaddr_in sai; - sai.sin_family = AF_INET; - sai.sin_port = 0; - sai.sin_addr.s_addr = inet_addr("10.50.0.1"); - memcpy(&ifr.ifr_addr, &sai, sizeof(struct sockaddr)); - - int sockfd = socket(AF_INET, SOCK_DGRAM, 0); - - if ( (err = ioctl(sockfd, SIOCSIFADDR, &ifr)) < 0 ) { - perror("ioctl(SIOCSIFADDR)"); - close(fd); - return err; - } - - sai.sin_addr.s_addr = inet_addr("255.255.255.0"); - memcpy(&ifr.ifr_netmask, &sai, sizeof(struct sockaddr)); - if ((err = ioctl(sockfd, SIOCSIFNETMASK, &ifr)) < 0) { - perror("ioctl(SIOCSIFNETMASK)"); - close(fd); - return err; - } - - if ((err = ioctl(sockfd, SIOCGIFFLAGS, &ifr)) < 0) { - perror("ioctl(SIOCGIFFLAGS)"); - close(fd); - return err; - } - ifr.ifr_flags |= IFF_UP | IFF_RUNNING; - ifr.ifr_flags &= ~(IFF_BROADCAST | IFF_LOWER_UP); - if ((err = ioctl(sockfd, SIOCSIFFLAGS, &ifr)) < 0) { - perror("ioctl(SIOCSIFFLAGS)"); - close(fd); - return err; - } - - return fd; -} - -void -umka_thread_net_drv(void) { - umka_sti(); - fprintf(stderr, "[net_drv] starting\n"); - int tapfd; - uint8_t buffer[2048]; - int plen = 0; - tapfd = tap_alloc(); - net_device_t *vnet = vnet_init(tapfd); - kos_net_add_device(vnet); - - char devname[64]; - 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); - fprintf(stderr, "[net_drv] device %i: %s %u\n", i, devname, devtype); - } - - f76ret_t r76; - r76 = umka_sys_net_ipv4_set_subnet(1, inet_addr("255.255.255.0")); - if (r76.eax == (uint32_t)-1) { - fprintf(stderr, "[net_drv] set subnet error\n"); - return; - } - -// r76 = umka_sys_net_ipv4_set_gw(1, inet_addr("192.168.1.1")); - r76 = umka_sys_net_ipv4_set_gw(1, inet_addr("10.50.0.1")); - if (r76.eax == (uint32_t)-1) { - fprintf(stderr, "set gw error\n"); - return; - } - - r76 = umka_sys_net_ipv4_set_dns(1, inet_addr("217.10.36.5")); - if (r76.eax == (uint32_t)-1) { - fprintf(stderr, "[net_drv] set dns error\n"); - return; - } - - r76 = umka_sys_net_ipv4_set_addr(1, inet_addr("10.50.0.2")); - if (r76.eax == (uint32_t)-1) { - fprintf(stderr, "[net_drv] set ip addr error\n"); - return; - } - - while(true) - { - plen = read(tapfd, buffer, 2*1024); - if (plen > 0) { - fprintf(stderr, "[net_drv] read %i bytes\n", plen); - for (int i = 0; i < plen; i++) { - fprintf(stderr, " %2.2x", buffer[i]); - } - fprintf(stderr, "\n"); - vnet_receive_frame(vnet, buffer, plen); - } else if(plen == -1 && (errno == EAGAIN || errno == EINTR)) { - continue; - } else { - perror("[net_drv] reading data"); - exit(1); - } - } - -} diff --git a/vdisk.h b/vdisk.h index ea2e4f1..51c1d6f 100644 --- a/vdisk.h +++ b/vdisk.h @@ -1,27 +1,11 @@ #ifndef VDISK_H_INCLUDED #define VDISK_H_INCLUDED -#include #include #include "umka.h" -void *vdisk_init(const char *fname, int adjust_cache_size, size_t cache_size); - -STDCALL void -vdisk_close(void *userdata); - -STDCALL int -vdisk_read(void *userdata, void *buffer, off_t startsector, size_t *numsectors); - -STDCALL int -vdisk_write(void *userdata, void *buffer, off_t startsector, - size_t *numsectors); - -STDCALL int -vdisk_querymedia(void *userdata, diskmediainfo_t *minfo); - -STDCALL unsigned int -vdisk_adjust_cache_size(void *userdata, unsigned suggested_size); +void* +vdisk_init(const char *fname, int adjust_cache_size, size_t cache_size); extern diskfunc_t vdisk_functions; diff --git a/vnet.c b/vnet.c index cb4a099..029654c 100644 --- a/vnet.c +++ b/vnet.c @@ -1,9 +1,19 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include -#include -#include -#include +#include +#include #include "umka.h" #include "trace.h" #include "vnet.h" @@ -13,20 +23,183 @@ #include #endif +#define TAP_DEV "/dev/net/tun" +#define UMKA_TAP_NAME "umka%d" + +#define STACK_SIZE 0x10000 + typedef struct { - int fd; + int tapfd; + bool input_processed; } vnet_userdata_t; -int vnet_input(void *udata) { - vnet_userdata_t *u = udata; +static int +tap_alloc() { + struct ifreq ifr = {.ifr_name = UMKA_TAP_NAME, + .ifr_flags = IFF_TAP | IFF_NO_PI}; + int fd, err; + + if( (fd = open(TAP_DEV, O_RDWR | O_NONBLOCK)) < 0 ) { + perror("Opening /dev/net/tun"); + return fd; + } + + if( (err = ioctl(fd, TUNSETIFF, &ifr)) < 0 ) { + perror("ioctl(TUNSETIFF)"); + close(fd); + return err; + } + + ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; + memcpy(ifr.ifr_hwaddr.sa_data, (char[]){0x00, 0x11, 0x00, 0x00, 0x00, 0x00}, 6); + + if( (err = ioctl(fd, SIOCSIFHWADDR, &ifr)) < 0 ) { + perror("ioctl(SIOCSIFHWADDR)"); + close(fd); + return err; + } + + struct sockaddr_in sai; + sai.sin_family = AF_INET; + sai.sin_port = 0; + sai.sin_addr.s_addr = inet_addr("10.50.0.1"); + memcpy(&ifr.ifr_addr, &sai, sizeof(struct sockaddr)); + + int sockfd = socket(AF_INET, SOCK_DGRAM, 0); + + if ( (err = ioctl(sockfd, SIOCSIFADDR, &ifr)) < 0 ) { + perror("ioctl(SIOCSIFADDR)"); + close(fd); + return err; + } + + sai.sin_addr.s_addr = inet_addr("255.255.255.0"); + memcpy(&ifr.ifr_netmask, &sai, sizeof(struct sockaddr)); + if ((err = ioctl(sockfd, SIOCSIFNETMASK, &ifr)) < 0) { + perror("ioctl(SIOCSIFNETMASK)"); + close(fd); + return err; + } + + if ((err = ioctl(sockfd, SIOCGIFFLAGS, &ifr)) < 0) { + perror("ioctl(SIOCGIFFLAGS)"); + close(fd); + return err; + } + ifr.ifr_flags |= IFF_UP | IFF_RUNNING; + ifr.ifr_flags &= ~(IFF_BROADCAST | IFF_LOWER_UP); + if ((err = ioctl(sockfd, SIOCSIFFLAGS, &ifr)) < 0) { + perror("ioctl(SIOCSIFFLAGS)"); + close(fd); + return err; + } + + return fd; +} + +static int +vnet_input(void *udata) { + umka_sti(); + net_device_t *vnet = udata; + vnet_userdata_t *u = vnet->userdata; + int tapfd = u->tapfd; + uint8_t buffer[2048]; + int plen = 0; fprintf(stderr, "###### vnet_input\n"); + plen = read(tapfd, buffer, 2*1024); + if (plen > 0) { + fprintf(stderr, "[net_drv] read %i bytes\n", plen); + for (int i = 0; i < plen; i++) { + fprintf(stderr, " %2.2x", buffer[i]); + } + fprintf(stderr, "\n"); + + net_buff_t *buf = kos_net_buff_alloc(plen + offsetof(net_buff_t, data)); + if (!buf) { + fprintf(stderr, "[vnet] Can't allocate network buffer!\n"); + return 1; + } + buf->length = plen; + buf->device = vnet; + buf->offset = offsetof(net_buff_t, data); + memcpy(buf->data, buffer, plen); + kos_eth_input(buf); + } + u->input_processed = true; + return 1; } -net_device_t *vnet_init(int fd) { +static void +vnet_input_monitor(net_device_t *vnet) { + umka_sti(); + vnet_userdata_t *u = vnet->userdata; + int tapfd = u->tapfd; + struct pollfd pfd = {tapfd, POLLIN, 0}; + while(true) + { + if (u->input_processed && poll(&pfd, 1, 0)) { + u->input_processed = false; + raise(SIGUSR1); + umka_sti(); + } + } +} + +static void +dump_net_buff(net_buff_t *buf) { + for (size_t i = 0; i < buf->length; i++) { + printf("%2.2x ", buf->data[i]); + } + putchar('\n'); +} + +static STDCALL void +vnet_unload() { + printf("vnet_unload\n"); + COVERAGE_ON(); + COVERAGE_OFF(); +} + +static STDCALL void +vnet_reset() { + printf("vnet_reset\n"); + COVERAGE_ON(); + COVERAGE_OFF(); +} + +static STDCALL int +vnet_transmit(net_buff_t *buf) { + // TODO: Separate implementations for win32 and linux +#ifdef _WIN32 + assert(!"Function is not implemented for win32"); +#else + net_device_t *vnet; + __asm__ __inline__ __volatile__ ( + "nop" + : "=b"(vnet) + : + : "memory"); + + vnet_userdata_t *u = vnet->userdata; + printf("vnet_transmit: %d bytes\n", buf->length); + dump_net_buff(buf); + write(u->tapfd, buf->data, buf->length); + buf->length = 0; + COVERAGE_OFF(); + COVERAGE_ON(); + printf("vnet_transmit: done\n"); +#endif + return 0; +} + +net_device_t* +vnet_init() { // printf("vnet_init\n"); + int tapfd = tap_alloc(); vnet_userdata_t *u = (vnet_userdata_t*)malloc(sizeof(vnet_userdata_t)); - u->fd = fd; + u->tapfd = tapfd; + u->input_processed = true; net_device_t *vnet = (net_device_t*)malloc(sizeof(net_device_t)); *vnet = (net_device_t){ @@ -50,66 +223,13 @@ net_device_t *vnet_init(int fd) { .userdata = u, }; - kos_attach_int_handler(SIGUSR1, vnet_input, u); + kos_attach_int_handler(SIGUSR1, vnet_input, vnet); + fprintf(stderr, "### thread_start: %p\n", (void*)(uintptr_t)vnet_input_monitor); + uint8_t *stack = malloc(STACK_SIZE); + size_t tid = umka_new_sys_threads(0, vnet_input_monitor, stack + STACK_SIZE); + appdata_t *t = kos_slot_base + tid; + *(void**)((uint8_t*)t->pl0_stack+0x2000-12) = vnet; +// t->saved_esp0 = (uint8_t*)t->saved_esp0 - 8; return vnet; } - -STDCALL void -vnet_unload() { - printf("vnet_unload\n"); - COVERAGE_OFF(); - COVERAGE_ON(); -} - -STDCALL void -vnet_reset() { - printf("vnet_reset\n"); - COVERAGE_OFF(); - COVERAGE_ON(); -} - -static void dump_net_buff(net_buff_t *buf) { - for (size_t i = 0; i < buf->length; i++) { - printf("%2.2x ", buf->data[i]); - } - putchar('\n'); -} - -STDCALL int -vnet_transmit(net_buff_t *buf) { - // TODO: Separate implementations for win32 and linux -#ifdef _WIN32 - assert(!"Function is not implemented for win32"); -#else - net_device_t *vnet; - __asm__ __inline__ __volatile__ ( - "nop" - : "=b"(vnet) - : - : "memory"); - - vnet_userdata_t *u = vnet->userdata; - printf("vnet_transmit: %d bytes\n", buf->length); - dump_net_buff(buf); - write(u->fd, buf->data, buf->length); - buf->length = 0; - COVERAGE_OFF(); - COVERAGE_ON(); - printf("vnet_transmit: done\n"); -#endif - return 0; -} - -void vnet_receive_frame(net_device_t *dev, void *data, size_t size) { - net_buff_t *buf = kos_net_buff_alloc(size + offsetof(net_buff_t, data)); - if (!buf) { - fprintf(stderr, "[vnet] Can't allocate network buffer!\n"); - return; - } - buf->length = size; - buf->device = dev; - buf->offset = offsetof(net_buff_t, data); - memcpy(buf->data, data, size); - kos_eth_input(buf); -} diff --git a/vnet.h b/vnet.h index b134220..961f19d 100644 --- a/vnet.h +++ b/vnet.h @@ -1,22 +1,9 @@ #ifndef VNET_H_INCLUDED #define VNET_H_INCLUDED -#include -#include #include "umka.h" -net_device_t *vnet_init(int fd); - -STDCALL void -vnet_unload(void); - -STDCALL void -vnet_reset(void); - -STDCALL int -vnet_transmit(net_buff_t *buf); - -void -vnet_receive_frame(net_device_t *dev, void *data, size_t size); +net_device_t* +vnet_init(void); #endif // VNET_H_INCLUDED