Many fixes to scheduler and especially network. Ping via tap0 works!!

This commit is contained in:
Ivan Baravy 2020-10-14 06:30:01 +03:00
parent f7942d2eb3
commit d2cbe2e9e0
9 changed files with 322 additions and 157 deletions

View File

@ -2,11 +2,8 @@
#define __USE_GNU
#include <signal.h>
#include <stddef.h>
#include <stdio.h>
#include <sys/time.h>
sigset_t mask;
struct itimerval timeout = {.it_value = {.tv_sec = 0, .tv_usec = 10000}};
void reset_procmask(void) {
sigemptyset (&mask);
@ -14,11 +11,13 @@ void reset_procmask(void) {
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 set_procmask(void) {
sigemptyset (&mask);
sigaddset (&mask, SIGPROF);
sigprocmask(SIG_BLOCK, &mask, NULL);
}
void restart_timer(void) {
setitimer(ITIMER_PROF, &timeout, NULL);
int get_fake_if(ucontext_t *ctx) {
// we fake IF with id flag
return !(ctx->uc_mcontext.__gregs[REG_EFL] & (1 << 21));
}

View File

@ -11,7 +11,7 @@ CFLAGS_32=$(CFLAGS) -m32
LDFLAGS=-no-pie
LDFLAGS_32=$(LDFLAGS) -m32
all: umka_shell umka_fuse umka_os umka_ping umka.sym umka.prp umka.lst tags \
all: umka_shell umka_fuse umka_os umka.sym umka.prp umka.lst tags \
covpreproc default.skn skin.skn
covpreproc: covpreproc.c
@ -25,11 +25,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`
umka_os: umka_os.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_ping: umka_ping.o umka.o shell.o lodepng.o vdisk.o vnet.o trace.o \
trace_lbr.o pci.o thread.o
pci.o thread.o umka_ping.o
$(CC) $(LDFLAGS_32) $^ -o $@ -static
umka.o umka.fas: umka.asm

65
shell.c
View File

@ -54,25 +54,6 @@
FILE *fin, *fout;
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},
};
char cur_dir[PATH_MAX] = "/";
const char *last_dir = cur_dir;
bool cur_dir_changed = true;
@ -485,6 +466,18 @@ void shell_dump_appdata(int argc, char **argv) {
a->wnd_clientbox.top, a->wnd_clientbox.width,
a->wnd_clientbox.height);
fprintf(fout, "priority: %u\n", a->priority);
fprintf(fout, "in_schedule: prev");
if (show_pointers) {
fprintf(fout, " %p", (void*)a->in_schedule.prev);
}
fprintf(fout, " (%u), next",
(appdata_t*)a->in_schedule.prev - kos_slot_base);
if (show_pointers) {
fprintf(fout, " %p", (void*)a->in_schedule.next);
}
fprintf(fout, " (%u)\n",
(appdata_t*)a->in_schedule.next - kos_slot_base);
}
void shell_dump_taskdata(int argc, char **argv) {
@ -493,8 +486,14 @@ void shell_dump_taskdata(int argc, char **argv) {
if (argc > 1) {
idx = strtol(argv[1], NULL, 0);
}
taskdata_t *t = kos_task_base + idx;
taskdata_t *t = kos_task_data + idx;
fprintf(fout, "event_mask: %" PRIx32 "\n", t->event_mask);
fprintf(fout, "pid: %" PRId32 "\n", t->pid);
fprintf(fout, "state: 0x%" PRIx8 "\n", t->state);
fprintf(fout, "wnd_number: %" PRIu8 "\n", t->wnd_number);
fprintf(fout, "counter_sum: %" PRIu32 "\n", t->counter_sum);
fprintf(fout, "counter_add: %" PRIu32 "\n", t->counter_add);
fprintf(fout, "cpu_usage: %" PRIu32 "\n", t->cpu_usage);
}
void shell_mouse_move(int argc, char **argv) {
@ -1047,6 +1046,28 @@ fs_enc_t parse_encoding(const char *str) {
return enc;
}
void shell_exec(int argc, char **argv) {
(void)argc;
f7080s7arg_t fX0 = {.sf = 7};
f7080ret_t r;
int opt = 1;
fX0.u.f70.zero = 0;
fX0.u.f70.path = argv[opt++];
fX0.flags = 0;
fX0.params = "test";
COVERAGE_ON();
umka_sys_lfn(&fX0, &r, F70);
COVERAGE_OFF();
if (r.status < 0) {
r.status = -r.status;
} else {
fprintf(fout, "pid: %" PRIu32 "\n", r.status);
r.status = 0;
}
print_f70_status(&r, 1);
}
void shell_ls(int argc, char **argv, const char *usage, f70or80_t f70or80) {
int opt;
optind = 1;
@ -1339,7 +1360,8 @@ void shell_stack_init(int argc, char **argv) {
void shell_net_add_device(int argc, char **argv) {
(void)argc;
(void)argv;
int32_t dev_num = kos_net_add_device(&vnet);
net_device_t *vnet = vnet_init(42); // FIXME: tap & list like block devices
int32_t dev_num = kos_net_add_device(vnet);
fprintf(fout, "device number: %" PRIi32 "\n", dev_num);
}
@ -2128,6 +2150,7 @@ func_table_t funcs[] = {
{ "pci_set_path", shell_pci_set_path },
{ "pci_get_path", shell_pci_get_path },
{ "mouse_move", shell_mouse_move },
{ "exec", shell_exec },
{ NULL, NULL },
};

View File

@ -64,6 +64,8 @@ public scheduler_add_thread
public new_sys_threads
public osloop
public set_mouse_data as 'kos_set_mouse_data'
public scheduler_current as 'kos_scheduler_current'
public eth_input as 'kos_eth_input'
macro cli {
pushfd
@ -346,6 +348,31 @@ proc kos_init c uses ebx esi edi ebp
mov [BOOT.lfb], LFB_BASE
call init_video
stdcall alloc_kernel_space, 0x50000 ; FIXME check size
mov [default_io_map], eax
add eax, 0x2000
mov [ipc_tmp], eax
mov ebx, 0x1000
add eax, 0x40000
mov [proc_mem_map], eax
add eax, 0x8000
mov [proc_mem_pdir], eax
add eax, ebx
mov [proc_mem_tab], eax
add eax, ebx
mov [tmp_task_ptab], eax
add eax, ebx
mov [ipc_pdir], eax
add eax, ebx
mov [ipc_ptab], eax
stdcall kernel_alloc, (unpack.LZMA_BASE_SIZE+(unpack.LZMA_LIT_SIZE shl \
(unpack.lc+unpack.lp)))*4
mov [unpack.p], eax
@ -512,25 +539,58 @@ proc delay_ms
ret
endp
;public inject_packet as 'kos_inject_packet'
public umka_inject_packet
proc umka_inject_packet c uses ebx esi edi, _data, _size, _dev
mov ebx, [_dev]
mov ecx, [_size]
push ecx
add ecx, NET_BUFF.data
stdcall net_buff_alloc, ecx ; Allocate a buffer to put packet into
pop ecx
test eax, eax ; Test if we allocated succesfully
jz .abort
mov [eax + NET_BUFF.length], ecx
mov [eax + NET_BUFF.device], ebx
mov [eax + NET_BUFF.offset], NET_BUFF.data
lea edi, [eax + NET_BUFF.data] ; Where we will copy too
mov esi, [_data] ; The buffer we will copy from
rep movsb
push .abort
push eax ; buffer ptr for Eth_input
jmp eth_input ; Send it to kernel
.abort:
ret
endp
extrn reset_procmask
extrn get_fake_if
extrn restart_timer
public irq0
proc irq0 c, _signo, _info, _context
DEBUGF 2, "### irq0\n"
pushfd
cli
pushad
inc [timer_ticks]
call updatecputimes
ccall reset_procmask
ccall get_fake_if, [_context]
test eax, eax
jz .done
jnz @f
DEBUGF 2, "### cli\n"
jmp .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

30
umka.h
View File

@ -160,7 +160,7 @@ typedef struct {
} bdfe_t;
typedef struct {
uint32_t status;
int32_t status;
uint32_t count;
} f7080ret_t;
@ -225,6 +225,24 @@ typedef struct {
} u;
} __attribute__((packed)) f7080s5arg_t;
typedef struct {
uint32_t sf;
uint32_t flags;
char *params;
uint32_t reserved1;
uint32_t reserved2;
union {
struct {
uint8_t zero;
const char *path;
} __attribute__((packed)) f70;
struct {
uint32_t path_encoding;
const char *path;
} f80;
} u;
} __attribute__((packed)) f7080s7arg_t;
#define KF_READONLY 0x01
#define KF_HIDDEN 0x02
#define KF_SYSTEM 0x04
@ -318,6 +336,7 @@ 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 {
@ -361,6 +380,8 @@ static inline void umka_mouse_move(int lbheld, int mbheld, int rbheld,
kos_set_mouse_data(btn_state, xmoving, ymoving, vscroll, hscroll);
}
void umka_inject_packet(void *data, size_t size, net_device_t *dev);
static inline void umka_new_sys_threads(uint32_t flags, void (*entry)(), void *stack) {
__asm__ __inline__ __volatile__ (
"pushad;"
@ -549,6 +570,13 @@ _Static_assert(sizeof(taskdata_t) == 32, "must be 0x20 bytes long");
#define UMKA_FUSE 2u
#define UMKA_OS 3u
#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 uint32_t umka_tool;
extern uint32_t kos_current_task;
extern appdata_t *kos_current_slot;

View File

@ -13,6 +13,12 @@
#define MONITOR_THREAD_STACK_SIZE 0x100000
void monitor() {
__asm__ __inline__ __volatile__ (
"pushfd;"
"btr dword ptr[esp], 21;"
"popfd"
: : : "memory");
fprintf(stderr, "Start monitor thread\n");
// mkfifo("/tmp/umka.fifo.2u", 0644);
// mkfifo("/tmp/umka.fifo.4u", 0644);
@ -25,7 +31,20 @@ void monitor() {
run_test(fin, fout, 0);
}
void restart_timer(void);
void umka_thread_ping(void);
void umka_thread_net_drv(void);
struct itimerval timeout = {.it_value = {.tv_sec = 0, .tv_usec = 10000},
.it_interval = {.tv_sec = 0, .tv_usec = 10000}};
int main() {
__asm__ __inline__ __volatile__ (
"pushfd;"
"btr dword ptr[esp], 21;"
"popfd"
: : : "memory");
umka_tool = UMKA_OS;
struct sigaction sa;
@ -51,9 +70,15 @@ int main() {
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);
umka_new_sys_threads(0, monitor, monitor_stack + MONITOR_THREAD_STACK_SIZE);
raise(SIGPROF);
uint8_t *net_drv_stack = malloc(MONITOR_THREAD_STACK_SIZE);
umka_new_sys_threads(0, umka_thread_net_drv, net_drv_stack + MONITOR_THREAD_STACK_SIZE);
uint8_t *ping_stack = malloc(MONITOR_THREAD_STACK_SIZE);
umka_new_sys_threads(0, umka_thread_ping, ping_stack + MONITOR_THREAD_STACK_SIZE);
setitimer(ITIMER_PROF, &timeout, NULL);
osloop(); // doesn't return

View File

@ -16,66 +16,43 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <limits.h>
#include <linux/if_tun.h>
#include <net/if.h>
#include <netinet/in.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <netinet/in.h>
#include "shell.h"
#include "umka.h"
#include "trace.h"
#include "vnet.h"
// tap
#include <stdint.h>
#include <net/if.h>
#include <linux/if_tun.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <sys/time.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
uint8_t packet[4096] = {0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, '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'};
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 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 )
if( (fd = open(clonedev , O_RDWR | O_NONBLOCK)) < 0 )
{
perror("Opening /dev/net/tun");
return fd;
@ -102,74 +79,26 @@ int tap_alloc(char *dev)
return fd;
}
int main(int argc, char **argv) {
umka_tool = UMKA_SHELL;
const char *usage = \
"usage: umka_shell <ip | hostname> [-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;
}
}
int tapfd;
_Atomic int go_ping = 0;
int umka_thread_ping(void) {
__asm__ __inline__ __volatile__ (
"pushfd;"
"btr dword ptr[esp], 21;"
"popfd"
: : : "memory");
while (!go_ping) { /* wait until initialized */ }
fprintf(stderr, "[ping] tapfd is %i\n", tapfd);
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);
r75 = umka_sys_net_open_socket(AF_INET4, SOCK_STREAM, IPPROTO_TCP);
if (r75.errorcode == (uint32_t)-1) {
fprintf(stderr, "error\n");
fprintf(stderr, "[ping] error\n");
exit(1);
}
uint32_t sockfd = r75.value;
@ -177,7 +106,8 @@ int main(int argc, char **argv) {
// 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;
// uint32_t addr = inet_addr("192.168.1.30");
uint16_t port = 5000;
struct sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
@ -187,18 +117,93 @@ int main(int argc, char **argv) {
r75 = umka_sys_net_connect(sockfd, &sa, sizeof(struct sockaddr_in));
if (r75.errorcode == (uint32_t)-1) {
fprintf(stderr, "error %u\n", r75.errorcode);
fprintf(stderr, "[ping] error %u\n", r75.errorcode);
exit(1);
}
r75 = umka_sys_net_send(sockfd, packet, 64, 0);
r75 = umka_sys_net_send(sockfd, packet, 128, 0);
if (r75.errorcode == (uint32_t)-1) {
fprintf(stderr, "error %u\n", r75.errorcode);
fprintf(stderr, "[ping] error %u\n", r75.errorcode);
exit(1);
}
if (coverage)
trace_end();
while (true) {}
return 0;
}
uint8_t buffer[2*1024];
int plen = 0;
void umka_thread_net_drv(void) {
__asm__ __inline__ __volatile__ (
"pushfd;"
"btr dword ptr[esp], 21;"
"popfd"
: : : "memory");
fprintf(stderr, "[net_drv] starting\n");
char tapdev[IFNAMSIZ] = "tap0";
tapfd = tap_alloc(tapdev);
net_device_t *vnet = vnet_init(tapfd);
kos_net_add_device(vnet);
umka_sys_net_dev_reset(1);
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);
printf("[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] error\n");
exit(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, "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, "[net_drv] error\n");
exit(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] error\n");
exit(1);
}
go_ping = 1;
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");
umka_inject_packet(buffer, plen, vnet);
} else if(plen == -1 && (errno == EAGAIN || errno == EINTR)) {
continue;
} else {
perror("[net_drv] reading data");
exit(1);
}
}
}

47
vnet.c
View File

@ -6,18 +6,39 @@
#include <errno.h>
#include "umka.h"
#include "trace.h"
int tapfd;
#include "vnet.h"
typedef struct {
int fd;
} vnet_t;
} vnet_userdata_t;
net_device_t *vnet_init(int fd) {
// printf("vnet_init\n");
vnet_userdata_t *u = (vnet_userdata_t*)malloc(sizeof(vnet_userdata_t));
u->fd = fd;
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",
.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},
.userdata = u,
};
void *vnet_init(int fd) {
printf("vnet_init\n");
vnet_t *vnet = (vnet_t*)malloc(sizeof(vnet_t));
*vnet = (vnet_t){.fd = fd,};
tapfd = fd;
return vnet;
}
@ -44,9 +65,17 @@ static void dump_net_buff(net_buff_t *buf) {
__attribute__((__stdcall__))
int vnet_transmit(net_buff_t *buf) {
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(tapfd, buf->data, buf->length);
write(u->fd, buf->data, buf->length);
buf->length = 0;
COVERAGE_OFF();
COVERAGE_ON();

2
vnet.h
View File

@ -5,7 +5,7 @@
#include <inttypes.h>
#include "umka.h"
void *vnet_init(int fd);
net_device_t *vnet_init(int fd);
__attribute__((__stdcall__))
void vnet_unload(void);