Skip to content

Commit

Permalink
修复不开启日志时无法启动的bug
Browse files Browse the repository at this point in the history
  • Loading branch information
copi143 committed Jan 10, 2025
1 parent 1337c4d commit d3a754a
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 59 deletions.
51 changes: 51 additions & 0 deletions doc/src/app/return-value.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@

# 应用程序返回值

应用程序返回值是一个 32 位整数(即使在 64 位系统上也是如此)。<br>
The application return value is a 32-bit integer (even on 64-bit systems).

应用程序返回值的高 16 位不应当被应用程序设置,而只应被操作系统或系统库设置。<br>
The high 16 bits of the application return value should not be set by the application, but only by the operating system or system library.

应用程序退出码应当是一个 8 位无符号整数,如果需要也可以是一个 16 位无符号整数。<br>
The application exit code should be an 8-bit unsigned integer, and can be a 16-bit unsigned integer if necessary.

- `0-7`: 应用程序退出码 / Application exit code.
- `8-15`: 可用 / Available.
- `16-23`: 错误码 / Error code.
- `24-28`: 保留 / Reserved.
- `29`: 链接错误 / Link error.
- `30`: 非应用程序主动退出 / Non-application initiated exit.
- `31`: 保留 / Reserved.

第 31 位永远不会被使用,第 24-28 位可能在未来被使用。<br>
The 31st bit will never be used, and the 16th-28th bits may be used in the future.

第 30 位标记为非应用程序主动退出,可能是因为启动时链接错误、未处理信号、因某些原因被杀死等。<br>
The 30th bit is marked as a non-application initiated exit, which may be due to a link error at startup, unhandled signals, being killed for some reason, etc.

第 29 位标记为链接错误,可能是因为未找到依赖库、文件数据错误等。<br>
The 29th bit is marked as a link error, which may be due to missing dependent libraries, file data errors, etc.

第 16-23 位是错误码,用于标记应用程序的错误类型。<br>
The 16th-23rd bits are error codes used to mark the error type of the application.

非应用程序主动退出时低 16 位将被填充为 0xffff。<br>
When a non-application initiated exit occurs, the low 16 bits will be filled with 0xffff.

应用程序退出码的值应当在 0 到 255 之间,其中 0 表示成功,非 0 表示失败。<br>
The value of the application exit code should be between 0 and 255, where 0 indicates success and non-zero indicates failure.

## 链接错误

- `0` 未知错误 / Unknown error.
- `1` 未定义入口点 / Entry point undefined.
- `2` 无法找到文件 / Unable to find file.
- `3` 无法读取文件 / Unable to read file.
- `4` 无法解析文件 / Unable to parse file.
- `5` 无法找到依赖库 / Unable to find dependent library.
- `6` 无法读取依赖库 / Unable to read dependent library.
- `7` 无法解析依赖库 / Unable to parse dependent library.
- `8` 内存不足 / Out of memory.
- `9` 架构不匹配 / Architecture mismatch.
- `255` 传入参数错误 / Invalid input parameters.
8 changes: 7 additions & 1 deletion include/libc-base/asm/asm.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,13 @@

#define asm_setreg(reg, value) ({ asm volatile("mov %0, %%" #reg "\n\t" ::"r"((size_t)(value))); })

#define used_val(value) ({ asm volatile("" ::"r,m"(value) : "memory"); })
#define used_val1(value) ({ asm volatile("" ::"r,m"(value)); })
#define used_val2(value, ...) ({ used_val1(value), used_val1(__VA_ARGS__); })
#define used_val3(value, ...) ({ used_val1(value), used_val2(__VA_ARGS__); })
#define used_val4(value, ...) ({ used_val1(value), used_val3(__VA_ARGS__); })
#define used_val5(value, ...) ({ used_val1(value), used_val4(__VA_ARGS__); })
#define used_val6(value, ...) ({ used_val1(value), used_val5(__VA_ARGS__); })
#define used_val(...) CONCAT(used_val, COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__)

