Split vnet driver to generic vnet part, tap and file interfaces
Fix most compilation issues of umka_shell on Windows(R)(TM), not all of them.
This commit is contained in:
parent
0fdfde2b5b
commit
be21f83af2
12
README
12
README
@ -89,15 +89,15 @@ Testing
|
||||
|
||||
# Copy ACPI tables and PCI configs
|
||||
|
||||
$ sudo cp --parents /sys/firmware/acpi/tables/?SDT* /sys/bus/pci/devices/*/config .
|
||||
# cp --parents /sys/firmware/acpi/tables/?SDT* /sys/bus/pci/devices/*/config .
|
||||
|
||||
# Manage tap device
|
||||
|
||||
$ sudo ip tuntap add dev tap0 mode tap
|
||||
$ sudo ip link set tap0 address 00:11:00:00:00:00
|
||||
$ sudo ip addr add 10.50.0.1/24 dev tap0
|
||||
$ sudo ip link set up dev tap0
|
||||
$ sudo ip tuntap del dev tap0 mode tap
|
||||
# ip tuntap add dev tap0 mode tap
|
||||
# ip link set tap0 address 00:11:00:00:00:00
|
||||
# ip addr add 10.50.0.1/24 dev tap0
|
||||
# ip link set up dev tap0
|
||||
# ip tuntap del dev tap0 mode tap
|
||||
|
||||
|
||||
Troubleshooting
|
||||
|
@ -10,7 +10,7 @@
|
||||
#ifndef IO_ASYNC_H_INCLUDED
|
||||
#define IO_ASYNC_H_INCLUDED
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stddef.h>
|
||||
|
||||
void *
|
||||
io_async_init();
|
142
linux/vnet/tap.c
Normal file
142
linux/vnet/tap.c
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
UMKa - User-Mode KolibriOS developer tools
|
||||
vnet - virtual network card, tap interface
|
||||
|
||||
Copyright (C) 2023 Ivan Baravy <dunkaist@gmail.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_tun.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "trace.h"
|
||||
#include "vnet.h"
|
||||
|
||||
#define TAP_DEV "/dev/net/tun"
|
||||
|
||||
static STDCALL void
|
||||
vnet_unload_tap() {
|
||||
printf("vnet_unload\n");
|
||||
COVERAGE_ON();
|
||||
COVERAGE_OFF();
|
||||
}
|
||||
|
||||
static STDCALL void
|
||||
vnet_reset_tap() {
|
||||
printf("vnet_reset\n");
|
||||
COVERAGE_ON();
|
||||
COVERAGE_OFF();
|
||||
}
|
||||
|
||||
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 int
|
||||
vnet_transmit_tap(net_buff_t *buf) {
|
||||
struct vnet *net;
|
||||
__asm__ __inline__ __volatile__ (
|
||||
"nop"
|
||||
: "=b"(net)
|
||||
:
|
||||
: "memory");
|
||||
|
||||
printf("vnet_transmit: %d bytes\n", buf->length);
|
||||
dump_net_buff(buf);
|
||||
write(net->fdout, buf->data, buf->length);
|
||||
buf->length = 0;
|
||||
COVERAGE_OFF();
|
||||
COVERAGE_ON();
|
||||
printf("vnet_transmit: done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct vnet *
|
||||
vnet_init_tap() {
|
||||
struct ifreq ifr = {.ifr_name = UMKA_VNET_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 NULL;
|
||||
}
|
||||
|
||||
if( (err = ioctl(fd, TUNSETIFF, &ifr)) < 0 ) {
|
||||
perror("ioctl(TUNSETIFF)");
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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 NULL;
|
||||
}
|
||||
|
||||
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 NULL;
|
||||
}
|
||||
|
||||
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 NULL;
|
||||
}
|
||||
|
||||
if ((err = ioctl(sockfd, SIOCGIFFLAGS, &ifr)) < 0) {
|
||||
perror("ioctl(SIOCGIFFLAGS)");
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
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 NULL;
|
||||
}
|
||||
|
||||
struct vnet *net = malloc(sizeof(struct vnet));
|
||||
net->netdev.device_type = NET_TYPE_ETH;
|
||||
net->netdev.mtu = 1514;
|
||||
net->netdev.name = "UMK0770";
|
||||
|
||||
net->netdev.unload = vnet_unload_tap;
|
||||
net->netdev.reset = vnet_reset_tap;
|
||||
net->netdev.transmit = vnet_transmit_tap;
|
||||
|
||||
net->fdin = fd;
|
||||
net->fdout = fd;
|
||||
net->input_processed = 1;
|
||||
|
||||
return net;
|
||||
}
|
41
makefile
41
makefile
@ -30,15 +30,15 @@ CFLAGS_32=$(CFLAGS) -m32 -D_FILE_OFFSET_BITS=64 -D__USE_TIME_BITS64
|
||||
LDFLAGS=-no-pie
|
||||
LDFLAGS_32=$(LDFLAGS) -m32
|
||||
|
||||
ifeq ($(HOST),linux)
|
||||
#ifeq ($(HOST),linux)
|
||||
FASM_INCLUDE=$(KOLIBRIOS)/kernel/trunk;$(KOLIBRIOS)/programs/develop/libraries/libcrash/hash
|
||||
FASM=INCLUDE="$(FASM_INCLUDE)" $(FASM_EXE) $(FASM_FLAGS)
|
||||
else ifeq ($(HOST),windows)
|
||||
FASM_INCLUDE=$(KOLIBRIOS)\kernel\trunk;$(KOLIBRIOS)\programs\develop\libraries\libcrash\hash
|
||||
FASM=set "INCLUDE=$(FASM_INCLUDE)" && $(FASM_EXE) $(FASM_FLAGS)
|
||||
else
|
||||
$(error your OS is not supported)
|
||||
endif
|
||||
#else ifeq ($(HOST),windows)
|
||||
# FASM_INCLUDE=$(KOLIBRIOS)\kernel\trunk;$(KOLIBRIOS)\programs\develop\libraries\libcrash\hash
|
||||
# FASM=set "INCLUDE=$(FASM_INCLUDE)" && $(FASM_EXE) $(FASM_FLAGS)
|
||||
#else
|
||||
# $(error your OS is not supported)
|
||||
#endif
|
||||
|
||||
ifeq ($(HOST),linux)
|
||||
all: umka_shell umka_fuse umka_os umka_gen_devices_dat umka.sym umka.prp \
|
||||
@ -56,20 +56,21 @@ test: umka_shell
|
||||
@cd test && make clean all && cd ../
|
||||
|
||||
umka_shell: umka_shell.o umka.o shell.o trace.o trace_lbr.o vdisk.o \
|
||||
vdisk/raw.o vdisk/qcow2.o vdisk/miniz/miniz.a vnet.o lodepng.o \
|
||||
$(HOST)/pci.o $(HOST)/thread.o io.o $(HOST)/io_async.o umkart.o \
|
||||
optparse32.o bestline32.o
|
||||
vdisk/raw.o vdisk/qcow2.o vdisk/miniz/miniz.a vnet.o \
|
||||
$(HOST)/vnet/tap.o vnet/file.o lodepng.o $(HOST)/pci.o \
|
||||
$(HOST)/thread.o umkaio.o $(HOST)/io_async.o umkart.o optparse32.o \
|
||||
bestline32.o
|
||||
$(CC) $(LDFLAGS_32) $^ -o $@ -T umka.ld
|
||||
|
||||
umka_fuse: umka_fuse.o umka.o trace.o trace_lbr.o vdisk.o vdisk/raw.o \
|
||||
vdisk/qcow2.o vdisk/miniz/miniz.a $(HOST)/pci.o $(HOST)/thread.o \
|
||||
io.o $(HOST)/io_async.o
|
||||
umkaio.o $(HOST)/io_async.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 vdisk/raw.o vdisk/qcow2.o \
|
||||
vdisk/miniz/miniz.a vnet.o trace.o trace_lbr.o $(HOST)/pci.o \
|
||||
$(HOST)/thread.o io.o $(HOST)/io_async.o umkart.o bestline32.o \
|
||||
optparse32.o
|
||||
vdisk/miniz/miniz.a vnet.o $(HOST)/vnet/tap.o vnet/file.o trace.o \
|
||||
trace_lbr.o $(HOST)/pci.o $(HOST)/thread.o umkaio.o \
|
||||
$(HOST)/io_async.o umkart.o bestline32.o optparse32.o
|
||||
$(CC) $(LDFLAGS_32) `sdl2-config --libs` $^ -o $@ -T umka.ld
|
||||
|
||||
umka_gen_devices_dat: umka_gen_devices_dat.o umka.o $(HOST)/pci.o \
|
||||
@ -82,10 +83,10 @@ umka.o umka.fas: umka.asm
|
||||
shell.o: shell.c lodepng.h
|
||||
$(CC) $(CFLAGS_32) -c $<
|
||||
|
||||
io.o: io.c io.h
|
||||
umkaio.o: umkaio.c umkaio.h
|
||||
$(CC) $(CFLAGS_32) -D_DEFAULT_SOURCE -c $< -o $@
|
||||
|
||||
$(HOST)/io_async.o: $(HOST)/io_async.c $(HOST)/io_async.h
|
||||
$(HOST)/io_async.o: $(HOST)/io_async.c io_async.h
|
||||
$(CC) $(CFLAGS_32) -D_DEFAULT_SOURCE -c $< -o $@
|
||||
|
||||
$(HOST)/thread.o: $(HOST)/thread.c
|
||||
@ -160,9 +161,15 @@ vdisk/miniz/miniz.o: vdisk/miniz/miniz.c vdisk/miniz/miniz.h
|
||||
vdisk/miniz/miniz.a: vdisk/miniz/miniz.o vdisk/miniz/miniz_tinfl.o vdisk/miniz/miniz_tdef.o
|
||||
$(AR) --target=elf32-i386 r $@ $^
|
||||
|
||||
vnet.o: vnet.c
|
||||
vnet.o: vnet.c vnet.h
|
||||
$(CC) $(CFLAGS_32) -c $<
|
||||
|
||||
$(HOST)/vnet/tap.o: $(HOST)/vnet/tap.c vnet/tap.h
|
||||
$(CC) $(CFLAGS_32) -c $< -o $@
|
||||
|
||||
vnet/file.o: vnet/file.c vnet/file.h
|
||||
$(CC) $(CFLAGS_32) -c $< -o $@
|
||||
|
||||
umka_shell.o: umka_shell.c umka.h trace.h
|
||||
$(CC) $(CFLAGS_32) -c $<
|
||||
|
||||
|
64
shell.c
64
shell.c
@ -25,6 +25,9 @@
|
||||
// TODO: Cleanup
|
||||
#ifndef _WIN32
|
||||
#include <arpa/inet.h>
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#include "shell.h"
|
||||
@ -78,13 +81,13 @@ umka_run_cmd_sync(struct shell_ctx *ctx) {
|
||||
}
|
||||
atomic_store_explicit(&cmd->status, UMKA_CMD_STATUS_DONE,
|
||||
memory_order_release);
|
||||
cnd_signal(&ctx->cmd_done);
|
||||
pthread_cond_signal(&ctx->cmd_done);
|
||||
}
|
||||
|
||||
static void
|
||||
umka_run_cmd(struct shell_ctx *ctx) {
|
||||
if (atomic_load_explicit(ctx->running, memory_order_acquire)) {
|
||||
cnd_wait(&ctx->cmd_done, &ctx->cmd_mutex);
|
||||
pthread_cond_wait(&ctx->cmd_done, &ctx->cmd_mutex);
|
||||
} else {
|
||||
umka_run_cmd_sync(ctx);
|
||||
}
|
||||
@ -109,20 +112,20 @@ const char *f70_status_name[] = {
|
||||
static const char *
|
||||
get_f70_status_name(int s) {
|
||||
switch (s) {
|
||||
case ERROR_SUCCESS:
|
||||
case KOS_ERROR_SUCCESS:
|
||||
// return "";
|
||||
case ERROR_DISK_BASE:
|
||||
case ERROR_UNSUPPORTED_FS:
|
||||
case ERROR_UNKNOWN_FS:
|
||||
case ERROR_PARTITION:
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
case ERROR_END_OF_FILE:
|
||||
case ERROR_MEMORY_POINTER:
|
||||
case ERROR_DISK_FULL:
|
||||
case ERROR_FS_FAIL:
|
||||
case ERROR_ACCESS_DENIED:
|
||||
case ERROR_DEVICE:
|
||||
case ERROR_OUT_OF_MEMORY:
|
||||
case KOS_ERROR_DISK_BASE:
|
||||
case KOS_ERROR_UNSUPPORTED_FS:
|
||||
case KOS_ERROR_UNKNOWN_FS:
|
||||
case KOS_ERROR_PARTITION:
|
||||
case KOS_ERROR_FILE_NOT_FOUND:
|
||||
case KOS_ERROR_END_OF_FILE:
|
||||
case KOS_ERROR_MEMORY_POINTER:
|
||||
case KOS_ERROR_DISK_FULL:
|
||||
case KOS_ERROR_FS_FAIL:
|
||||
case KOS_ERROR_ACCESS_DENIED:
|
||||
case KOS_ERROR_DEVICE:
|
||||
case KOS_ERROR_OUT_OF_MEMORY:
|
||||
return f70_status_name[s];
|
||||
default:
|
||||
return "unknown";
|
||||
@ -144,7 +147,7 @@ print_f70_status(struct shell_ctx *ctx, f7080ret_t *r, int use_ebx) {
|
||||
fprintf(ctx->fout, "status = %d %s", r->status,
|
||||
get_f70_status_name(r->status));
|
||||
if (use_ebx
|
||||
&& (r->status == ERROR_SUCCESS || r->status == ERROR_END_OF_FILE)) {
|
||||
&& (r->status == KOS_ERROR_SUCCESS || r->status == KOS_ERROR_END_OF_FILE)) {
|
||||
fprintf(ctx->fout, ", count = %d", r->count);
|
||||
}
|
||||
fprintf(ctx->fout, "\n");
|
||||
@ -2326,8 +2329,8 @@ ls_range(struct shell_ctx *ctx, f7080s1arg_t *fX0, f70or80_t f70or80) {
|
||||
f7080s1info_t *dir = fX0->buf;
|
||||
int ok = (r.count <= fX0->size);
|
||||
ok &= (dir->cnt == r.count);
|
||||
ok &= (r.status == ERROR_SUCCESS && r.count == fX0->size)
|
||||
|| (r.status == ERROR_END_OF_FILE && r.count < fX0->size);
|
||||
ok &= (r.status == KOS_ERROR_SUCCESS && r.count == fX0->size)
|
||||
|| (r.status == KOS_ERROR_END_OF_FILE && r.count < fX0->size);
|
||||
assert(ok);
|
||||
if (!ok)
|
||||
break;
|
||||
@ -2338,7 +2341,7 @@ ls_range(struct shell_ctx *ctx, f7080s1arg_t *fX0, f70or80_t f70or80) {
|
||||
fprintf(ctx->fout, "%s %s\n", fattr, bdfe->name);
|
||||
bdfe = (bdfe_t*)((uintptr_t)bdfe + bdfe_len);
|
||||
}
|
||||
if (r.status == ERROR_END_OF_FILE) {
|
||||
if (r.status == KOS_ERROR_END_OF_FILE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2360,8 +2363,8 @@ ls_all(struct shell_ctx *ctx, f7080s1arg_t *fX0, f70or80_t f70or80) {
|
||||
fX0->offset += dir->cnt;
|
||||
int ok = (r.count <= fX0->size);
|
||||
ok &= (dir->cnt == r.count);
|
||||
ok &= (r.status == ERROR_SUCCESS && r.count == fX0->size)
|
||||
|| (r.status == ERROR_END_OF_FILE && r.count < fX0->size);
|
||||
ok &= (r.status == KOS_ERROR_SUCCESS && r.count == fX0->size)
|
||||
|| (r.status == KOS_ERROR_END_OF_FILE && r.count < fX0->size);
|
||||
assert(ok);
|
||||
if (!ok)
|
||||
break;
|
||||
@ -2373,7 +2376,7 @@ ls_all(struct shell_ctx *ctx, f7080s1arg_t *fX0, f70or80_t f70or80) {
|
||||
fprintf(ctx->fout, "%s %s\n", fattr, bdfe->name);
|
||||
bdfe = (bdfe_t*)((uintptr_t)bdfe + bdfe_len);
|
||||
}
|
||||
if (r.status == ERROR_END_OF_FILE) {
|
||||
if (r.status == KOS_ERROR_END_OF_FILE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2538,7 +2541,7 @@ cmd_stat(struct shell_ctx *ctx, int argc, char **argv, f70or80_t f70or80) {
|
||||
umka_sys_lfn(&fX0, &r, f70or80);
|
||||
COVERAGE_OFF();
|
||||
print_f70_status(ctx, &r, 0);
|
||||
if (r.status != ERROR_SUCCESS)
|
||||
if (r.status != KOS_ERROR_SUCCESS)
|
||||
return;
|
||||
char fattr[KF_ATTR_CNT+1];
|
||||
convert_f70_file_attr(file.attr, fattr);
|
||||
@ -2648,7 +2651,7 @@ cmd_read(struct shell_ctx *ctx, int argc, char **argv, f70or80_t f70or80,
|
||||
COVERAGE_OFF();
|
||||
|
||||
print_f70_status(ctx, &r, 1);
|
||||
if (r.status == ERROR_SUCCESS || r.status == ERROR_END_OF_FILE) {
|
||||
if (r.status == KOS_ERROR_SUCCESS || r.status == KOS_ERROR_END_OF_FILE) {
|
||||
if (dump_bytes)
|
||||
print_bytes(ctx, fX0.buf, r.count);
|
||||
if (dump_hash)
|
||||
@ -2889,9 +2892,9 @@ cmd_net_add_device(struct shell_ctx *ctx, int argc, char **argv) {
|
||||
fputs(usage, ctx->fout);
|
||||
return;
|
||||
}
|
||||
net_device_t *vnet = vnet_init(); // FIXME: list like block devices
|
||||
struct vnet *net = vnet_init(VNET_TAP); // TODO: list like block devices
|
||||
COVERAGE_ON();
|
||||
int32_t dev_num = kos_net_add_device(vnet);
|
||||
int32_t dev_num = kos_net_add_device(&net->netdev);
|
||||
COVERAGE_OFF();
|
||||
fprintf(ctx->fout, "device number: %" PRIi32 "\n", dev_num);
|
||||
}
|
||||
@ -3990,7 +3993,7 @@ cmd_help(struct shell_ctx *ctx, int argc, char **argv) {
|
||||
|
||||
void *
|
||||
run_test(struct shell_ctx *ctx) {
|
||||
mtx_lock(&ctx->cmd_mutex);
|
||||
pthread_mutex_lock(&ctx->cmd_mutex);
|
||||
int is_tty = isatty(fileno(ctx->fin));
|
||||
char **argv = (char**)calloc(sizeof(char*), (MAX_COMMAND_ARGS + 1));
|
||||
bestlineSetCompletionCallback(completion);
|
||||
@ -4030,7 +4033,8 @@ run_test(struct shell_ctx *ctx) {
|
||||
free(argv);
|
||||
bestlineHistorySave(ctx->hist_file);
|
||||
|
||||
mtx_unlock(&ctx->cmd_mutex);
|
||||
fclose(ctx->fin);
|
||||
pthread_mutex_unlock(&ctx->cmd_mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -4046,8 +4050,8 @@ shell_init(int reproducible, const char *hist_file, struct umka_ctx *umka,
|
||||
ctx->fin = fin;
|
||||
ctx->fout = fout;
|
||||
ctx->running = running;
|
||||
cnd_init(&ctx->cmd_done);
|
||||
mtx_init(&ctx->cmd_mutex, mtx_plain);
|
||||
pthread_cond_init(&ctx->cmd_done, NULL);
|
||||
pthread_mutex_init(&ctx->cmd_mutex, NULL);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
8
shell.h
8
shell.h
@ -11,9 +11,9 @@
|
||||
#define SHELL_H_INCLUDED
|
||||
|
||||
#include <stdio.h>
|
||||
#include <threads.h>
|
||||
#include <pthread.h>
|
||||
#include "umka.h"
|
||||
#include "io.h"
|
||||
#include "umkaio.h"
|
||||
|
||||
enum shell_var_type {
|
||||
SHELL_VAR_SINT,
|
||||
@ -42,8 +42,8 @@ struct shell_ctx {
|
||||
FILE *fin;
|
||||
FILE *fout;
|
||||
const int *running;
|
||||
cnd_t cmd_done;
|
||||
mtx_t cmd_mutex;
|
||||
pthread_cond_t cmd_done;
|
||||
pthread_mutex_t cmd_mutex;
|
||||
|
||||
};
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
UMKa - User-Mode KolibriOS developer tools
|
||||
|
||||
Copyright (C) 2019-2020,2022 Ivan Baravy <dunkaist@gmail.com>
|
||||
Copyright (C) 2019-2020,2022-2023 Ivan Baravy <dunkaist@gmail.com>
|
||||
Copyright (C) 2021 Magomed Kostoev <mkostoevr@yandex.ru>
|
||||
*/
|
||||
|
||||
@ -36,6 +36,7 @@ uint64_t rdmsr(uint32_t reg)
|
||||
exit(1);
|
||||
}
|
||||
#else
|
||||
(void)reg;
|
||||
printf("STUB: %s:%d", __FILE__, __LINE__);
|
||||
#endif
|
||||
|
||||
@ -59,6 +60,8 @@ void wrmsr(uint32_t reg, uint64_t data)
|
||||
|
||||
close(fd);
|
||||
#else
|
||||
(void)reg;
|
||||
(void)data;
|
||||
printf("STUB: %s:%d", __FILE__, __LINE__);
|
||||
#endif
|
||||
}
|
||||
|
9
umka.asm
9
umka.asm
@ -1023,7 +1023,6 @@ acpi_root dd ?
|
||||
acpi_dev_next dd ?
|
||||
endg
|
||||
|
||||
;sys_msg_board equ __pex0
|
||||
delay_ms equ __pex1
|
||||
|
||||
include fix pew
|
||||
@ -1047,14 +1046,13 @@ include 'kernel.asm'
|
||||
purge jmp
|
||||
restore bios32_entry, tmp_page_tabs
|
||||
purge org,delay_ms
|
||||
;purge sys_msg_board
|
||||
restore org,delay_ms
|
||||
;restore sys_msg_board
|
||||
|
||||
coverage_end:
|
||||
|
||||
|
||||
section '.bss.coverage' executable writable align 64
|
||||
; cov for coverage; otherwide fasm complains with 'name too long' for MS COFF
|
||||
section '.bss.cov' executable writable align 64
|
||||
struct coverage_branch
|
||||
to_cnt DQ ?
|
||||
from_cnt DQ ?
|
||||
@ -1066,7 +1064,8 @@ coverage_table rb COVERAGE_TABLE_SIZE * sizeof.coverage_branch
|
||||
pubsym coverage_table
|
||||
|
||||
|
||||
section '.data.boot' writeable align 0x1000
|
||||
; bt for boot; otherwide fasm complains with 'name too long' for MS COFF
|
||||
section '.data.bt' writeable align 0x1000
|
||||
BOOT boot_data
|
||||
virtual at BOOT
|
||||
BOOT_LO boot_data
|
||||
|
47
umka.h
47
umka.h
@ -41,6 +41,9 @@ struct umka_ctx {
|
||||
#define KEYBOARD_MODE_ASCII 0
|
||||
#define KEYBOARD_MODE_SCANCODES 1
|
||||
|
||||
#define UMKA_IRQ_MOUSE 14
|
||||
#define UMKA_IRQ_NETWORK 15
|
||||
|
||||
enum kos_lang {
|
||||
KOS_LANG_EN = 1,
|
||||
KOS_LANG_FIRST = KOS_LANG_EN,
|
||||
@ -195,19 +198,19 @@ typedef enum {
|
||||
} f70or80_t;
|
||||
|
||||
enum {
|
||||
ERROR_SUCCESS,
|
||||
ERROR_DISK_BASE,
|
||||
ERROR_UNSUPPORTED_FS,
|
||||
ERROR_UNKNOWN_FS,
|
||||
ERROR_PARTITION,
|
||||
ERROR_FILE_NOT_FOUND,
|
||||
ERROR_END_OF_FILE,
|
||||
ERROR_MEMORY_POINTER,
|
||||
ERROR_DISK_FULL,
|
||||
ERROR_FS_FAIL,
|
||||
ERROR_ACCESS_DENIED,
|
||||
ERROR_DEVICE,
|
||||
ERROR_OUT_OF_MEMORY,
|
||||
KOS_ERROR_SUCCESS,
|
||||
KOS_ERROR_DISK_BASE,
|
||||
KOS_ERROR_UNSUPPORTED_FS,
|
||||
KOS_ERROR_UNKNOWN_FS,
|
||||
KOS_ERROR_PARTITION,
|
||||
KOS_ERROR_FILE_NOT_FOUND,
|
||||
KOS_ERROR_END_OF_FILE,
|
||||
KOS_ERROR_MEMORY_POINTER,
|
||||
KOS_ERROR_DISK_FULL,
|
||||
KOS_ERROR_FS_FAIL,
|
||||
KOS_ERROR_ACCESS_DENIED,
|
||||
KOS_ERROR_DEVICE,
|
||||
KOS_ERROR_OUT_OF_MEMORY,
|
||||
};
|
||||
|
||||
typedef struct lhead lhead_t;
|
||||
@ -501,7 +504,6 @@ struct net_device_t {
|
||||
uint32_t hwacc; // bitmask stating enabled HW accelerations (offload
|
||||
// engines)
|
||||
uint8_t mac[6];
|
||||
void *userdata; // not in kolibri, umka-specific
|
||||
}; // NET_DEVICE
|
||||
|
||||
typedef struct {
|
||||
@ -1085,13 +1087,6 @@ static_assert(sizeof(appdata_t) == 256, "must be 0x100 bytes long");
|
||||
#define UMKA_OS 3
|
||||
#define UMKA_GEN_DEVICES_DAT 4
|
||||
|
||||
#define MAX_PRIORITY 0 // highest, used for kernel tasks
|
||||
#define USER_PRIORITY 1 // default
|
||||
#define IDLE_PRIORITY 2 // lowest, only IDLE thread goes here
|
||||
#define NR_SCHED_QUEUES 3 // MUST equal IDLE_PRIORYTY + 1
|
||||
|
||||
extern appdata_t *kos_scheduler_current[NR_SCHED_QUEUES];
|
||||
|
||||
extern uint8_t kos_redraw_background;
|
||||
extern size_t kos_task_count;
|
||||
extern wdata_t kos_window_data[];
|
||||
@ -1130,14 +1125,16 @@ umka_scheduler_add_thread(appdata_t *thread, int32_t priority) {
|
||||
: "memory", "cc");
|
||||
}
|
||||
|
||||
#define MAX_PRIORITY 0
|
||||
#define USER_PRIORITY 1
|
||||
#define IDLE_PRIORITY 2
|
||||
#define NR_SCHED_QUEUES 3
|
||||
#define KOS_MAX_PRIORITY 0 // highest, used for kernel tasks
|
||||
#define KOS_USER_PRIORITY 1 // default
|
||||
#define KOS_IDLE_PRIORITY 2 // lowest, only IDLE thread goes here
|
||||
#define KOS_NR_SCHED_QUEUES 3 // MUST equal IDLE_PRIORYTY + 1
|
||||
|
||||
#define SCHEDULE_ANY_PRIORITY 0
|
||||
#define SCHEDULE_HIGHER_PRIORITY 1
|
||||
|
||||
extern appdata_t *kos_scheduler_current[KOS_NR_SCHED_QUEUES];
|
||||
|
||||
typedef struct {
|
||||
appdata_t *appdata;
|
||||
void *taskdata;
|
||||
|
2
umka.ld
2
umka.ld
@ -19,7 +19,7 @@ SECTIONS
|
||||
{
|
||||
.data.boot BLOCK(0x1000) :
|
||||
{
|
||||
*(.data.boot)
|
||||
*(.data.bt)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include "io.h"
|
||||
#include "umkaio.h"
|
||||
#include "vdisk.h"
|
||||
|
||||
#define DIRENTS_TO_READ 100
|
||||
|
50
umka_os.c
50
umka_os.c
@ -112,7 +112,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++) {
|
||||
for (int i = 0; i < KOS_NR_SCHED_QUEUES; i++) {
|
||||
fprintf(stderr, "sched queue #%i:", i);
|
||||
appdata_t *p_begin = kos_scheduler_current[i];
|
||||
appdata_t *p = p_begin;
|
||||
@ -186,7 +186,7 @@ hw_int(int signo, siginfo_t *info, void *context) {
|
||||
}
|
||||
|
||||
int
|
||||
sdlthr(void *arg) {
|
||||
umka_display(void *arg) {
|
||||
(void)arg;
|
||||
if(SDL_Init(SDL_INIT_VIDEO) < 0)
|
||||
{
|
||||
@ -194,7 +194,10 @@ sdlthr(void *arg) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_Window *window = SDL_CreateWindow("LFB Viewer SDL2",
|
||||
char title[64];
|
||||
sprintf(title, "umka0 %ux%u %ubpp", kos_display.width, kos_display.height,
|
||||
kos_display.bits_per_pixel);
|
||||
SDL_Window *window = SDL_CreateWindow(title,
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
kos_display.width,
|
||||
@ -257,10 +260,8 @@ umka_thread_cmd_runner() {
|
||||
static int
|
||||
umka_monitor(void *arg) {
|
||||
(void)arg;
|
||||
os->shell->fin = stdin;
|
||||
os->shell->fout = stdout;
|
||||
run_test(os->shell);
|
||||
return 0;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -280,11 +281,13 @@ int
|
||||
main(int argc, char *argv[]) {
|
||||
(void)argc;
|
||||
const char *usage = "umka_os [-i <infile>] [-o <outfile>]"
|
||||
" [-b <boardlog>]\n";
|
||||
" [-b <boardlog>] [\n";
|
||||
if (coverage) {
|
||||
trace_begin();
|
||||
}
|
||||
|
||||
int show_display = 0;
|
||||
|
||||
umka_sti();
|
||||
|
||||
build_history_filename();
|
||||
@ -292,9 +295,11 @@ main(int argc, char *argv[]) {
|
||||
bestlineSetHintsCallback(hints);
|
||||
bestlineHistoryLoad(history_filename);
|
||||
|
||||
const char *startupfile = NULL;
|
||||
const char *infile = NULL;
|
||||
const char *outfile = NULL;
|
||||
const char *boardlogfile = NULL;
|
||||
FILE *fstartup = NULL;
|
||||
FILE *fin = stdin;
|
||||
FILE *fout = stdout;
|
||||
FILE *fboardlog;
|
||||
@ -303,17 +308,23 @@ main(int argc, char *argv[]) {
|
||||
int opt;
|
||||
optparse_init(&options, argv);
|
||||
|
||||
while ((opt = optparse(&options, "b:i:o:s:")) != -1) {
|
||||
while ((opt = optparse(&options, "b:di:o:s:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'b':
|
||||
boardlogfile = options.optarg;
|
||||
break;
|
||||
case 'd':
|
||||
show_display = 1;
|
||||
break;
|
||||
case 'i':
|
||||
infile = options.optarg;
|
||||
break;
|
||||
case 'o':
|
||||
outfile = options.optarg;
|
||||
break;
|
||||
case 's':
|
||||
startupfile = options.optarg;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "bad option: %c\n", opt);
|
||||
fputs(usage, stderr);
|
||||
@ -379,8 +390,8 @@ main(int argc, char *argv[]) {
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
|
||||
if (sigaction(SIGUSR2, &sa, NULL) == -1) {
|
||||
fprintf(stderr, "Can't install SIGUSR2 handler!\n");
|
||||
if (sigaction(SIGSYS, &sa, NULL) == -1) {
|
||||
fprintf(stderr, "Can't install SIGSYS handler!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -397,14 +408,19 @@ main(int argc, char *argv[]) {
|
||||
kos_boot.pitch = UMKA_DEFAULT_DISPLAY_WIDTH * UMKA_DEFAULT_DISPLAY_BPP / 8;
|
||||
|
||||
run_test(os->shell);
|
||||
// umka_stack_init();
|
||||
os->shell->fin = stdin;
|
||||
umka_stack_init();
|
||||
|
||||
// load_app_host("../apps/board_cycle", app);
|
||||
load_app_host("../apps/readdir", app);
|
||||
// load_app("/rd/1/loader");
|
||||
|
||||
// net_device_t *vnet = vnet_init();
|
||||
// kos_net_add_device(vnet);
|
||||
struct vnet *net = vnet_init(VNET_TAP);
|
||||
if (net) {
|
||||
kos_net_add_device(&net->netdev);
|
||||
} else {
|
||||
fprintf(stderr, "[!] can't initialize vnet device\n");
|
||||
}
|
||||
|
||||
char devname[64];
|
||||
for (size_t i = 0; i < umka_sys_net_get_dev_count(); i++) {
|
||||
@ -442,7 +458,7 @@ main(int argc, char *argv[]) {
|
||||
}
|
||||
*/
|
||||
|
||||
kos_attach_int_handler(14, hw_int_mouse, NULL);
|
||||
kos_attach_int_handler(UMKA_IRQ_MOUSE, hw_int_mouse, NULL);
|
||||
|
||||
thread_start(1, umka_thread_board, THREAD_STACK_SIZE);
|
||||
thread_start(1, umka_thread_cmd_runner, THREAD_STACK_SIZE);
|
||||
@ -454,8 +470,10 @@ main(int argc, char *argv[]) {
|
||||
thrd_t thrd_monitor;
|
||||
thrd_create(&thrd_monitor, umka_monitor, NULL);
|
||||
|
||||
thrd_t thrd_screen;
|
||||
thrd_create(&thrd_screen, sdlthr, NULL);
|
||||
if (show_display) {
|
||||
thrd_t thrd_display;
|
||||
thrd_create(&thrd_display, umka_display, NULL);
|
||||
}
|
||||
|
||||
setitimer(ITIMER_REAL, &timeout, NULL);
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include <unistd.h>
|
||||
#include "optparse.h"
|
||||
#include "shell.h"
|
||||
#include "io.h"
|
||||
#include "umkaio.h"
|
||||
#include "trace.h"
|
||||
|
||||
#define HIST_FILE_BASENAME ".umka_shell.history"
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include "io.h"
|
||||
#include "umkaio.h"
|
||||
#include "io_async.h"
|
||||
|
||||
struct umka_io *
|
@ -7,8 +7,8 @@
|
||||
Copyright (C) 2023 Ivan Baravy <dunkaist@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef IO_H_INCLUDED
|
||||
#define IO_H_INCLUDED
|
||||
#ifndef UMKAIO_H_INCLUDED
|
||||
#define UMKAIO_H_INCLUDED
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
@ -29,4 +29,4 @@ io_read(int fd, void *buf, size_t count, struct umka_io *io);
|
||||
ssize_t
|
||||
io_write(int fd, const void *buf, size_t count, struct umka_io *io);
|
||||
|
||||
#endif // IO_H_INCLUDED
|
||||
#endif // UMKAIO_H_INCLUDED
|
5
umkart.c
5
umkart.c
@ -6,12 +6,13 @@
|
||||
Copyright (C) 2021, 2023 Ivan Baravy <dunkaist@gmail.com>
|
||||
*/
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include <stdio.h>
|
||||
#include <threads.h>
|
||||
#include <stdlib.h>
|
||||
#include "umka.h"
|
||||
#include "shell.h"
|
||||
|
||||
uint32_t umka_irq_number;
|
||||
|
||||
struct devices_dat_entry {
|
||||
uint8_t fun:3;
|
||||
uint8_t dev:5;
|
||||
|
6
umkart.h
6
umkart.h
@ -6,8 +6,8 @@
|
||||
Copyright (C) 2021, 2023 Ivan Baravy <dunkaist@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef UTIL_H_INCLUDED
|
||||
#define UTIL_H_INCLUDED
|
||||
#ifndef UMKART_H_INCLUDED
|
||||
#define UMKART_H_INCLUDED
|
||||
|
||||
#include "umka.h"
|
||||
#include "shell.h"
|
||||
@ -20,4 +20,4 @@ dump_devices_dat(const char *filename);
|
||||
void
|
||||
copy_display_to_rgb888(void *to);
|
||||
|
||||
#endif // UTIL_H_INCLUDED
|
||||
#endif // UMKART_H_INCLUDED
|
||||
|
2
vdisk.c
2
vdisk.c
@ -27,7 +27,7 @@ vdisk_querymedia(void *userdata, diskmediainfo_t *minfo) {
|
||||
minfo->sector_size = disk->sect_size;
|
||||
minfo->capacity = disk->sect_cnt;
|
||||
COVERAGE_ON();
|
||||
return ERROR_SUCCESS;
|
||||
return KOS_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
STDCALL size_t
|
||||
|
@ -14,7 +14,11 @@
|
||||
#include "../trace.h"
|
||||
#include "qcow2.h"
|
||||
#include "miniz/miniz.h"
|
||||
#include "io.h"
|
||||
#include "umkaio.h"
|
||||
#ifdef _WIN32
|
||||
//#include <io.h>
|
||||
//#define open _open
|
||||
#endif
|
||||
|
||||
#define L1_MAX_LEN (32u*1024u*1024u)
|
||||
#define L1_MAX_ENTRIES (L1_MAX_LEN / sizeof(uint64_t))
|
||||
@ -179,7 +183,7 @@ vdisk_qcow2_read(void *userdata, void *buffer, off_t startsector,
|
||||
buffer = (uint8_t*)buffer + d->vdisk.sect_size;
|
||||
}
|
||||
COVERAGE_ON();
|
||||
return ERROR_SUCCESS;
|
||||
return KOS_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
STDCALL int
|
||||
@ -193,7 +197,7 @@ vdisk_qcow2_write(void *userdata, void *buffer, off_t startsector,
|
||||
(void)numsectors;
|
||||
fprintf(stderr, "[vdisk.qcow2] writing is not implemented");
|
||||
COVERAGE_ON();
|
||||
return ERROR_UNSUPPORTED_FS;
|
||||
return KOS_ERROR_UNSUPPORTED_FS;
|
||||
}
|
||||
|
||||
struct vdisk*
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include "vdisk.h"
|
||||
#include "io.h"
|
||||
#include "umkaio.h"
|
||||
|
||||
#define QCOW2_SUFFIX ".qcow2"
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "../trace.h"
|
||||
#include "io.h"
|
||||
#include "umkaio.h"
|
||||
#include "raw.h"
|
||||
|
||||
struct vdisk_raw {
|
||||
@ -38,7 +38,7 @@ vdisk_raw_read(void *userdata, void *buffer, off_t startsector,
|
||||
io_read(disk->fd, buffer, *numsectors * disk->vdisk.sect_size,
|
||||
disk->vdisk.io);
|
||||
COVERAGE_ON();
|
||||
return ERROR_SUCCESS;
|
||||
return KOS_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
STDCALL int
|
||||
@ -50,7 +50,7 @@ vdisk_raw_write(void *userdata, void *buffer, off_t startsector,
|
||||
io_write(disk->fd, buffer, *numsectors * disk->vdisk.sect_size,
|
||||
disk->vdisk.io);
|
||||
COVERAGE_ON();
|
||||
return ERROR_SUCCESS;
|
||||
return KOS_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
struct vdisk*
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include "vdisk.h"
|
||||
#include "io.h"
|
||||
#include "umkaio.h"
|
||||
|
||||
#define RAW_SUFFIX ".raw"
|
||||
|
||||
|
224
vnet.c
224
vnet.c
@ -4,115 +4,42 @@
|
||||
UMKa - User-Mode KolibriOS developer tools
|
||||
vnet - virtual network card
|
||||
|
||||
Copyright (C) 2020-2022 Ivan Baravy <dunkaist@gmail.com>
|
||||
Copyright (C) 2020-2023 Ivan Baravy <dunkaist@gmail.com>
|
||||
Copyright (C) 2021 Magomed Kostoev <mkostoevr@yandex.ru>
|
||||
*/
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_tun.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <netinet/in.h>
|
||||
#include <poll.h>
|
||||
#include <stdbool.h>
|
||||
#define _POSIX // to have SIGSYS on windows
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include "umka.h"
|
||||
#include "trace.h"
|
||||
#include "vnet.h"
|
||||
#include "vnet/tap.h"
|
||||
#include "vnet/file.h"
|
||||
|
||||
// TODO: Cleanup
|
||||
#ifndef _WIN32
|
||||
#include <arpa/inet.h>
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#define TAP_DEV "/dev/net/tun"
|
||||
#define UMKA_TAP_NAME "umka%d"
|
||||
|
||||
#define STACK_SIZE 0x10000
|
||||
|
||||
typedef struct {
|
||||
int tapfd;
|
||||
bool input_processed;
|
||||
} vnet_userdata_t;
|
||||
|
||||
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;
|
||||
struct vnet *net = udata;
|
||||
int fd = net->fdin;
|
||||
int plen = 0;
|
||||
fprintf(stderr, "[vnet] input interrupt\n");
|
||||
net_buff_t *buf = kos_net_buff_alloc(NET_BUFFER_SIZE);
|
||||
@ -120,8 +47,8 @@ vnet_input(void *udata) {
|
||||
fprintf(stderr, "[vnet] Can't allocate network buffer!\n");
|
||||
return 1;
|
||||
}
|
||||
buf->device = vnet;
|
||||
plen = read(tapfd, buf->data, NET_BUFFER_SIZE - offsetof(net_buff_t, data));
|
||||
buf->device = &net->netdev;
|
||||
plen = read(fd, buf->data, NET_BUFFER_SIZE - offsetof(net_buff_t, data));
|
||||
if (plen == -1) {
|
||||
plen = 0; // we have just allocated a buffer, so we have to submit it
|
||||
}
|
||||
@ -134,112 +61,63 @@ vnet_input(void *udata) {
|
||||
buf->length = plen;
|
||||
buf->offset = offsetof(net_buff_t, data);
|
||||
kos_eth_input(buf);
|
||||
u->input_processed = true;
|
||||
net->input_processed = 1;
|
||||
|
||||
return 1; // acknowledge our interrupt
|
||||
}
|
||||
|
||||
static void
|
||||
vnet_input_monitor(net_device_t *vnet) {
|
||||
vnet_input_monitor(struct vnet *net) {
|
||||
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);
|
||||
struct pollfd pfd = {net->fdin, POLLIN, 0};
|
||||
while (1) {
|
||||
if (net->input_processed && poll(&pfd, 1, 0)) {
|
||||
net->input_processed = 0;
|
||||
umka_irq_number = UMKA_IRQ_NETWORK;
|
||||
raise(SIGSYS);
|
||||
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() {
|
||||
struct vnet *
|
||||
vnet_init(enum vnet_type type) {
|
||||
// printf("vnet_init\n");
|
||||
int tapfd = tap_alloc();
|
||||
vnet_userdata_t *u = (vnet_userdata_t*)malloc(sizeof(vnet_userdata_t));
|
||||
u->tapfd = tapfd;
|
||||
u->input_processed = true;
|
||||
struct vnet *net;
|
||||
switch (type) {
|
||||
case VNET_FILE:
|
||||
net = vnet_init_file();
|
||||
break;
|
||||
case VNET_TAP:
|
||||
net = vnet_init_tap();
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "[vnet] bad vnet type: %d\n", type);
|
||||
return NULL;
|
||||
}
|
||||
if (!net) {
|
||||
fprintf(stderr, "[vnet] device initialization failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
net_device_t *vnet = (net_device_t*)malloc(sizeof(net_device_t));
|
||||
*vnet = (net_device_t){
|
||||
.device_type = NET_TYPE_ETH,
|
||||
.mtu = 1514,
|
||||
.name = "UMK0770",
|
||||
net->netdev.bytes_tx = 0;
|
||||
net->netdev.bytes_rx = 0;
|
||||
net->netdev.packets_tx = 0;
|
||||
net->netdev.packets_rx = 0;
|
||||
|
||||
.unload = vnet_unload,
|
||||
.reset = vnet_reset,
|
||||
.transmit = vnet_transmit,
|
||||
net->netdev.link_state = ETH_LINK_FD + ETH_LINK_10M;
|
||||
net->netdev.hwacc = 0;
|
||||
memcpy(net->netdev.mac, &(uint8_t[6]){0x80, 0x2b, 0xf9, 0x3b, 0x6c, 0xca},
|
||||
sizeof(net->netdev.mac));
|
||||
|
||||
.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},
|
||||
|
||||
.userdata = u,
|
||||
};
|
||||
|
||||
kos_attach_int_handler(SIGUSR1, vnet_input, vnet);
|
||||
kos_attach_int_handler(UMKA_IRQ_NETWORK, vnet_input, net);
|
||||
fprintf(stderr, "[vnet] start input_monitor thread\n");
|
||||
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->saved_esp0-12) = vnet; // param for monitor thread
|
||||
*(void**)((uint8_t*)t->saved_esp0-12) = net; // param for monitor thread
|
||||
// -12 here because in UMKa, unlike real hardware, we don't switch between
|
||||
// kernel and userspace, i.e. stack structure is different
|
||||
|
||||
return vnet;
|
||||
return net;
|
||||
}
|
||||
|
22
vnet.h
22
vnet.h
@ -4,7 +4,7 @@
|
||||
UMKa - User-Mode KolibriOS developer tools
|
||||
vnet - virtual network card
|
||||
|
||||
Copyright (C) 2020-2022 Ivan Baravy <dunkaist@gmail.com>
|
||||
Copyright (C) 2020-2023 Ivan Baravy <dunkaist@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef VNET_H_INCLUDED
|
||||
@ -12,7 +12,23 @@
|
||||
|
||||
#include "umka.h"
|
||||
|
||||
net_device_t*
|
||||
vnet_init(void);
|
||||
#define UMKA_VNET_NAME "umka%d"
|
||||
|
||||
extern uint32_t umka_irq_number;
|
||||
|
||||
enum vnet_type {
|
||||
VNET_FILE,
|
||||
VNET_TAP,
|
||||
};
|
||||
|
||||
struct vnet {
|
||||
net_device_t netdev;
|
||||
int fdin;
|
||||
int fdout;
|
||||
int input_processed;
|
||||
};
|
||||
|
||||
struct vnet *
|
||||
vnet_init(enum vnet_type type);
|
||||
|
||||
#endif // VNET_H_INCLUDED
|
||||
|
15
vnet/file.c
Normal file
15
vnet/file.c
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
UMKa - User-Mode KolibriOS developer tools
|
||||
vnet - virtual network card, file interface
|
||||
|
||||
Copyright (C) 2023 Ivan Baravy <dunkaist@gmail.com>
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
struct vnet *
|
||||
vnet_init_file() {
|
||||
return NULL;
|
||||
}
|
16
vnet/file.h
Normal file
16
vnet/file.h
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
UMKa - User-Mode KolibriOS developer tools
|
||||
vnet - virtual network card, file interface
|
||||
|
||||
Copyright (C) 2023 Ivan Baravy <dunkaist@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef VNET_FILE_H_INCLUDED
|
||||
#define VNET_FILE_H_INCLUDED
|
||||
|
||||
struct vnet *
|
||||
vnet_init_file(void);
|
||||
|
||||
#endif // VNET_FILE_H_INCLUDED
|
16
vnet/tap.h
Normal file
16
vnet/tap.h
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
UMKa - User-Mode KolibriOS developer tools
|
||||
vnet - virtual network card, tap interface
|
||||
|
||||
Copyright (C) 2023 Ivan Baravy <dunkaist@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef VNET_TAP_H_INCLUDED
|
||||
#define VNET_TAP_H_INCLUDED
|
||||
|
||||
struct vnet *
|
||||
vnet_init_tap(void);
|
||||
|
||||
#endif // VNET_TAP_H_INCLUDED
|
51
windows/io_async.c
Normal file
51
windows/io_async.c
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
UMKa - User-Mode KolibriOS developer tools
|
||||
io_async - input/output platform specific code
|
||||
|
||||
Copyright (C) 2023 Ivan Baravy <dunkaist@gmail.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include "umka.h"
|
||||
|
||||
#define QUEUE_DEPTH 1
|
||||
|
||||
#define read_barrier() __asm__ __volatile__("":::"memory")
|
||||
#define write_barrier() __asm__ __volatile__("":::"memory")
|
||||
|
||||
#define MAX(x, y) ((x) >= (y) ? (x) : (y))
|
||||
|
||||
void *
|
||||
io_async_init() {
|
||||
fprintf(stderr, "[io_async] not implemented for windows\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
io_async_close(void *arg) {
|
||||
(void)arg;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
io_async_read(int fd, void *buf, size_t count, void *arg) {
|
||||
(void)fd;
|
||||
(void)buf;
|
||||
(void)count;
|
||||
(void)arg;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
io_async_write(int fd, const void *buf, size_t count, void *arg) {
|
||||
(void)fd;
|
||||
(void)buf;
|
||||
(void)count;
|
||||
(void)arg;
|
||||
return -1;
|
||||
}
|
@ -17,6 +17,11 @@ char pci_path[UMKA_PATH_MAX] = ".";
|
||||
__attribute__((stdcall)) uint32_t pci_read(uint32_t bus, uint32_t dev,
|
||||
uint32_t fun, uint32_t offset,
|
||||
size_t len) {
|
||||
(void)bus;
|
||||
(void)dev;
|
||||
(void)fun;
|
||||
(void)offset;
|
||||
(void)len;
|
||||
printf("STUB: %s:%d", __FILE__, __LINE__);
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ void reset_procmask(void) {
|
||||
}
|
||||
|
||||
int get_fake_if(void *ctx) {
|
||||
(void)ctx;
|
||||
printf("STUB: %s:%d", __FILE__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
|
16
windows/vnet/tap.c
Normal file
16
windows/vnet/tap.c
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
UMKa - User-Mode KolibriOS developer tools
|
||||
vnet - virtual network card, tap interface
|
||||
|
||||
Copyright (C) 2023 Ivan Baravy <dunkaist@gmail.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
struct vnet *
|
||||
vnet_init_tap() {
|
||||
fprintf(stderr, "[vnet] tap interface isn't implemented for windows\n");
|
||||
return NULL;
|
||||
}
|
Loading…
Reference in New Issue
Block a user