build.bat can create the image if missing, split the shell into native, posix and win32, clean up the build by moving executables into directories, the bootloader is no longer responsible to resolve drivers, fix ResolvePath, every process gets a copy of a module (dll), the child always inherits the cwd, fix function exports in posix, add unlink and exit to posix, add path translator to win32, first bugcheck.

This commit is contained in:
maksw committed 2026-05-13 09:24:16 +02:00
1 parent 0c7f461c6d
commit f80e66ecde
38 files changed
+1620 -462

No files matched your search

+247
View File
@@ -0,0 +1,247 @@
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <string.h>
#include <syscall.h>
#include <io_file.h>
// ---------------------------------------------------------------------------
// Output helpers
// ---------------------------------------------------------------------------
static void print(const char* s) {
SysWriteConsole(s, strlen(s));
}
static void printUInt(uint32_t n) {
char buf[12];
int i = 0;
if (n == 0) { print("0"); return; }
while (n > 0) { buf[i++] = (char)('0' + n % 10); n /= 10; }
char rev[12];
int j = 0;
while (i > 0) rev[j++] = buf[--i];
rev[j] = '\0';
print(rev);
}
static void printInt(int32_t n) {
if (n < 0) {
print("-");
printUInt((uint32_t)-(n + 1) + 1);
} else {
printUInt((uint32_t)n);
}
}
// ---------------------------------------------------------------------------
// Line editor
// ---------------------------------------------------------------------------
#define MAX_CMD 256
static void readLine(char* buf, int len) {
int pos = 0;
while (true) {
char c = SysKbReadChar();
if (!c) {
SysYield();
continue;
}
if (c == '\r' || c == '\n') {
print("\n");
break;
}
if ((c == '\b' || c == 127) && pos > 0) {
pos--;
print("\b \b");
continue;
}
if (c < 0x20 || c == 127)
continue;
if (pos < len - 1) {
buf[pos++] = c;
char echo[2] = { c, '\0' };
print(echo);
}
}
buf[pos] = '\0';
}
static char* trim(char* s) {
while (*s == ' ') s++;
int len = (int)strlen(s);
while (len > 0 && s[len - 1] == ' ') len--;
s[len] = '\0';
return s;
}
// ---------------------------------------------------------------------------
// Built-in commands
// ---------------------------------------------------------------------------
static void cmd_help() {
print("Available commands:\n"
" help - Show this list\n"
" dir - List files\n"
" cd <path> - Change directory\n"
" type <file> - Display file contents\n"
" del <file> - Delete a file\n"
" write <file> <tx> - Create a file with text\n"
" exit - Close the shell\n");
}
static void cmd_write(const char* args) {
char filename[MAX_CMD];
int i = 0;
while (args[i] != ' ' && args[i] != '\0' && i < MAX_CMD - 1) {
filename[i] = args[i];
i++;
}
filename[i] = '\0';
if (args[i] == '\0' || args[i+1] == '\0') {
print("write: usage: write <filename> <text>\n");
return;
}
uint32_t hFile;
if (SysCreateFile(filename, &hFile) != 0) {
print("write: could not create file\n");
return;
}
const char* text = args + i + 1;
size_t written;
SysWriteFile(hFile, text, strlen(text), &written);
SysCloseHandle(hFile);
print("File written successfully.\n");
}
static void cmd_dir(const char* path) {
uint32_t hDir;
// Validate input
if (path == NULL || path[0] == '\0') {
path = "."; // Default to current directory if empty
}
// SysOpenDir (Syscall 54) handles the const char* path directly
if (SysOpenDir(path, &hDir) != 0) {
SysDebugPrint("dir: failed to open directory\n");
return;
}
// Assuming KDIR_ENTRY is your structure for directory entries
KDIR_ENTRY ke;
// SysReadDir (Syscall 55) populates the buffer with entry data
// It typically returns 0 on success and non-zero (or error) when done
while (SysReadDir(hDir, &ke) == 0) {
// We assume ke.Name is a null-terminated string within the struct
print(ke.Name);
print("\n");
}
// Always close the handle (Syscall 26) to prevent leaks
SysCloseHandle(hDir);
}
static void cmd_type(const char* filename) {
uint32_t hFile;
if (SysOpenFile(filename, &hFile) != 0) {
print("type: error opening file\n");
return;
}
char buffer[512];
size_t bytesRead;
while (SysReadFile(hFile, buffer, sizeof(buffer) - 1, &bytesRead) == 0 && bytesRead > 0) {
buffer[bytesRead] = '\0';
print(buffer);
}
SysCloseHandle(hFile);
print("\n");
}
// ---------------------------------------------------------------------------
// Run one command
// ---------------------------------------------------------------------------
static int runCommand(const char* cmd) {
if (!cmd || *cmd == '\0') return 0;
if (strcmp(cmd, "exit") == 0) return 1;
if (strcmp(cmd, "help") == 0) { cmd_help(); return 0; }
if (strcmp(cmd, "crash") == 0) { *(int*)0 = 42; return 0; }
if (strcmp(cmd, "dir") == 0) {
cmd_dir(".");
return 0;
}
if (strncmp(cmd, "dir ", 4) == 0) {
cmd_dir(cmd + 4);
return 0;
}
if (strcmp(cmd, "clear") == 0) {
SysScreenClear(0x00000000);
return 0;
}
if (strncmp(cmd, "cd ", 3) == 0) {
SysSetCwd(cmd + 3);
return 0;
}
if (strncmp(cmd, "del ", 4) == 0) {
SysDeleteFile(cmd + 4);
return 0;
}
if (strncmp(cmd, "type ", 5) == 0) {
cmd_type(cmd + 5);
return 0;
}
if (strncmp(cmd, "write ", 6) == 0) {
cmd_write(cmd + 6);
return 0;
}
// --- External Process Execution ---
uint32_t hProc;
if (SysCreateProcess(cmd, &hProc, cmd) == 0) {
SysWaitForProcess(hProc);
int exitCode = 0;
SysGetProcessExitCode(hProc, &exitCode);
SysCloseHandle(hProc);
while (SysKbPoll()) {
(void)SysKbReadChar();
}
} else {
print("shell: launch failed\n");
}
return 0;
}
// ---------------------------------------------------------------------------
// Entry point
// ---------------------------------------------------------------------------
int main(int argc, char** argv) {
char lineBuf[MAX_CMD];
print("shell: ready\n");
while (true) {
print("> ");
readLine(lineBuf, MAX_CMD);
if (runCommand(trim(lineBuf)))
break;
}
print("shell: goodbye\n");
SysExitProcess(0);
return 0;
}