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