2021-11-03 15:28:03 +01:00
|
|
|
/*
|
|
|
|
UMKa - User-Mode KolibriOS developer tools
|
|
|
|
umka_os - kind of KolibriOS rump kernel
|
|
|
|
Copyright (C) 2018--2021 Ivan Baravy <dunkaist@gmail.com>
|
|
|
|
|
|
|
|
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 <https://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2020-10-17 04:13:18 +02:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <fcntl.h>
|
2022-05-24 21:22:12 +02:00
|
|
|
#define __USE_GNU
|
2020-05-08 06:44:32 +02:00
|
|
|
#include <signal.h>
|
|
|
|
#include <stdio.h>
|
2020-05-10 06:21:49 +02:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
2022-05-24 21:22:12 +02:00
|
|
|
#define __USE_MISC
|
2020-10-12 05:02:02 +02:00
|
|
|
#include <sys/mman.h>
|
2020-05-10 06:21:49 +02:00
|
|
|
#include <sys/select.h>
|
|
|
|
#include <sys/stat.h>
|
2020-05-08 06:44:32 +02:00
|
|
|
#include <sys/time.h>
|
2020-05-10 06:21:49 +02:00
|
|
|
#include <sys/types.h>
|
2020-05-08 06:44:32 +02:00
|
|
|
#include "umka.h"
|
2020-05-10 06:21:49 +02:00
|
|
|
#include "shell.h"
|
2020-10-17 04:13:18 +02:00
|
|
|
#include "trace.h"
|
2020-05-08 06:44:32 +02:00
|
|
|
|
2021-11-03 15:28:03 +01:00
|
|
|
#define UMKA_DEFAULT_DISPLAY_WIDTH 400
|
|
|
|
#define UMKA_DEFAULT_DISPLAY_HEIGHT 300
|
|
|
|
|
2020-10-17 04:13:18 +02:00
|
|
|
#define THREAD_STACK_SIZE 0x100000
|
2020-05-08 06:44:32 +02:00
|
|
|
|
2020-10-17 04:13:18 +02:00
|
|
|
static void
|
|
|
|
monitor(void) {
|
2020-10-14 19:56:28 +02:00
|
|
|
umka_sti();
|
2020-05-10 06:21:49 +02:00
|
|
|
fprintf(stderr, "Start monitor thread\n");
|
2022-06-25 00:41:23 +02:00
|
|
|
__asm__ __inline__ __volatile__ ("jmp $");
|
2020-05-09 06:34:28 +02:00
|
|
|
}
|
|
|
|
|
2020-10-14 05:30:01 +02:00
|
|
|
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}};
|
|
|
|
|
2020-10-17 04:13:18 +02:00
|
|
|
static void
|
|
|
|
thread_start(int is_kernel, void (*entry)(void), size_t stack_size) {
|
2022-06-25 00:41:23 +02:00
|
|
|
fprintf(stderr, "### thread_start: %p\n", (void*)(uintptr_t)entry);
|
2020-10-17 04:13:18 +02:00
|
|
|
uint8_t *stack = malloc(stack_size);
|
|
|
|
umka_new_sys_threads(is_kernel, entry, stack + stack_size);
|
|
|
|
}
|
|
|
|
|
2022-06-25 00:41:23 +02:00
|
|
|
static void
|
|
|
|
dump_procs() {
|
|
|
|
for (int i = 0; i < NR_SCHED_QUEUES; i++) {
|
|
|
|
printf("sched queue #%i:", i);
|
|
|
|
appdata_t *p_begin = kos_scheduler_current[i];
|
|
|
|
appdata_t *p = p_begin;
|
|
|
|
do {
|
|
|
|
printf(" %p", (void*)p);
|
|
|
|
p = p->in_schedule.next;
|
|
|
|
} while (p != p_begin);
|
|
|
|
putchar('\n');
|
2020-10-17 04:13:18 +02:00
|
|
|
}
|
|
|
|
}
|
2022-05-24 21:22:12 +02:00
|
|
|
|
|
|
|
int
|
2022-06-25 00:41:23 +02:00
|
|
|
load_app_host(const char *fname, void *base) {
|
2022-05-24 21:22:12 +02:00
|
|
|
FILE *f = fopen(fname, "r");
|
|
|
|
if (!f) {
|
|
|
|
perror("Can't open app file");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
fread(base, 1, 0x4000, f);
|
|
|
|
fclose(f);
|
|
|
|
|
|
|
|
for (size_t i = 0; i < 0x64; i++) {
|
|
|
|
fprintf(stderr, "%2.2hx ", ((uint8_t*)base)[i]);
|
|
|
|
}
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-06-25 00:41:23 +02:00
|
|
|
int
|
|
|
|
load_app(const char *fname) {
|
|
|
|
int32_t result = umka_fs_execute(fname);
|
|
|
|
printf("result: %" PRIi32 "\n", result);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2022-05-24 21:22:12 +02:00
|
|
|
void handle_i40(int signo, siginfo_t *info, void *context) {
|
|
|
|
(void)signo;
|
|
|
|
(void)info;
|
|
|
|
ucontext_t *ctx = context;
|
|
|
|
void *ip = (void*)ctx->uc_mcontext.__gregs[REG_EIP];
|
|
|
|
int eax = ctx->uc_mcontext.__gregs[REG_EAX];
|
|
|
|
if (*(uint16_t*)ip == 0x40cd) {
|
|
|
|
ctx->uc_mcontext.__gregs[REG_EIP] += 2; // skip int 0x40
|
|
|
|
}
|
|
|
|
printf("i40: %i %p\n", eax, ip);
|
|
|
|
umka_i40((pushad_t*)(ctx->uc_mcontext.__gregs + REG_EDI));
|
|
|
|
}
|
|
|
|
|
2020-10-17 04:13:18 +02:00
|
|
|
int
|
|
|
|
main() {
|
|
|
|
if (coverage)
|
|
|
|
trace_begin();
|
|
|
|
|
2020-05-11 05:38:44 +02:00
|
|
|
umka_tool = UMKA_OS;
|
2020-10-17 04:13:18 +02:00
|
|
|
umka_sti();
|
2020-05-08 06:44:32 +02:00
|
|
|
|
2020-10-10 01:30:52 +02:00
|
|
|
struct sigaction sa;
|
|
|
|
sa.sa_sigaction = irq0;
|
2020-05-08 06:44:32 +02:00
|
|
|
sigemptyset(&sa.sa_mask);
|
|
|
|
sa.sa_flags = SA_SIGINFO;
|
|
|
|
|
|
|
|
if (sigaction(SIGPROF, &sa, NULL) == -1) {
|
2022-05-24 21:22:12 +02:00
|
|
|
printf("Can't install SIGPROF handler!\n");
|
2020-05-08 06:44:32 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2022-05-24 21:22:12 +02:00
|
|
|
sa.sa_sigaction = handle_i40;
|
|
|
|
sigemptyset(&sa.sa_mask);
|
|
|
|
sa.sa_flags = SA_SIGINFO;
|
|
|
|
|
|
|
|
if (sigaction(SIGSEGV, &sa, NULL) == -1) {
|
|
|
|
printf("Can't install SIGSEGV handler!\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void *app_base = mmap((void*)0, 16*0x100000, PROT_READ | PROT_WRITE |
|
2020-10-21 16:57:54 +02:00
|
|
|
PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS,
|
|
|
|
-1, 0);
|
2020-10-12 05:02:02 +02:00
|
|
|
if (app_base == MAP_FAILED) {
|
|
|
|
perror("mmap failed");
|
|
|
|
exit(1);
|
|
|
|
}
|
2022-05-24 21:22:12 +02:00
|
|
|
|
2020-10-12 05:02:02 +02:00
|
|
|
printf("pid=%d, kos_lfb_base=%p\n", getpid(), (void*)kos_lfb_base);
|
2020-05-09 06:34:28 +02:00
|
|
|
|
2021-11-03 15:28:03 +01:00
|
|
|
kos_boot.bpp = 32;
|
|
|
|
kos_boot.x_res = UMKA_DEFAULT_DISPLAY_WIDTH;
|
|
|
|
kos_boot.y_res = UMKA_DEFAULT_DISPLAY_HEIGHT;
|
|
|
|
kos_boot.pitch = UMKA_DEFAULT_DISPLAY_WIDTH*4; // 32bpp
|
|
|
|
|
2020-10-14 19:56:28 +02:00
|
|
|
umka_init();
|
2022-06-25 00:41:23 +02:00
|
|
|
dump_procs();
|
2020-10-14 19:56:28 +02:00
|
|
|
umka_stack_init();
|
2020-10-14 05:30:01 +02:00
|
|
|
|
2022-06-25 00:41:23 +02:00
|
|
|
FILE *f = fopen("../img/kolibri.img", "r");
|
|
|
|
fread(kos_ramdisk, 2880*512, 1, f);
|
|
|
|
fclose(f);
|
|
|
|
kos_ramdisk_init();
|
2022-06-26 10:44:16 +02:00
|
|
|
// load_app_host("../apps/board_cycle", app_base);
|
|
|
|
// load_app("/rd/1/loader");
|
2022-06-25 00:41:23 +02:00
|
|
|
|
2020-10-17 04:13:18 +02:00
|
|
|
thread_start(0, monitor, THREAD_STACK_SIZE);
|
2022-06-26 10:44:16 +02:00
|
|
|
thread_start(0, umka_thread_net_drv, THREAD_STACK_SIZE);
|
2022-06-25 00:41:23 +02:00
|
|
|
|
|
|
|
dump_procs();
|
2020-10-10 01:30:52 +02:00
|
|
|
|
2020-10-14 05:30:01 +02:00
|
|
|
setitimer(ITIMER_PROF, &timeout, NULL);
|
2020-10-10 01:30:52 +02:00
|
|
|
|
2020-10-14 19:56:28 +02:00
|
|
|
kos_osloop(); // doesn't return
|
2020-05-08 06:44:32 +02:00
|
|
|
|
2020-10-17 04:13:18 +02:00
|
|
|
if (coverage)
|
|
|
|
trace_end();
|
|
|
|
|
2020-05-08 06:44:32 +02:00
|
|
|
return 0;
|
|
|
|
}
|