/**
*\brief 加载 GDT
Expand Down
4 changes: 2 additions & 2 deletions src/kernel/cpu/gdtidt.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ size_t syscall(size_t eax, size_t ebx, size_t ecx, size_t edx, size_t esi, size_

FASTCALL void inthandler(i32 id, regs32 *regs) {
kassert(id < 256);
if (id != 0x07 && id != 0x2d) asm_set_ts;
if (fpu_using_task != null && id != 0x07 && id != 0x2d) asm_set_ts;
if (id >= 0x20 && id < 0x30) send_eoi(id - 0x20);

if (acpi_inited) {
Expand All @@ -55,7 +55,7 @@ FASTCALL void inthandler(i32 id, regs32 *regs) {
klogw("Unknown interrupt %02x (%d)", id, id);
}

if (id != 0x07 && id != 0x2d) {
if (fpu_using_task != null && id != 0x07 && id != 0x2d) {
val from_usermod = (regs->cs & 3) == 3;
(current_task == fpu_using_task && fpu_ctx_usermod == from_usermod) ? asm_clr_ts : asm_set_ts;
}
Expand Down
4 changes: 1 addition & 3 deletions src/kernel/exec/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,13 @@ void task_to_user_mode_elf() {

struct args args = {.cmdline = current_task->command_line, .sp = (void *)TASK_ARGS_ADDR};
parse_args(&args);
used_val(*args.argv, *args.envp);
klogd("argc: %d", args.argc);
klogd("argv: %p", args.argv);
klogd("argv: %p", args.envp);
for (int i = 0; i < args.argc; i++) {
klogd("argv[%d]: %s", i, args.argv[i]);
}

vfs_node_t file = vfs_open("/fatfs0/ld-plos.bin");
// vfs_node_t file = vfs_open(args.argv[0]);
if (file == null) {
if (mouse_use_task == current_task) mouse_sleep(&mdec);
kloge();
Expand Down
17 changes: 5 additions & 12 deletions src/kernel/task/basetask.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,26 @@ static plff_t load_font(cstr path) {
}

void plty_set_default(plty_t plty);

void stdout_read() {}
void stdout_write(int drive, u8 *buffer, u32 number, u32 lba) {
for (int i = 0; i < number; i++) {
putchar(buffer[i]);
}
}

void random_read(int drive, u8 *buffer, u32 number, u32 lba) {
for (int i = 0; i < number; i++) {
buffer[i] = krandb();
}
}
void random_write(int drive, u8 *buffer, u32 number, u32 lba) {}
void random_write(int drive, u8 *buffer, u32 number, u32 lba) {}

char *GetSVGACharOEMString();
bool is_vbox = false;

static void check_device() {
char *s = strdup(GetSVGACharOEMString());
char *s = GetSVGACharOEMString();
info("VIDEO CARD: %s", s);
if (strstr(s, "VirtualBox")) {
info("VirtualBox detected");
Expand All @@ -64,16 +67,6 @@ static void check_device() {
is_vbox = false;
info("VirtualBox not detected");
}
free(s);
}

static void draw(int n) {
u32 *buf = vbe_backbuffer;
for (size_t y = 0; y < screen_h; y++) {
for (size_t x = 0; x < screen_w; x++) {
buf[y * screen_w + x] = (0xff8000 + x + n) & 0xffffff;
}
}
}

extern bool debug_enabled;
Expand Down
87 changes: 46 additions & 41 deletions src/ld-plos/ld-plos.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,36 @@
#include <libc-base.h>
#include <sys.h>

#include "ld-plos.h"

// 一个在没有标准库的环境下加载动态链接 elf 文件的程序

#define syscall(...) __syscall(__VA_ARGS__)
static int argc;
static char **argv;
static char **envp;

#ifdef __x86_64__
// 加载完毕后运行应用程序
static __attr(noreturn) void run(usize entry) {
asm("mov %0, %%edi\n\t" ::"r"(argc));
asm("mov %0, %%esi\n\t" ::"r"(argv));
asm("mov %0, %%edx\n\t" ::"r"(envp));
asm volatile("jmp *%0" ::"r"(entry));
__builtin_unreachable();
}

static void load_elf32(const Elf32Header *elf) {}
static void load_elf64(const Elf64Header *elf) {}
#ifdef __x86_64__

#else
static int load_elf32(const Elf32Header *elf) {
return 0;
}

void print_num(usize num) {
static char buffer[32];
char *buf = buffer + 32;
*--buf = '\0';
*--buf = '\n';
while (num) {
int digit = num % 16;
*--buf = (digit < 10) ? digit + '0' : digit - 10 + 'a';
num /= 16;
}
syscall(SYSCALL_PRINT, buf);
static int load_elf64(const Elf64Header *elf) {
return 0;
}

#else

int load_segment(const Elf32ProgramHeader *prog, const void *elf) {
print_num(prog->type);
print_num(prog->offset);
print_num(prog->vaddr);
print_num(prog->filesz);
print_num(prog->memsz);
print_num(prog->flags);
if (prog->type != ELF_PROGRAM_TYPE_LOAD) return 0;
usize hi = PADDING_UP(prog->vaddr + prog->memsz, PAGE_SIZE);
usize lo = PADDING_DOWN(prog->vaddr, PAGE_SIZE);
Expand All @@ -42,45 +41,51 @@ int load_segment(const Elf32ProgramHeader *prog, const void *elf) {
return 0;
}

static void load_elf32(const Elf32Header *elf) {
static int load_elf32(const Elf32Header *elf) {
var prog = (const Elf32ProgramHeader *)((usize)elf + elf->phoff);
for (usize i = 0; i < elf->phnum; i++) {
if (load_segment(prog + i, elf) < 0) return;
if (load_segment(prog + i, elf) < 0) return LDE_FILE_UNPARSABLE;
}
asm volatile("jmp *%0" : : "r"(elf->entry));
run(elf->entry);
}
static void load_elf64(const void *elf) {

static int load_elf64(const void *elf) {
// Can't load 64-bit ELF in 32-bit system.
return LDE_ARCH_MISSMATCH;
}

#endif

void __linker_main(int argc, char **argv, char **envp) {
if (argc <= 0 || argv == null || envp == null) return;
if (argv[0] == null) return;
int __linker_main(int argc, char **argv, char **envp) {
if (argc <= 0 || argv == null || envp == null || argv[0] == null) return LDE_INVALID_INPUT;

usize size = syscall(SYSCALL_FILE_SIZE, argv[0]);
isize size = syscall(SYSCALL_FILE_SIZE, argv[0]);
if (size < 0) return LDE_FILE_NOT_FOUND;
void *file = (void *)syscall(SYSCALL_MMAP, null, size);
syscall(SYSCALL_LOAD_FILE, argv[0], file, size);
if (file == null) return LDE_OUT_OF_MEMORY;
if (syscall(SYSCALL_LOAD_FILE, argv[0], file, size) < 0) return LDE_FILE_UNREADABLE;

const Elf32Header *elf = (Elf32Header *)file;
const ElfIdent *ident = (ElfIdent *)file;
if (ident->magic != ELF_MAGIC) return 1;

const ElfIdent *ident = (ElfIdent *)file;
if (ident->magic != ELF_MAGIC) return;
if (ident->class == ELF_CLASS_32) {
load_elf32(file);
} else if (ident->class == ELF_CLASS_64) {
load_elf64(file);
if (elf->machine != ELF_MACHINE_IA32) return LDE_ARCH_MISSMATCH;
return load_elf32(file);
}
if (ident->class == ELF_CLASS_64) {
if (elf->machine != ELF_MACHINE_AMD64) return LDE_ARCH_MISSMATCH;
return load_elf64(file);
}
return LDE_FILE_UNPARSABLE;
}

void __linker_start() {
int volatile argc;
char **volatile argv;
char **volatile envp;
asm("mov %%edi, %0\n\t" : "=r"(argc));
asm("mov %%esi, %0\n\t" : "=r"(argv));
asm("mov %%edx, %0\n\t" : "=r"(envp));

__linker_main(argc, argv, envp);
int errcode = __linker_main(argc, argv, envp);

syscall(SYSCALL_EXIT, INT_MAX);
syscall(SYSCALL_EXIT, MASK(30) | MASK(29) | (errcode << 16));
}
16 changes: 16 additions & 0 deletions src/ld-plos/ld-plos.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

// 动态链接器错误
#define LDE_UNKNOWN 0 // 未知错误
#define LDE_ENTRY_POINT 1 // 未定义入口点
#define LDE_FILE_NOT_FOUND 2 // 无法找到文件
#define LDE_FILE_UNREADABLE 3 // 无法读取文件
#define LDE_FILE_UNPARSABLE 4 // 无法解析文件
#define LDE_DEP_LIB_NOT_FOUND 5 // 无法找到依赖库
#define LDE_DEP_LIB_UNREADABLE 6 // 无法读取依赖库
#define LDE_DEP_LIB_UNPARSABLE 7 // 无法解析依赖库
#define LDE_OUT_OF_MEMORY 8 // 内存不足
#define LDE_ARCH_MISSMATCH 9 // 架构不匹配
#define LDE_INVALID_INPUT 255 // 传入参数错误

#define syscall(...) __syscall(__VA_ARGS__)

0 comments on commit d3a754a

Please sign in to comment.