Benutzer-Werkzeuge

Webseiten-Werkzeuge


start

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
start [2025/12/06 09:33]
jango
start [2025/12/10 10:09] (aktuell)
jango
Zeile 1: Zeile 1:
-<code> 
-// kernel.c  (freestanding, 32-bit) 
-// Minimal "better kernel": VGA terminal + keyboard driver + tiny shell. 
-// You can split this later into vga.c/keyboard.c/shell.c. 
  
-#include <stddef.h> 
- 
-// -------- types (if you already have uint8/uint16/uint32 in utils.h, remove these) ----- 
-typedef unsigned char  uint8; 
-typedef unsigned short uint16; 
-typedef unsigned int   uint32; 
- 
-// -------- port I/O ---------- 
-static inline void outb(uint16_t port, uint8_t val) { 
-    asm volatile ("outb %b0, %w1" 
-                  : 
-                  : "a"(val), "Nd"(port)); 
-} 
- 
-static inline uint8_t inb(uint16_t port) { 
-    uint8_t ret; 
-    asm volatile ("inb %w1, %b0" 
-                  : "=a"(ret) 
-                  : "Nd"(port)); 
-    return ret; 
-} 
- 
-static inline void io_wait(void) { 
-    // 0x80 ist klassisch "slow" I/O port 
-    asm volatile ("outb %b0, %w1" : : "a"((uint8_t)0), "Nd"((uint16_t)0x80)); 
-} 
- 
-// -------- very small utils (no libc) ---------- 
-static void *memset_(void *dst, int v, size_t n) { 
-    uint8 *p = (uint8*)dst; 
-    while (n--) *p++ = (uint8)v; 
-    return dst; 
-} 
-static void *memmove_(void *dst, const void *src, size_t n) { 
-    uint8 *d = (uint8*)dst; 
-    const uint8 *s = (const uint8*)src; 
-    if (d == s || n == 0) return dst; 
-    if (d < s) { while (n--) *d++ = *s++; } 
-    else { d += n; s += n; while (n--) *--d = *--s; } 
-    return dst; 
-} 
-static size_t strlen_(const char *s) { 
-    size_t n = 0; 
-    while (s && s[n]) n++; 
-    return n; 
-} 
-static int isspace_(char c) { return c==' ' || c=='\t' || c=='\n' || c=='\r'; } 
-static int tolower_(int c) { return (c>='A' && c<='Z') ? (c+32) : c; } 
-static int strcmpi_(const char *a, const char *b) { 
-    while (*a && *b) { 
-        int ca = tolower_(*a), cb = tolower_(*b); 
-        if (ca != cb) return ca - cb; 
-        a++; b++; 
-    } 
-    return tolower_(*a) - tolower_(*b); 
-} 
- 
-// -------- VGA terminal ---------- 
-#define VGA_ADDRESS     0xB8000 
-#define VGA_W           80 
-#define VGA_H           25 
-#define VGA_CRTC_INDEX  0x3D4 
-#define VGA_CRTC_DATA   0x3D5 
- 
-enum vga_color { 
-    BLACK=0, BLUE=1, GREEN=2, CYAN=3, RED=4, MAGENTA=5, BROWN=6, LIGHT_GREY=7, 
-    DARK_GREY=8, LIGHT_BLUE=9, LIGHT_GREEN=10, LIGHT_CYAN=11, LIGHT_RED=12, 
-    LIGHT_MAGENTA=13, LIGHT_BROWN=14, WHITE=15 
-}; 
- 
-static volatile uint16 *g_vga = (volatile uint16*)VGA_ADDRESS; 
-static uint8 g_fg = WHITE, g_bg = BLUE; 
-static uint16 g_cursor = 0; // 0..(VGA_W*VGA_H-1) 
- 
-static inline uint16 vga_entry(char ch, uint8 fg, uint8 bg) { 
-    uint8 attr = (uint8)((bg << 4) | (fg & 0x0F)); 
-    return (uint16)((uint16)attr << 8) | (uint8)ch; 
-} 
-static void vga_set_cursor(uint16 pos) { 
-    outb(VGA_CRTC_INDEX, 0x0F); 
-    outb(VGA_CRTC_DATA, (uint8)(pos & 0xFF)); 
-    outb(VGA_CRTC_INDEX, 0x0E); 
-    outb(VGA_CRTC_DATA, (uint8)((pos >> 8) & 0xFF)); 
-} 
-static void term_set_color(uint8 fg, uint8 bg) { g_fg = fg; g_bg = bg; } 
- 
-static void term_clear(void) { 
-    for (uint32 i=0; i < VGA_W*VGA_H; i++) g_vga[i] = vga_entry(' ', g_fg, g_bg); 
-    g_cursor = 0; 
-    vga_set_cursor(g_cursor); 
-} 
- 
-static void term_scroll_if_needed(void) { 
-    uint32 row = g_cursor / VGA_W; 
-    if (row < VGA_H) return; 
- 
-    // scroll up 1 row 
-    memmove_((void*)g_vga, (const void*)(g_vga + VGA_W), (VGA_H-1)*VGA_W*sizeof(uint16)); 
-    // clear last row 
-    for (uint32 i=(VGA_H-1)*VGA_W; i < VGA_H*VGA_W; i++) 
-        g_vga[i] = vga_entry(' ', g_fg, g_bg); 
- 
-    g_cursor = (VGA_H-1)*VGA_W; 
-} 
- 
-static void term_putc(char c) { 
-    if (c == '\n') { 
-        g_cursor += VGA_W - (g_cursor % VGA_W); 
-        term_scroll_if_needed(); 
-        vga_set_cursor(g_cursor); 
-        return; 
-    } 
-    if (c == '\r') return; 
- 
-    g_vga[g_cursor++] = vga_entry(c, g_fg, g_bg); 
-    term_scroll_if_needed(); 
-    vga_set_cursor(g_cursor); 
-} 
-static void term_write(const char *s) { 
-    for (size_t i=0; s && s[i]; i++) term_putc(s[i]); 
-} 
- 
-// backspace within the current line (won't jump to prev line here) 
-static void term_backspace(void) { 
-    if (g_cursor == 0) return; 
-    // don't backspace over prompt " > " (simple guard: stop at col 2) 
-    uint16 col = g_cursor % VGA_W; 
-    if (col <= 2) return; 
- 
-    g_cursor--; 
-    g_vga[g_cursor] = vga_entry(' ', g_fg, g_bg); 
-    vga_set_cursor(g_cursor); 
-} 
- 
-// -------- Keyboard (polling, robust, no busy-wait bugs) ---------- 
-#define KBD_DATA    0x60 
-#define KBD_STATUS  0x64 
- 
-static inline uint8 kbd_has_data(void) { return (inb(KBD_STATUS) & 0x01); } 
-static inline uint8 kbd_read_scancode(void) { return inb(KBD_DATA); } 
- 
-// simple typematic repeat filter (like your idea, but safe) 
-static uint8 key_down[128]; 
-static uint8 e0_prefix; 
- 
-// scancode set 1 maps 
-static const char map_norm[128] = { 
-    [0x02]='1',[0x03]='2',[0x04]='3',[0x05]='4',[0x06]='5',[0x07]='6',[0x08]='7',[0x09]='8',[0x0A]='9',[0x0B]='0', 
-    [0x0C]='-',[0x0D]='=', 
-    [0x10]='q',[0x11]='w',[0x12]='e',[0x13]='r',[0x14]='t',[0x15]='y',[0x16]='u',[0x17]='i',[0x18]='o',[0x19]='p', 
-    [0x1A]='[',[0x1B]=']', 
-    [0x1E]='a',[0x1F]='s',[0x20]='d',[0x21]='f',[0x22]='g',[0x23]='h',[0x24]='j',[0x25]='k',[0x26]='l', 
-    [0x27]=';',[0x28]='\'',[0x29]='`', 
-    [0x2B]='\\', 
-    [0x2C]='z',[0x2D]='x',[0x2E]='c',[0x2F]='v',[0x30]='b',[0x31]='n',[0x32]='m', 
-    [0x33]=',',[0x34]='.',[0x35]='/', 
-    [0x39]=' ', 
-}; 
- 
-static const char map_shift[128] = { 
-    [0x02]='!',[0x03]='@',[0x04]='#',[0x05]='$',[0x06]='%',[0x07]='^',[0x08]='&',[0x09]='*',[0x0A]='(',[0x0B]=')', 
-    [0x0C]='_',[0x0D]='+', 
-    [0x10]='Q',[0x11]='W',[0x12]='E',[0x13]='R',[0x14]='T',[0x15]='Y',[0x16]='U',[0x17]='I',[0x18]='O',[0x19]='P', 
-    [0x1A]='{',[0x1B]='}', 
-    [0x1E]='A',[0x1F]='S',[0x20]='D',[0x21]='F',[0x22]='G',[0x23]='H',[0x24]='J',[0x25]='K',[0x26]='L', 
-    [0x27]=':',[0x28]='"',[0x29]='~', 
-    [0x2B]='|', 
-    [0x2C]='Z',[0x2D]='X',[0x2E]='C',[0x2F]='V',[0x30]='B',[0x31]='N',[0x32]='M', 
-    [0x33]='<',[0x34]='>',[0x35]='?', 
-    [0x39]=' ', 
-}; 
- 
-static uint8 kbd_shift; 
-static uint8 kbd_caps; 
- 
-static int kbd_get_scancode_once(uint8 *out_sc) { 
-    if (!kbd_has_data()) return 0; 
-    uint8 sc = kbd_read_scancode(); 
- 
-    if (sc == 0xE0) { e0_prefix = 1; return 0; } 
- 
-    // break (release) 
-    if (sc & 0x80) { 
-        uint8 make = sc & 0x7F; 
-        if (!e0_prefix && make < 128) key_down[make] = 0; 
-        // handle shift release 
-        if (!e0_prefix && (make == 0x2A || make == 0x36)) kbd_shift = 0; 
-        e0_prefix = 0; 
-        return 0; 
-    } 
- 
-    // make (press) - ignore typematic repeats 
-    if (!e0_prefix && sc < 128) { 
-        if (key_down[sc]) return 0; 
-        key_down[sc] = 1; 
-    } 
- 
-    e0_prefix = 0; 
-    *out_sc = sc; 
-    return 1; 
-} 
- 
-static char kbd_translate(uint8 sc) { 
-    // modifiers 
-    if (sc == 0x2A || sc == 0x36) { kbd_shift = 1; return 0; } // shift 
-    if (sc == 0x3A) { kbd_caps ^= 1; return 0; }               // caps lock 
- 
-    // special keys 
-    if (sc == 0x1C) return '\n'; // enter 
-    if (sc == 0x0E) return '\b'; // backspace 
-    if (sc == 0x0F) return '\t'; // tab (optional) 
- 
-    char c = kbd_shift ? map_shift[sc] : map_norm[sc]; 
-    if (!c) return 0; 
- 
-    // caps only affects letters (and only if shift isn't producing uppercase already) 
-    if (kbd_caps && !kbd_shift && (c >= 'a' && c <= 'z')) c = (char)(c - 32); 
-    return c; 
-} 
- 
-// blocking getchar (polling). If you have timer IRQs enabled, you can use hlt to reduce CPU. 
-static char kbd_getchar(void) { 
-    for (;;) { 
-        uint8 sc; 
-        if (kbd_get_scancode_once(&sc)) { 
-            char c = kbd_translate(sc); 
-            if (c) return c; 
-        } else { 
-            // reduce busy loop a bit 
-            io_wait(); 
-            // OPTIONAL (only if interrupts are enabled): 
-            // asm volatile("hlt"); 
-        } 
-    } 
-} 
- 
-// -------- tiny shell ---------- 
-#define LINE_MAX 128 
- 
-static void shell_prompt(void) { 
-    term_putc('\n'); 
-    term_write("> "); 
-} 
- 
-static void cmd_help(void) { 
-    term_write("Commands:\n"); 
-    term_write("  help           - this help\n"); 
-    term_write("  clear          - clear screen\n"); 
-    term_write("  echo <text>    - print text\n"); 
-    term_write("  color <fg> <bg>- set colors (0-15)\n"); 
-    term_write("  reboot         - triple-fault/8042 reboot\n"); 
-} 
- 
-static int parse_u8_dec(const char *s, uint8 *out) { 
-    if (!s || !*s) return 0; 
-    uint32 v = 0; 
-    for (; *s; s++) { 
-        if (*s < '0' || *s > '9') return 0; 
-        v = v*10u + (uint32)(*s - '0'); 
-        if (v > 255u) return 0; 
-    } 
-    *out = (uint8)v; 
-    return 1; 
-} 
- 
-static void do_reboot(void) { 
-    // try 8042 reboot pulse 
-    outb(0x64, 0xFE); 
-    // fallback: halt 
-    for (;;) asm volatile("hlt"); 
-} 
- 
-static void shell_exec(char *line) { 
-    // tokenize in-place 
-    char *argv[8] = {0}; 
-    int argc = 0; 
- 
-    // skip leading spaces 
-    while (*line && isspace_(*line)) line++; 
- 
-    while (*line && argc < 8) { 
-        argv[argc++] = line; 
-        while (*line && !isspace_(*line)) line++; 
-        if (!*line) break; 
-        *line++ = 0; 
-        while (*line && isspace_(*line)) line++; 
-    } 
-    if (argc == 0) return; 
- 
-    if (strcmpi_(argv[0], "help") == 0) { 
-        cmd_help(); 
-        return; 
-    } 
-    if (strcmpi_(argv[0], "clear") == 0) { 
-        term_clear(); 
-        return; 
-    } 
-    if (strcmpi_(argv[0], "echo") == 0) { 
-        if (argc >= 2) { 
-            term_write(argv[1]); 
-            for (int i=2; i<argc; i++) { term_putc(' '); term_write(argv[i]); } 
-        } 
-        term_putc('\n'); 
-        return; 
-    } 
-    if (strcmpi_(argv[0], "color") == 0) { 
-        uint8 fg, bg; 
-        if (argc == 3 && parse_u8_dec(argv[1], &fg) && parse_u8_dec(argv[2], &bg) && fg < 16 && bg < 16) { 
-            term_set_color(fg, bg); 
-            term_write("ok\n"); 
-        } else { 
-            term_write("usage: color <fg 0-15> <bg 0-15>\n"); 
-        } 
-        return; 
-    } 
-    if (strcmpi_(argv[0], "reboot") == 0) { 
-        term_write("rebooting...\n"); 
-        do_reboot(); 
-        return; 
-    } 
- 
-    term_write("unknown command: "); 
-    term_write(argv[0]); 
-    term_putc('\n'); 
-} 
- 
-static void shell_run(void) { 
-    char line[LINE_MAX]; 
-    size_t len = 0; 
-    memset_(line, 0, sizeof(line)); 
- 
-    term_write("Kernel-OS v2.0\n"); 
-    term_write("(C) Manuel Zarat (improved)\n"); 
-    term_write("Type 'help' for commands.\n"); 
-    term_write("> "); 
- 
-    for (;;) { 
-        char c = kbd_getchar(); 
- 
-        if (c == '\b') { 
-            if (len > 0) { 
-                len--; 
-                line[len] = 0; 
-                term_backspace(); 
-            } 
-            continue; 
-        } 
- 
-        if (c == '\n') { 
-            term_putc('\n'); 
-            shell_exec(line); 
-            memset_(line, 0, sizeof(line)); 
-            len = 0; 
-            term_write("> "); 
-            continue; 
-        } 
- 
-        // printable range: keep it simple 
-        if (c >= 32 && c <= 126) { 
-            if (len < LINE_MAX - 1) { 
-                line[len++] = c; 
-                line[len] = 0; 
-                term_putc(c); 
-            } 
-        } 
-    } 
-} 
- 
-// -------- entry ---------- 
-void kernel_entry(void) { 
-    term_set_color(WHITE, BLUE); 
-    term_clear(); 
-    shell_run(); 
-} 
-</code> 
 Hallo Besucher! Willkommen in diesem kleinen Wiki rund um IT. Vieles ist noch **unvollständig, unstrukturiert oder vielleicht sogar falsch bzw. irreführend**. Hallo Besucher! Willkommen in diesem kleinen Wiki rund um IT. Vieles ist noch **unvollständig, unstrukturiert oder vielleicht sogar falsch bzw. irreführend**.
  
start.1765009997.txt.gz · Zuletzt geändert: 2025/12/06 09:33 von jango