bx_enh_dbg.ini
machine/
draft/
-iso_inspect/
\ No newline at end of file
+iso_inspect/
+unused/
\ No newline at end of file
{
"name": "OS-DEV",
"includePath": [
- "${workspaceFolder}/includes"
+ "${workspaceFolder}/includes",
+ "${workspaceFolder}/usr/includes"
],
"compilerArgs": [
"-ffreestanding",
CC := i686-elf-gcc
AS := i686-elf-as
+AR := i686-elf-ar
ARCH_OPT := -D__ARCH_IA32 -include flags.h
OBJECT_DIR := $(BUILD_DIR)/obj
BIN_DIR := $(BUILD_DIR)/bin
ISO_DIR := $(BUILD_DIR)/iso
+USR_DIR := $(BUILD_DIR)/usr
ISO_BOOT_DIR := $(ISO_DIR)/boot
ISO_GRUB_DIR := $(ISO_BOOT_DIR)/grub
-INCLUDES_DIR := includes
\ No newline at end of file
+INCLUDES := -Iincludes -Iusr/includes
\ No newline at end of file
OS_ARCH := x86
-OS_NAME = lunaix
-OS_BIN = $(OS_NAME).bin
-OS_ISO = $(OS_NAME).iso
\ No newline at end of file
+OS_NAME := lunaix
+OS_BIN := $(OS_NAME).bin
+OS_ISO := $(OS_NAME).iso
+
+USR_LIB := liblxusrt.a
\ No newline at end of file
#ifndef __LUNAIX_FOPTIONS_H
#define __LUNAIX_FOPTIONS_H
-#include <usr/fcntl_defs.h>
+#include <fcntl_defs.h>
#endif /* __LUNAIX_FOPTIONS_H */
#ifndef __LUNAIX_IOCTL_H
#define __LUNAIX_IOCTL_H
-#include <usr/sys/ioctl_defs.h>
+#include <sys/ioctl_defs.h>
#endif /* __LUNAIX_IOCTL_H */
ptr_t base;
ptr_t end;
ptr_t mem_sz;
+
+ ptr_t stack_top;
+ ptr_t entry;
};
struct ld_param
int
elf_load(struct ld_param* ldparam, struct v_file* elfile);
+int
+exec_load_byname(struct ld_param* param,
+ const char* filename,
+ const char** argv,
+ const char** envp);
+
+int
+exec_load(struct ld_param* param,
+ struct v_file* executable,
+ const char** argv,
+ const char** envp);
+
void
ld_create_param(struct ld_param* param, struct proc_info* proc, ptr_t vms);
#endif
#include <lunaix/fs.h>
#include <lunaix/types.h>
-#include <usr/sys/mann_flags.h>
+#include <sys/mann_flags.h>
/**
* @brief 私有区域,该区域中的页无法进行任何形式的共享。
#ifndef __LUNAIX_SIGNAL_H
#define __LUNAIX_SIGNAL_H
-#include <usr/signal_defs.h>
+#include <signal_defs.h>
#define _SIG_NUM 16
#include <stdarg.h>
#include <stdint.h>
-#include <usr/sys/types.h>
+#include <sys/types.h>
#define PACKED __attribute__((packed))
+++ /dev/null
-#include <usr/errno.h>
-#include <usr/fcntl.h>
-#include <usr/sys/dirent.h>
-#include <usr/unistd.h>
-
-void
-_readdir_main()
-{
- int fd = open("/dev/./../dev/.", 0);
- if (fd == -1) {
- printf("fail to open (%d)\n", errno);
- return;
- }
-
- char path[129];
- int len = realpathat(fd, path, 128);
- if (len < 0) {
- printf("fail to read (%d)\n", errno);
- } else {
- path[len] = 0;
- printf("%s\n", path);
- }
-
- struct lx_dirent ent = { .d_offset = 0 };
-
- while (sys_readdir(fd, &ent) == 1) {
- printf("%s\n", ent.d_name);
- }
-
- close(fd);
-
- return;
-}
\ No newline at end of file
+++ /dev/null
-#include <lunaix/input.h>
-
-#include <ulibc/stdio.h>
-#include <usr/errno.h>
-#include <usr/fcntl.h>
-#include <usr/sys/lunaix.h>
-#include <usr/unistd.h>
-
-#define STDIN 1
-#define STDOUT 0
-
-void
-input_test()
-{
- int fd = open("/dev/input/i8042-kbd", 0);
-
- if (fd < 0) {
- printf("fail to open (%d)", errno);
- return;
- }
-
- struct input_evt_pkt event;
-
- while (read(fd, &event, sizeof(event)) > 0) {
- char* action;
- if (event.pkt_type == PKT_PRESS) {
- action = "pressed";
- } else {
- action = "release";
- }
-
- printf("%u: %s '%c', class=0x%x, scan=%x\n",
- event.timestamp,
- action,
- event.sys_code & 0xff,
- (event.sys_code & 0xff00) >> 8,
- event.scan_code);
- }
- return;
-}
\ No newline at end of file
+++ /dev/null
-#include <ulibc/stdio.h>
-#include <usr/errno.h>
-#include <usr/fcntl.h>
-#include <usr/sys/lunaix.h>
-#include <usr/unistd.h>
-
-void
-_iotest_main()
-{
- char test_sequence[] = "Once upon a time, in a magical land of Equestria. "
- "There were two regal sisters who ruled together "
- "and created harmony for all the land.";
- char read_out[256];
-
- // 切换工作目录至 /dev
- int status = chdir("/dev");
- if (status) {
- write(stdout, "fail to chdir", 15);
- return;
- }
-
- if (getcwd(read_out, sizeof(read_out))) {
- printf("current working dir: %s\n", read_out);
- }
-
- // sda 设备 - 硬盘
- // sda设备属于容积设备(Volumetric Device),
- // Lunaix会尽可能缓存任何对此设备的上层读写,并使用延迟写入策略。(FO_DIRECT可用于屏蔽该功能)
- int fd = open("./sda", 0);
-
- if (fd < 0) {
- printf("fail to open (%d)\n", errno);
- return;
- }
-
- // 移动指针至512字节,在大多数情况下,这是第二个逻辑扇区的起始处
- lseek(fd, 512, FSEEK_SET);
-
- // 总共写入 64 * 136 字节,会产生3个页作为缓存
- for (size_t i = 0; i < 64; i++) {
- write(fd, test_sequence, sizeof(test_sequence));
- }
-
- // 随机读写测试
- lseek(fd, 4 * 4096, FSEEK_SET);
- write(fd, test_sequence, sizeof(test_sequence));
-
- printf("input: ");
- int size = read(stdin, read_out, 256);
-
- printf("your said: %s\n", read_out);
-
- write(fd, read_out, size);
-
- // 读出我们写的内容
- lseek(fd, 512, FSEEK_SET);
- read(fd, read_out, sizeof(read_out));
-
- // 将读出的内容直接写入tty设备
- write(stdout, read_out, sizeof(read_out));
- write(stdout, "\n", 1);
-
- // 关闭文件,这同时会将页缓存中的数据下发到底层驱动
- close(fd);
-}
\ No newline at end of file
+++ /dev/null
-#include <lunaix/spike.h>
-
-#include <ulibc/stdio.h>
-
-#include <usr/signal.h>
-#include <usr/sys/lunaix.h>
-#include <usr/unistd.h>
-
-void __USER__
-sigchild_handler(int signum)
-{
- printf("SIGCHLD received\n");
-}
-
-void __USER__
-sigsegv_handler(int signum)
-{
- pid_t pid = getpid();
- printf("SIGSEGV received on process %d\n", pid);
- _exit(signum);
-}
-
-void __USER__
-sigalrm_handler(int signum)
-{
- pid_t pid = getpid();
- printf("I, pid %d, have received an alarm!\n", pid);
-}
-
-void __USER__
-_signal_demo_main()
-{
- signal(SIGCHLD, sigchild_handler);
- signal(SIGSEGV, sigsegv_handler);
- signal(SIGALRM, sigalrm_handler);
-
- alarm(5);
-
- int status;
- pid_t p = 0;
-
- printf("Child sleep 3s, parent pause.\n");
- if (!fork()) {
- sleep(3);
- _exit(0);
- }
-
- pause();
-
- printf("Parent resumed on SIGCHILD\n");
-
- for (int i = 0; i < 5; i++) {
- pid_t pid = 0;
- if (!(pid = fork())) {
- signal(SIGSEGV, sigsegv_handler);
- sleep(i);
- if (i == 3) {
- i = *(int*)0xdeadc0de; // seg fault!
- }
- printf("%d\n", i);
- _exit(0);
- }
- printf("Forked %d\n", pid);
- }
-
- while ((p = wait(&status)) >= 0) {
- short code = WEXITSTATUS(status);
- if (WIFSIGNALED(status)) {
- printf("Process %d terminated by signal, exit_code: %d\n", p, code);
- } else if (WIFEXITED(status)) {
- printf("Process %d exited with code %d\n", p, code);
- } else {
- printf("Process %d aborted with code %d\n", p, code);
- }
- }
-
- printf("done\n");
-}
\ No newline at end of file
+++ /dev/null
-#include <lunaix/ioctl.h>
-#include <lunaix/status.h>
-
-#include <usr/fcntl.h>
-#include <usr/signal.h>
-#include <usr/sys/dirent.h>
-#include <usr/sys/lunaix.h>
-#include <usr/sys/mann.h>
-#include <usr/unistd.h>
-
-#include <klibc/string.h>
-#include <ulibc/stdio.h>
-
-char pwd[512];
-char cat_buf[1024];
-
-/*
- Simple shell - (actually this is not even a shell)
- It just to make the testing more easy.
-*/
-
-void
-parse_cmdline(char* line, char** cmd, char** arg_part)
-{
- strrtrim(line);
- line = strltrim_safe(line);
- int l = 0;
- char c = 0;
- while ((c = line[l])) {
- if (c == ' ') {
- line[l++] = 0;
- break;
- }
- l++;
- }
- *cmd = line;
- *arg_part = strltrim_safe(line + l);
-}
-
-void
-sh_printerr()
-{
- int errno = geterrno();
- switch (errno) {
- case ENOTDIR:
- printf("Error: Not a directory\n");
- break;
- case ENOENT:
- printf("Error: No such file or directory\n");
- break;
- case EINVAL:
- printf("Error: Invalid parameter or operation\n");
- break;
- case ENOTSUP:
- printf("Error: Not supported\n");
- break;
- case EROFS:
- printf("Error: File system is read only\n");
- break;
- case ENOMEM:
- printf("Error: Out of memory\n");
- break;
- case EISDIR:
- printf("Error: This is a directory\n");
- break;
- default:
- printf("Error: (%d)\n", errno);
- break;
- }
-}
-
-void
-sigint_handle(int signum)
-{
- return;
-}
-
-void
-do_cat(const char* file)
-{
- int fd = open(file, 0);
- if (fd < 0) {
- sh_printerr();
- } else {
- int sz;
- while ((sz = read(fd, cat_buf, 1024)) > 0) {
- write(stdout, cat_buf, sz);
- }
- if (sz < 0) {
- sh_printerr();
- }
- close(fd);
- printf("\n");
- }
-}
-
-void
-do_ls(const char* path)
-{
- int fd = open(path, 0);
- if (fd < 0) {
- sh_printerr();
- } else {
- struct lx_dirent ent = { .d_offset = 0 };
- int status;
- while ((status = sys_readdir(fd, &ent)) == 1) {
- if (ent.d_type == DT_DIR) {
- printf(" \033[3m%s\033[39;49m\n", ent.d_name);
- } else {
- printf(" %s\n", ent.d_name);
- }
- }
-
- if (status < 0)
- sh_printerr();
-
- close(fd);
- }
-}
-
-void
-do_mcat(const char* file)
-{
- int fd = open(file, 0);
- if (fd < 0) {
- sh_printerr();
- } else {
- void* p = mmap(NULL, 2048, 0, 0, fd, 0);
- if ((int)p < 0) {
- sh_printerr();
- } else {
- printf("%s\n", p);
- }
- munmap(p, 1);
- close(fd);
- printf("\n");
- }
-}
-
-void
-sh_loop()
-{
- char buf[512];
- char *cmd, *argpart;
- pid_t p;
- signal(SIGINT, sigint_handle);
-
- // set our shell as foreground process
- // (unistd.h:tcsetpgrp is essentially a wrapper of this)
- // stdout (by default, unless user did smth) is the tty we are currently at
- ioctl(stdout, TIOCSPGRP, getpgid());
-
- while (1) {
- getcwd(pwd, 512);
- printf("[\033[2m%s\033[39;49m]$ ", pwd);
- size_t sz = read(stdin, buf, 511);
- if (sz < 0) {
- printf("fail to read user input (%d)\n", geterrno());
- return;
- }
- buf[sz] = '\0';
- parse_cmdline(buf, &cmd, &argpart);
- if (cmd[0] == 0) {
- printf("\n");
- goto cont;
- }
- if (streq(cmd, "cd")) {
- if (chdir(argpart) < 0) {
- sh_printerr();
- }
- goto cont;
- } else if (streq(cmd, "clear")) {
- ioctl(stdout, TIOCCLSBUF);
- goto cont;
- } else if (streq(cmd, "ls")) {
- if (!(p = fork())) {
- do_ls(argpart);
- _exit(0);
- }
- } else if (streq(cmd, "cat")) {
- if (!(p = fork())) {
- do_cat(argpart);
- _exit(0);
- }
- } else if (streq(cmd, "mcat")) {
- if (!(p = fork())) {
- do_mcat(argpart);
- _exit(0);
- }
- } else {
- printf("unknow command\n");
- goto cont;
- }
- setpgid(p, getpgid());
- waitpid(p, NULL, 0);
- cont:
- printf("\n");
- }
-}
-
-void
-sh_main()
-{
- printf("\n Simple shell. Use <PG_UP> or <PG_DOWN> to scroll.\n\n");
- if (!fork()) {
- sh_loop();
- _exit(0);
- }
- wait(NULL);
-}
\ No newline at end of file
#include <lunaix/fs/devfs.h>
#include <lunaix/spike.h>
-#include <usr/sys/dirent_defs.h>
+#include <sys/dirent_defs.h>
extern struct v_inode_ops devfs_inode_ops;
extern struct v_file_ops devfs_file_ops;
#include <klibc/string.h>
-#include <usr/sys/dirent_defs.h>
+#include <sys/dirent_defs.h>
extern struct cake_pile* drec_cache_pile;
#include <lunaix/fs/twifs.h>
-#include <usr/sys/dirent_defs.h>
+#include <sys/dirent_defs.h>
static struct cake_pile* dnode_pile;
static struct cake_pile* inode_pile;
size_t
exec_str_size(const char** str_arr, size_t* length)
{
+ if (!str_arr) {
+ *length = 0;
+ return 0;
+ }
+
const char* chr = *str_arr;
size_t sz = 0, len = 0;
}
int
-exec_loadto(struct ld_param* param,
- struct v_file* executable,
- const char** argv,
- const char** envp)
+exec_load(struct ld_param* param,
+ struct v_file* executable,
+ const char** argv,
+ const char** envp)
{
int errno = 0;
.mlen = MAX_VAR_PAGES * PG_SIZE };
void* mapped;
- isr_param* intr_ctx = ¶m->proc->intr_ctx;
if ((errno = __exec_remap_heap(param, pvms))) {
goto done;
// make some handy infos available to user space
ptr_t arg_start = mapped + sizeof(struct usr_exec_param);
- memcpy(arg_start, (void*)argv, sz_argv);
- memcpy(arg_start + sz_argv, (void*)envp, sz_envp);
+ if (argv)
+ memcpy(arg_start, (void*)argv, sz_argv);
+ if (envp)
+ memcpy(arg_start + sz_argv, (void*)envp, sz_envp);
struct usr_exec_param* param = mapped;
*param = (struct usr_exec_param){ .argc = argv_len,
.info = param->info };
ptr_t* ustack = (ptr_t*)USTACK_TOP;
ustack[-1] = (ptr_t)mapped;
- intr_ctx->esp = &ustack[-1];
+ param->info.stack_top = &ustack[-1];
} else {
// TODO need to find a way to inject argv and envp remotely
fail("not implemented");
}
- intr_ctx->eip = param->info.ehdr_out.e_entry;
- // we will jump to new entry point (_u_start) upon syscall's
- // return so execve 'will not return' from the perspective of it's invoker
-
+ param->info.entry = param->info.ehdr_out.e_entry;
done:
return errno;
}
-__DEFINE_LXSYSCALL3(int,
- execve,
- const char*,
- filename,
- const char*,
- argv[],
- const char*,
- envp[])
+int
+exec_load_byname(struct ld_param* param,
+ const char* filename,
+ const char** argv,
+ const char** envp)
{
int errno = 0;
struct v_dnode* dnode;
goto done;
}
+ if ((errno = exec_load(param, file, argv, envp))) {
+ vfs_pclose(file, __current->pid);
+ }
+
+done:
+ return errno;
+}
+
+__DEFINE_LXSYSCALL3(int,
+ execve,
+ const char*,
+ filename,
+ const char*,
+ argv[],
+ const char*,
+ envp[])
+{
+ int errno = 0;
struct ld_param ldparam;
ld_create_param(&ldparam, __current, VMS_SELF);
- if ((errno = exec_loadto(&ldparam, file, argv, envp))) {
- vfs_pclose(file, __current->pid);
-
+ if ((errno = exec_load_byname(&ldparam, filename, argv, envp))) {
if ((ldparam.status & LD_STAT_FKUP)) {
// we fucked up our address space.
terminate_proc(11451);
}
}
+ isr_param* intr_ctx = &__current->intr_ctx;
+ intr_ctx->esp = ldparam.info.stack_top;
+ intr_ctx->eip = ldparam.info.entry;
+
+ // we will jump to new entry point (_u_start) upon syscall's
+ // return so execve 'will not return' from the perspective of it's invoker
+
done:
return errno;
}
\ No newline at end of file
+++ /dev/null
-#include <hal/cpu.h>
-#include <lunaix/clock.h>
-#include <lunaix/lxconsole.h>
-#include <lunaix/mm/vmm.h>
-#include <lunaix/spike.h>
-#include <lunaix/syslog.h>
-#include <lunaix/timer.h>
-
-#include <usr/sys/lunaix.h>
-#include <usr/unistd.h>
-
-extern uint8_t __kernel_start;
-
-LOG_MODULE("INIT")
-
-// #define FORK_BOMB_DEMO
-#define WAIT_DEMO
-#define IN_USER_MODE
-
-void __USER__
-_lxinit_main()
-{
-#ifdef FORK_BOMB_DEMO
- // fork炸弹
- for (;;) {
- pid_t p;
- if ((p = fork())) {
- kprintf(KDEBUG "Pinkie Pie #%d: FUN!\n", p);
- }
- }
-#endif
-
- int status;
-#ifdef WAIT_DEMO
- // 测试wait
- kprintf("I am parent, going to fork my child and wait.\n");
- if (!fork()) {
- kprintf("I am child, going to sleep for 2 seconds\n");
- sleep(2);
- kprintf("I am child, I am about to terminated\n");
- _exit(1);
- }
- wait(&status);
- pid_t child = wait(&status);
- kprintf("I am parent, my child (%d) terminated normally with code: %d.\n",
- child,
- WEXITSTATUS(status));
-#endif
-
- pid_t p = 0;
-
- if (!fork()) {
- kprintf("Test no hang!\n");
- sleep(6);
- _exit(0);
- }
-
- waitpid(-1, &status, WNOHANG);
-
- for (size_t i = 0; i < 5; i++) {
- pid_t pid = 0;
- if (!(pid = fork())) {
- sleep(i);
- if (i == 3) {
- i = *(int*)0xdeadc0de; // seg fault!
- }
- kprintf(KINFO "%d\n", i);
- _exit(0);
- }
- kprintf(KINFO "Forked %d\n", pid);
- }
-
- while ((p = wait(&status)) >= 0) {
- short code = WEXITSTATUS(status);
- if (WIFEXITED(status)) {
- kprintf(KINFO "Process %d exited with code %d\n", p, code);
- } else {
- kprintf(KWARN "Process %d aborted with code %d\n", p, code);
- }
- }
-
- char buf[64];
-
- kprintf(KINFO "Hello processes!\n");
-
- cpu_get_brand(buf);
- kprintf("CPU: %s\n\n", buf);
-
- _exit(0);
-}
\ No newline at end of file
#include <lunaix/foptions.h>
#include <lunaix/fs.h>
#include <lunaix/fs/twifs.h>
+#include <lunaix/ld.h>
#include <lunaix/lxconsole.h>
#include <lunaix/mm/cake.h>
#include <lunaix/mm/pmm.h>
#include <lunaix/syslog.h>
#include <lunaix/types.h>
-#include <usr/fcntl.h>
-#include <usr/sys/lunaix.h>
-#include <usr/unistd.h>
-
#include <sdbg/protocol.h>
#include <hal/acpi/acpi.h>
#include <klibc/string.h>
-#include <ulibc/stdio.h>
-
LOG_MODULE("PROC0")
-extern void
-_lxinit_main(); /* lxinit.c */
-
void
init_platform();
void
__do_reserved_memory(int unlock);
-#define USE_DEMO
-// #define DEMO_SIGNAL
-// #define DEMO_READDIR
-// #define DEMO_IOTEST
-// #define DEMO_INPUT_TEST
-#define DEMO_SIMPLE_SH
-
-extern void
-_pconsole_main();
-
-extern void
-_signal_demo_main();
-
-extern void
-_lxinit_main();
-
-extern void
-_readdir_main();
-
-extern void
-_iotest_main();
-
-extern void
-input_test();
-
-extern void
-sh_main();
-
-void __USER__
-__setup_dir()
+int
+mount_bootmedium()
{
- int errno;
- mkdir("/mnt");
- mkdir("/mnt/lunaix-os");
+ struct v_dnode* dnode;
+ int errno = 0;
+ if ((errno = vfs_walk_proc("/dev/sdb", &dnode, NULL, 0))) {
+ kprintf(KERROR "fail to acquire device. (%d)", errno);
+ return 0;
+ }
- if ((errno = mount("/dev/sdb", "/mnt/lunaix-os", "iso9660", 0))) {
- syslog(2, "fail mounting boot medium. (%d)\n", errno);
+ struct device* dev = (struct device*)dnode->inode->data;
+ if ((errno = vfs_mount("/mnt/lunaix-os", "iso9660", dev, 0))) {
+ kprintf(KERROR "fail to boot medium. (%d)", errno);
+ return 0;
}
+
+ return 1;
}
-void __USER__
-__proc0_usr()
+int
+exec_initd()
{
- // 打开tty设备(控制台),作为标准输入输出。
- // tty设备属于序列设备(Sequential Device),该类型设备的上层读写
- // 无须经过Lunaix的缓存层,而是直接下发到底层驱动。(不受FO_DIRECT的影响)
- int fdstdout = open("/dev/tty", 0);
- int fdstdin = dup2(stdout, 1);
-
- __setup_dir();
-
- pid_t p;
-
- if (!(p = fork())) {
-#ifndef USE_DEMO
- _exit(0);
-#elif defined DEMO_SIGNAL
- _signal_demo_main();
-#elif defined DEMO_READDIR
- _readdir_main();
-#elif defined DEMO_IOTEST
- _iotest_main();
-#elif defined DEMO_INPUT_TEST
- input_test();
-#elif defined DEMO_SIMPLE_SH
- sh_main();
-#else
- _lxinit_main();
-#endif
- printf("==== test end ====\n");
- _exit(0);
- }
+ int errno = 0;
+ struct ld_param param;
+ char filename[] = "/mnt/lunaix-os/usr/initd";
- waitpid(p, 0, 0);
+ ld_create_param(¶m, __current, VMS_SELF);
- while (1) {
- yield();
+ if ((errno = exec_load_byname(¶m, filename, NULL, NULL))) {
+ goto fail;
}
+
+ // user space
+ asm volatile("movw %0, %%ax\n"
+ "movw %%ax, %%es\n"
+ "movw %%ax, %%ds\n"
+ "movw %%ax, %%fs\n"
+ "movw %%ax, %%gs\n"
+ "pushl %0\n"
+ "pushl %1\n"
+ "pushl %2\n"
+ "pushl %3\n"
+ "retf" ::"i"(UDATA_SEG),
+ "r"(param.info.stack_top),
+ "i"(UCODE_SEG),
+ "r"(param.info.entry)
+ : "eax", "memory");
+
+ fail("should not reach");
+
+fail:
+ kprintf(KERROR "fail to load initd. (%d)", errno);
+ return 0;
}
/**
init_proc_user_space(__current);
- // user space
- asm volatile("movw %0, %%ax\n"
- "movw %%ax, %%es\n"
- "movw %%ax, %%ds\n"
- "movw %%ax, %%fs\n"
- "movw %%ax, %%gs\n"
- "pushl %0\n"
- "pushl %1\n"
- "pushl %2\n"
- "pushl %3\n"
- "retf" ::"i"(UDATA_SEG),
- "i"(USTACK_TOP & ~0xf),
- "i"(UCODE_SEG),
- "r"(__proc0_usr)
- : "eax", "memory");
+ if (!mount_bootmedium() || !exec_initd()) {
+ while (1) {
+ asm("hlt");
+ }
+ // should not reach
+ }
}
extern uint8_t __kernel_start; /* link/linker.ld */
#include <klibc/stdio.h>
#include <klibc/string.h>
-#include <usr/sys/dirent_defs.h>
+#include <sys/dirent_defs.h>
#define COUNTER_MASK ((1 << 16) - 1)
#include <lunaix/spike.h>
#include <ulibc/stdio.h>
-#include <usr/unistd.h>
+#include <unistd.h>
// This is VERY bad implementation as it mixes both kernel and user space
// code together. It is here however, just for the convenience of our testing
include config/make-cc
include config/make-debug-tool
-DEPS := $(CC) $(LD) xorriso grub-mkrescue
-
-INCLUDES := $(patsubst %, -I%, $(INCLUDES_DIR))
-SOURCE_FILES := $(shell find -name "*.[cS]")
-SRC := $(patsubst ./%, $(OBJECT_DIR)/%.o, $(SOURCE_FILES))
+DEPS := $(CC) $(LD) $(AR) xorriso grub-mkrescue
$(DEPS):
@echo -n "checking $@ .... "
@echo -n "checking target i686-elf.... "
@test "`i686-elf-gcc -dumpmachine`" = "i686-elf" && echo ok || (echo "failed" && exit 1)
-check: $(DEPS) check-cc
-
$(OBJECT_DIR):
@mkdir -p $(OBJECT_DIR)
$(BIN_DIR):
@mkdir -p $(BIN_DIR)
+$(USR_DIR):
+ @mkdir -p $(USR_DIR)
+
$(ISO_DIR):
@mkdir -p $(ISO_DIR)
@mkdir -p $(ISO_BOOT_DIR)
@mkdir -p $(ISO_GRUB_DIR)
-$(OBJECT_DIR)/%.S.o: %.S
- @mkdir -p $(@D)
- @echo " CC $<"
- @$(CC) $(INCLUDES) -c $< -o $@
+check: $(DEPS) check-cc GRUB_TEMPLATE
+
+prepare: check $(OBJECT_DIR) $(BIN_DIR) $(ISO_DIR) $(USR_DIR)
+
+usrlib: prepare makefile.usr
+ @make -f makefile.usr usr-runtime
+
+usrlib-debug: prepare makefile.usr
+ @make -f makefile.usr usr-runtime-debug
-$(OBJECT_DIR)/%.c.o: %.c
- @mkdir -p $(@D)
- @echo " CC $<"
- @$(CC) $(INCLUDES) -c $< -o $@ $(CFLAGS)
+usr-prog: prepare usrlib makefile.prog
+ @make -f makefile.prog all
-$(BIN_DIR)/$(OS_BIN): $(OBJECT_DIR) $(BIN_DIR) $(SRC)
- @echo " LD $(BIN_DIR)/$(OS_BIN)"
- @$(CC) -T link/linker.ld -o $(BIN_DIR)/$(OS_BIN) $(SRC) $(LDFLAGS)
+bootable: usr-prog usrlib makefile.ker
+ @make -f makefile.ker all
-$(BUILD_DIR)/$(OS_ISO): check $(ISO_DIR) $(BIN_DIR)/$(OS_BIN) GRUB_TEMPLATE
- @./config-grub.sh ${OS_NAME} $(ISO_GRUB_DIR)/grub.cfg
- @cp $(BIN_DIR)/$(OS_BIN) $(ISO_BOOT_DIR)
- @grub-mkrescue -o $(BUILD_DIR)/$(OS_ISO) $(ISO_DIR)
+bootable-debug: usr-prog usrlib-debug makefile.ker
+ @make -f makefile.ker all-debug
-all: $(BUILD_DIR)/$(OS_ISO)
+all: bootable
instable: CFLAGS := -g -std=gnu99 -ffreestanding $(O) $(W) $(ARCH_OPT) -D__LUNAIXOS_DEBUG__
instable: all
-all-debug: O := -Og
-all-debug: CFLAGS := -g -std=gnu99 -ffreestanding $(O) $(W) $(ARCH_OPT) -D__LUNAIXOS_DEBUG__
-all-debug: LDFLAGS := -g -ffreestanding $(O) -nostdlib -lgcc
-all-debug: clean $(BUILD_DIR)/$(OS_ISO)
+all-debug: clean bootable-debug
@echo "Dumping the disassembled kernel code to $(BUILD_DIR)/kdump.txt"
@i686-elf-objdump -S $(BIN_DIR)/$(OS_BIN) > $(BUILD_DIR)/kdump.txt
--- /dev/null
+include config/make-os
+include config/make-cc
+include config/make-debug-tool
+include config/make-locations
+
+SRC_DIRS := kernel \
+ hal \
+ debug \
+ libs \
+ arch \
+
+SRC_FILES := $(foreach f, $(SRC_DIRS), $(shell find $(f) -name "*.[cS]"))
+
+OBJS := $(foreach f, $(SRC_FILES), $(OBJECT_DIR)/$(f).o)
+
+$(OBJECT_DIR)/%.S.o: %.S
+ @mkdir -p $(@D)
+ @echo " CC $<"
+ @$(CC) $(INCLUDES) -c $< -o $@
+
+$(OBJECT_DIR)/%.c.o: %.c
+ @mkdir -p $(@D)
+ @echo " CC $<"
+ @$(CC) $(INCLUDES) -c $< -o $@ $(CFLAGS)
+
+$(BIN_DIR)/$(OS_BIN): $(OBJECT_DIR) $(BIN_DIR) $(OBJS)
+ @echo " LD $(BIN_DIR)/$(OS_BIN)"
+ @$(CC) -T link/linker.ld -o $(BIN_DIR)/$(OS_BIN) $(OBJS) $(BIN_DIR)/$(USR_LIB) $(LDFLAGS)
+
+$(BUILD_DIR)/$(OS_ISO): $(BIN_DIR)/$(OS_BIN)
+ @./config-grub.sh ${OS_NAME} $(ISO_GRUB_DIR)/grub.cfg
+ @cp $(BIN_DIR)/$(OS_BIN) $(ISO_BOOT_DIR)
+ @cp -r $(USR_DIR) $(ISO_DIR)
+ @grub-mkrescue -o $(BUILD_DIR)/$(OS_ISO) $(ISO_DIR)
+
+all: $(BUILD_DIR)/$(OS_ISO)
+
+all-debug: O := -Og
+all-debug: CFLAGS := -g -std=gnu99 -ffreestanding $(O) $(W) $(ARCH_OPT) -D__LUNAIXOS_DEBUG__
+all-debug: LDFLAGS := -g -ffreestanding $(O) -nostdlib -lgcc
+all-debug: all
\ No newline at end of file
--- /dev/null
+include config/make-locations
+include config/make-os
+include config/make-cc
+
+SRC_FILES := $(wildcard uprog/*.c)
+PROGRAMES := $(patsubst uprog/%.c, $(USR_DIR)/%, $(SRC_FILES))
+
+$(USR_DIR)/%:
+ @echo " BUILD $(*F)"
+ @$(CC) -T usr/link-usr.ld $(INCLUDES) $(CFLAGS) $(LDFLAGS) uprog/$(*F).c $(BIN_DIR)/$(USR_LIB) -o $@
+
+all: $(PROGRAMES)
\ No newline at end of file
--- /dev/null
+include config/make-cc
+include config/make-os
+include config/make-locations
+
+SRC_DIRS := usr
+
+SRC_FILES := $(foreach f, $(SRC_DIRS), $(shell find $(f) -name "*.[cS]"))
+
+OBJS := $(foreach f, $(SRC_FILES), $(OBJECT_DIR)/$(f).o)
+
+$(OBJECT_DIR)/%.S.o: %.S
+ @mkdir -p $(@D)
+ @echo " CC $<"
+ @$(CC) $(INCLUDES) -c $< -o $@
+
+$(OBJECT_DIR)/%.c.o: %.c
+ @mkdir -p $(@D)
+ @echo " CC $<"
+ @$(CC) $(INCLUDES) -c $< -o $@ $(CFLAGS)
+
+$(BIN_DIR)/$(USR_LIB): $(OBJS)
+ @echo " AR $@"
+ @$(AR) rcs $@ $^
+
+usr-runtime: $(BIN_DIR)/$(USR_LIB)
+
+usr-runtime-debug: O := -Og
+usr-runtime-debug: CFLAGS := -g -std=gnu99 -ffreestanding $(O) $(W) $(ARCH_OPT) -D__LUNAIXOS_DEBUG__
+usr-runtime-debug: LDFLAGS := -g -ffreestanding $(O) -nostdlib -lgcc
+usr-runtime-debug: usr-runtime
+
+usr-objs: $(OBJS)
\ No newline at end of file
--- /dev/null
+#include <fcntl.h>
+#include <sys/lunaix.h>
+#include <unistd.h>
+
+int
+main(int argc, const char** argv)
+{
+ int errno = 0;
+
+ if ((errno = open("/dev/tty", 0))) {
+ syslog(2, "fail to open tty (%d)\n", errno);
+ return 0;
+ }
+
+ if ((errno = dup(errno))) {
+ syslog(2, "fail to setup tty i/o (%d)\n", errno);
+ return 0;
+ }
+
+ syslog(0, "user space!\n");
+
+ return 0;
+}
\ No newline at end of file
#include <lunaix/syscall.h>
-#include <usr/sys/dirent.h>
+#include <sys/dirent.h>
__LXSYSCALL2(int, sys_readdir, int, fd, struct lx_dirent*, dent)
#include <lunaix/syscall.h>
-#include <usr/errno.h>
+#include <errno.h>
__LXSYSCALL(int, geterrno);
\ No newline at end of file
#include <lunaix/syscall.h>
-#include <usr/fcntl.h>
+#include <fcntl.h>
__LXSYSCALL2(int, open, const char*, path, int, options)
#include <lunaix/syscall.h>
-#include <usr/sys/ioctl.h>
+#include <sys/ioctl.h>
__LXSYSCALL2_VARG(int, ioctl, int, fd, int, req);
\ No newline at end of file
#include <lunaix/syscall.h>
-#include <usr/sys/lunaix.h>
+#include <sys/lunaix.h>
__LXSYSCALL(void, yield);
#include <lunaix/syscall.h>
-#include <usr/sys/mann.h>
+#include <sys/mann.h>
__LXSYSCALL2_VARG(void*, sys_mmap, void*, addr, size_t, length);
#include <lunaix/syscall.h>
-#include <usr/sys/mount.h>
+#include <sys/mount.h>
__LXSYSCALL4(int,
mount,
#include <lunaix/syscall.h>
-#include <usr/signal.h>
+#include <signal.h>
__LXSYSCALL2(int, signal, int, signum, sighandler_t, handler);
#include <lunaix/syscall.h>
-#include <usr/unistd.h>
+#include <unistd.h>
__LXSYSCALL(pid_t, fork)
#ifndef __LUNAIX_SYS_FCNTL_H
#define __LUNAIX_SYS_FCNTL_H
-#include <usr/fcntl_defs.h>
-#include <usr/sys/types.h>
+#include <fcntl_defs.h>
+#include <sys/types.h>
int
open(const char* path, int flags);
#ifndef __LUNAIX_SYS_SIGNAL_H
#define __LUNAIX_SYS_SIGNAL_H
-#include <usr/signal_defs.h>
-#include <usr/sys/types.h>
+#include <signal_defs.h>
+#include <sys/types.h>
int
signal(int signum, sighandler_t handler);
#ifndef __LUNAIX_SYS_DIRENT_H
#define __LUNAIX_SYS_DIRENT_H
-#include <usr/sys/dirent_defs.h>
+#include <sys/dirent_defs.h>
int
sys_readdir(int fd, struct lx_dirent* dirent);
#ifndef __LUNAIX_SYS_LUNAIX_H
#define __LUNAIX_SYS_LUNAIX_H
-#include <usr/sys/types.h>
+#include <sys/types.h>
void
yield();
#ifndef __LUNAIX_SYS_MANN_H
#define __LUNAIX_SYS_MANN_H
-#include <usr/sys/mann_flags.h>
-#include <usr/sys/types.h>
+#include <sys/mann_flags.h>
+#include <sys/types.h>
void*
mmap(void* addr, size_t length, int proct, int flags, int fd, off_t offset);
#ifndef __LUNAIX_SYS_MOUNT_H
#define __LUNAIX_SYS_MOUNT_H
-#include <usr/sys/types.h>
+#include <sys/types.h>
int
mount(const char* source, const char* target, const char* fstype, int flags);
#ifndef __LUNAIX_SYS_UNISTD_H
#define __LUNAIX_SYS_UNISTD_H
-#include <usr/sys/types.h>
+#include <sys/types.h>
pid_t
fork();
--- /dev/null
+ENTRY(_u_start)
+
+SECTIONS {
+ . = 0x400000;
+}
\ No newline at end of file
--- /dev/null
+#define __USR_WRAPPER__
+#include <lunaix/ld.h>
+
+int
+usr_pre_init(struct usr_exec_param* param)
+{
+ // TODO some inits before executing user program
+
+ return 0;
+}
\ No newline at end of file
--- /dev/null
+#define __ASM__
+#include <lunaix/syscall.h>
+
+.section .text
+ .global _u_start
+ _u_start:
+ call usr_pre_init
+ jnz 1f
+
+ popl %eax
+
+ pushl (%eax) // argc
+ pushl 4(%eax) // argv
+
+ xorl %eax, %eax
+ call main
+
+ 1:
+ movl %eax, %ebx
+ movl $__SYSCALL__exit, %eax
+ int $LUNAIX_SYS_CALL
+
+ ud2 // should not reach
\ No newline at end of file