feat: Add Process Manager, Limine Framebuffer GUI, RTL8139 Net stack, and extended UNIX commands
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
#include "stdint.h"
|
||||
#include "stddef.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// 32-bit ARGB Color Palette Helpers
|
||||
#define FB_COLOR(r, g, b) (((uint32_t)(r) << 16) | ((uint32_t)(g) << 8) | (uint32_t)(b))
|
||||
#define FB_BLACK FB_COLOR(15, 17, 23)
|
||||
#define FB_WHITE FB_COLOR(240, 246, 252)
|
||||
#define FB_DARK_GRAY FB_COLOR(33, 38, 45)
|
||||
#define FB_LIGHT_GRAY FB_COLOR(139, 148, 158)
|
||||
#define FB_BLUE FB_COLOR(88, 166, 255)
|
||||
#define FB_NAVY FB_COLOR(22, 27, 34)
|
||||
#define FB_GREEN FB_COLOR(63, 185, 80)
|
||||
#define FB_RED FB_COLOR(248, 81, 73)
|
||||
#define FB_ORANGE FB_COLOR(210, 153, 34)
|
||||
#define FB_PURPLE FB_COLOR(188, 140, 255)
|
||||
#define FB_CYAN FB_COLOR(56, 189, 248)
|
||||
|
||||
typedef struct {
|
||||
uint32_t *buffer;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t pitch;
|
||||
uint32_t bpp;
|
||||
int is_initialized;
|
||||
} fb_context_t;
|
||||
|
||||
extern fb_context_t g_fb;
|
||||
|
||||
// Framebuffer API
|
||||
int fb_init(void);
|
||||
void fb_clear(uint32_t color);
|
||||
void fb_draw_pixel(int x, int y, uint32_t color);
|
||||
void fb_fill_rect(int x, int y, int w, int h, uint32_t color);
|
||||
void fb_draw_rect(int x, int y, int w, int h, uint32_t color);
|
||||
void fb_draw_char(int x, int y, char c, uint32_t fg, uint32_t bg);
|
||||
void fb_draw_string(int x, int y, const char *str, uint32_t fg, uint32_t bg);
|
||||
void fb_draw_window(int x, int y, int w, int h, const char *title);
|
||||
void fb_demo_desktop(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include "stdint.h"
|
||||
|
||||
// Standard 8x16 VGA bitmap font for characters 32 (' ') to 127
|
||||
// Each character is 16 bytes (1 byte per row, 8 bits wide)
|
||||
extern const uint8_t font8x16_data[96][16];
|
||||
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
#include "stdint.h"
|
||||
#include "stddef.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint16_t io_base;
|
||||
uint8_t mac[6];
|
||||
uint8_t rx_buffer[8192 + 16 + 1500] __attribute__((aligned(4)));
|
||||
uint8_t tx_buffers[4][1536] __attribute__((aligned(4)));
|
||||
uint8_t tx_cur;
|
||||
int is_initialized;
|
||||
uint64_t rx_packets;
|
||||
uint64_t tx_packets;
|
||||
uint64_t rx_bytes;
|
||||
uint64_t tx_bytes;
|
||||
} rtl8139_dev_t;
|
||||
|
||||
extern rtl8139_dev_t g_rtl8139;
|
||||
|
||||
// RTL8139 API
|
||||
int rtl8139_init(void);
|
||||
int rtl8139_send_packet(const void *data, uint16_t len);
|
||||
int rtl8139_poll_packet(void *out_buf, uint16_t max_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
+242
@@ -0,0 +1,242 @@
|
||||
#include "../include/fb.h"
|
||||
#include "../include/font8x16.h"
|
||||
#include "abi/syscalls.h"
|
||||
|
||||
fb_context_t g_fb = {0};
|
||||
|
||||
// Built-in standard 8x16 ASCII glyph table (Basic readable font)
|
||||
const uint8_t font8x16_data[96][16] = {
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 32 ' '
|
||||
{0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, // 33 '!'
|
||||
{0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 34 '"'
|
||||
{0x00,0x00,0x6C,0x6C,0xFE,0x6C,0x6C,0x6C,0xFE,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00}, // 35 '#'
|
||||
{0x18,0x18,0x7C,0xC6,0xC2,0xC0,0x7C,0x06,0x06,0x86,0xC6,0x7C,0x18,0x18,0x00,0x00}, // 36 '$'
|
||||
{0x00,0x00,0x00,0xC2,0xC6,0x0C,0x18,0x30,0x60,0xC6,0x86,0x00,0x00,0x00,0x00,0x00}, // 37 '%'
|
||||
{0x00,0x38,0x6C,0x6C,0x38,0x76,0xDC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,0x00}, // 38 '&'
|
||||
{0x00,0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 39 '\''
|
||||
{0x00,0x0C,0x18,0x30,0x30,0x60,0x60,0x60,0x60,0x30,0x30,0x18,0x0C,0x00,0x00,0x00}, // 40 '('
|
||||
{0x00,0x30,0x18,0x0C,0x0C,0x06,0x06,0x06,0x06,0x0C,0x0C,0x18,0x30,0x00,0x00,0x00}, // 41 ')'
|
||||
{0x00,0x00,0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 42 '*'
|
||||
{0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 43 '+'
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00}, // 44 ','
|
||||
{0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 45 '-'
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00}, // 46 '.'
|
||||
{0x00,0x00,0x02,0x06,0x0C,0x18,0x30,0x60,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00}, // 47 '/'
|
||||
{0x00,0x3C,0x66,0xC3,0xE3,0xD3,0xDB,0xCF,0xC7,0xC3,0x66,0x3C,0x00,0x00,0x00,0x00}, // 48 '0'
|
||||
{0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00}, // 49 '1'
|
||||
{0x00,0x3C,0x66,0xC3,0x03,0x06,0x0C,0x18,0x30,0x60,0xC3,0xFF,0x00,0x00,0x00,0x00}, // 50 '2'
|
||||
{0x00,0x3C,0x66,0xC3,0x03,0x06,0x1C,0x06,0x03,0xC3,0x66,0x3C,0x00,0x00,0x00,0x00}, // 51 '3'
|
||||
{0x00,0x06,0x0E,0x1E,0x36,0x66,0xC6,0xFF,0x06,0x06,0x06,0x0F,0x00,0x00,0x00,0x00}, // 52 '4'
|
||||
{0x00,0x7F,0x60,0x60,0x7C,0x66,0x03,0x03,0x03,0xC3,0x66,0x3C,0x00,0x00,0x00,0x00}, // 53 '5'
|
||||
{0x00,0x3C,0x66,0xC0,0xC0,0xDC,0xE6,0xC3,0xC3,0xC3,0x66,0x3C,0x00,0x00,0x00,0x00}, // 54 '6'
|
||||
{0x00,0xFF,0xC3,0x03,0x06,0x0C,0x18,0x30,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x00}, // 55 '7'
|
||||
{0x00,0x3C,0x66,0xC3,0xC3,0x66,0x3C,0x66,0xC3,0xC3,0x66,0x3C,0x00,0x00,0x00,0x00}, // 56 '8'
|
||||
{0x00,0x3C,0x66,0xC3,0xC3,0xC3,0x67,0x3B,0x03,0x03,0x66,0x3C,0x00,0x00,0x00,0x00}, // 57 '9'
|
||||
{0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00}, // 58 ':'
|
||||
{0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00}, // 59 ';'
|
||||
{0x00,0x06,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00}, // 60 '<'
|
||||
{0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 61 '='
|
||||
{0x00,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00}, // 62 '>'
|
||||
{0x00,0x3C,0x66,0xC3,0x03,0x06,0x0C,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, // 63 '?'
|
||||
{0x00,0x3C,0x66,0xC3,0xDF,0xDB,0xDB,0xDB,0xDE,0xC0,0x66,0x3C,0x00,0x00,0x00,0x00}, // 64 '@'
|
||||
{0x00,0x18,0x3C,0x66,0xC3,0xC3,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0x00,0x00,0x00,0x00}, // 65 'A'
|
||||
{0x00,0xFE,0x63,0x63,0x63,0x7E,0x63,0x63,0x63,0x63,0x63,0xFE,0x00,0x00,0x00,0x00}, // 66 'B'
|
||||
{0x00,0x3C,0x66,0xC3,0xC0,0xC0,0xC0,0xC0,0xC0,0xC3,0x66,0x3C,0x00,0x00,0x00,0x00}, // 67 'C'
|
||||
{0x00,0xFC,0x66,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x66,0xFC,0x00,0x00,0x00,0x00}, // 68 'D'
|
||||
{0x00,0xFF,0x63,0x60,0x60,0x7C,0x60,0x60,0x60,0x60,0x63,0xFF,0x00,0x00,0x00,0x00}, // 69 'E'
|
||||
{0x00,0xFF,0x63,0x60,0x60,0x7C,0x60,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00}, // 70 'F'
|
||||
{0x00,0x3C,0x66,0xC3,0xC0,0xC0,0xDE,0xC3,0xC3,0xC3,0x66,0x3C,0x00,0x00,0x00,0x00}, // 71 'G'
|
||||
{0x00,0xC3,0xC3,0xC3,0xC3,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x00,0x00,0x00,0x00}, // 72 'H'
|
||||
{0x00,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00}, // 73 'I'
|
||||
{0x00,0x0F,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0xC3,0x66,0x3C,0x00,0x00,0x00,0x00}, // 74 'J'
|
||||
{0x00,0xC3,0xC6,0xCC,0xD8,0xF0,0xF8,0xDC,0xCE,0xC6,0xC3,0xC3,0x00,0x00,0x00,0x00}, // 75 'K'
|
||||
{0x00,0xF0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x63,0x63,0xFF,0x00,0x00,0x00,0x00}, // 76 'L'
|
||||
{0x00,0xC3,0xE7,0xFF,0xDB,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x00,0x00,0x00,0x00}, // 77 'M'
|
||||
{0x00,0xC3,0xE3,0xF3,0xFB,0xDF,0xCF,0xC7,0xC3,0xC3,0xC3,0xC3,0x00,0x00,0x00,0x00}, // 78 'N'
|
||||
{0x00,0x3C,0x66,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x66,0x3C,0x00,0x00,0x00,0x00}, // 79 'O'
|
||||
{0x00,0xFE,0x63,0x63,0x63,0x63,0x7E,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00}, // 80 'P'
|
||||
{0x00,0x3C,0x66,0xC3,0xC3,0xC3,0xC3,0xC3,0xC7,0xCF,0x66,0x3C,0x06,0x03,0x00,0x00}, // 81 'Q'
|
||||
{0x00,0xFE,0x63,0x63,0x63,0x7E,0x6C,0x66,0x63,0x63,0x63,0xC6,0x00,0x00,0x00,0x00}, // 82 'R'
|
||||
{0x00,0x3C,0x66,0xC3,0x60,0x38,0x0E,0x03,0xC3,0xC3,0x66,0x3C,0x00,0x00,0x00,0x00}, // 83 'S'
|
||||
{0x00,0x7E,0x5A,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}, // 84 'T'
|
||||
{0x00,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x66,0x3C,0x00,0x00,0x00,0x00}, // 85 'U'
|
||||
{0x00,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x66,0x66,0x3C,0x18,0x18,0x00,0x00,0x00,0x00}, // 86 'V'
|
||||
{0x00,0xC3,0xC3,0xC3,0xC3,0xC3,0xDB,0xDB,0xFF,0x66,0x66,0x66,0x00,0x00,0x00,0x00}, // 87 'W'
|
||||
{0x00,0xC3,0xC3,0x66,0x66,0x3C,0x18,0x3C,0x66,0x66,0xC3,0xC3,0x00,0x00,0x00,0x00}, // 88 'X'
|
||||
{0x00,0xC3,0xC3,0xC3,0x66,0x66,0x3C,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}, // 89 'Y'
|
||||
{0x00,0xFF,0xC3,0x86,0x0C,0x18,0x30,0x60,0xC0,0xC1,0xC3,0xFF,0x00,0x00,0x00,0x00}, // 90 'Z'
|
||||
{0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,0x00,0x00,0x00}, // 91 '['
|
||||
{0x00,0x00,0x80,0xC0,0x60,0x30,0x18,0x0C,0x06,0x02,0x00,0x00,0x00,0x00,0x00,0x00}, // 92 '\\'
|
||||
{0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,0x00,0x00,0x00}, // 93 ']'
|
||||
{0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 94 '^'
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00}, // 95 '_'
|
||||
{0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 96 '`'
|
||||
{0x00,0x00,0x00,0x3C,0x06,0x3E,0x66,0xC6,0xC6,0x7E,0x00,0x00,0x00,0x00,0x00,0x00}, // 97 'a'
|
||||
{0x00,0xE0,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0xDC,0x00,0x00,0x00,0x00,0x00,0x00}, // 98 'b'
|
||||
{0x00,0x00,0x00,0x3C,0x66,0xC0,0xC0,0xC0,0x66,0x3C,0x00,0x00,0x00,0x00,0x00,0x00}, // 99 'c'
|
||||
{0x00,0x0E,0x06,0x06,0x3E,0x66,0x66,0x66,0x66,0x3B,0x00,0x00,0x00,0x00,0x00,0x00}, // 100 'd'
|
||||
{0x00,0x00,0x00,0x3C,0x66,0xFF,0xC0,0xC0,0x66,0x3C,0x00,0x00,0x00,0x00,0x00,0x00}, // 101 'e'
|
||||
{0x00,0x1C,0x36,0x30,0x78,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00,0x00,0x00}, // 102 'f'
|
||||
{0x00,0x00,0x00,0x3B,0x66,0x66,0x66,0x3E,0x06,0x66,0x3C,0x00,0x00,0x00,0x00,0x00}, // 103 'g'
|
||||
{0x00,0xE0,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0xE7,0x00,0x00,0x00,0x00,0x00,0x00}, // 104 'h'
|
||||
{0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,0x00,0x00}, // 105 'i'
|
||||
{0x00,0x06,0x06,0x00,0x0E,0x06,0x06,0x06,0x06,0x66,0x3C,0x00,0x00,0x00,0x00,0x00}, // 106 'j'
|
||||
{0x00,0xE0,0x60,0x66,0x6C,0x78,0x78,0x6C,0x66,0xE7,0x00,0x00,0x00,0x00,0x00,0x00}, // 107 'k'
|
||||
{0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,0x00,0x00}, // 108 'l'
|
||||
{0x00,0x00,0x00,0xE6,0xFF,0xDB,0xDB,0xDB,0xDB,0xFF,0x00,0x00,0x00,0x00,0x00,0x00}, // 109 'm'
|
||||
{0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0xE7,0x00,0x00,0x00,0x00,0x00,0x00}, // 110 'n'
|
||||
{0x00,0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x66,0x3C,0x00,0x00,0x00,0x00,0x00,0x00}, // 111 'o'
|
||||
{0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x7C,0x60,0xF0,0x00,0x00,0x00,0x00,0x00,0x00}, // 112 'p'
|
||||
{0x00,0x00,0x00,0x3B,0x66,0x66,0x66,0x3E,0x06,0x0F,0x00,0x00,0x00,0x00,0x00,0x00}, // 113 'q'
|
||||
{0x00,0x00,0x00,0xDC,0x66,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,0x00,0x00}, // 114 'r'
|
||||
{0x00,0x00,0x00,0x3E,0x60,0x3C,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 115 's'
|
||||
{0x00,0x10,0x30,0x7E,0x30,0x30,0x30,0x30,0x36,0x1C,0x00,0x00,0x00,0x00,0x00,0x00}, // 116 't'
|
||||
{0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x3B,0x00,0x00,0x00,0x00,0x00,0x00}, // 117 'u'
|
||||
{0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0x00,0x00,0x00,0x00}, // 118 'v'
|
||||
{0x00,0x00,0x00,0xC3,0xC3,0xDB,0xDB,0xFF,0x66,0x66,0x00,0x00,0x00,0x00,0x00,0x00}, // 119 'w'
|
||||
{0x00,0x00,0x00,0xC3,0x66,0x3C,0x18,0x3C,0x66,0xC3,0x00,0x00,0x00,0x00,0x00,0x00}, // 120 'x'
|
||||
{0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0x38,0x00,0x00,0x00,0x00,0x00}, // 121 'y'
|
||||
{0x00,0x00,0x00,0x7E,0x4C,0x18,0x30,0x62,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 122 'z'
|
||||
{0x00,0x0E,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00,0x00,0x00}, // 123 '{'
|
||||
{0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00}, // 124 '|'
|
||||
{0x00,0x70,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00,0x00,0x00}, // 125 '}'
|
||||
{0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 126 '~'
|
||||
{0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 127
|
||||
};
|
||||
|
||||
int fb_init(void) {
|
||||
fb_info_data_t info;
|
||||
register uint64_t rax __asm__("rax") = SYS_FB_INFO;
|
||||
register uint64_t rdi __asm__("rdi") = (uint64_t)&info;
|
||||
__asm__ volatile("syscall" : "+r"(rax) : "r"(rdi) : "rcx", "r11", "memory");
|
||||
|
||||
if (rax != 0 || info.fb_addr == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_fb.buffer = (uint32_t *)info.fb_addr;
|
||||
g_fb.width = (uint32_t)info.width;
|
||||
g_fb.height = (uint32_t)info.height;
|
||||
g_fb.pitch = (uint32_t)(info.pitch / 4); // in 32-bit dwords
|
||||
g_fb.bpp = info.bpp;
|
||||
g_fb.is_initialized = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fb_draw_pixel(int x, int y, uint32_t color) {
|
||||
if (!g_fb.is_initialized) return;
|
||||
if (x < 0 || (uint32_t)x >= g_fb.width || y < 0 || (uint32_t)y >= g_fb.height) return;
|
||||
g_fb.buffer[y * g_fb.pitch + x] = color;
|
||||
}
|
||||
|
||||
void fb_clear(uint32_t color) {
|
||||
if (!g_fb.is_initialized) return;
|
||||
for (uint32_t y = 0; y < g_fb.height; y++) {
|
||||
for (uint32_t x = 0; x < g_fb.width; x++) {
|
||||
g_fb.buffer[y * g_fb.pitch + x] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fb_fill_rect(int x, int y, int w, int h, uint32_t color) {
|
||||
if (!g_fb.is_initialized) return;
|
||||
for (int dy = 0; dy < h; dy++) {
|
||||
int py = y + dy;
|
||||
if (py < 0 || (uint32_t)py >= g_fb.height) continue;
|
||||
for (int dx = 0; dx < w; dx++) {
|
||||
int px = x + dx;
|
||||
if (px < 0 || (uint32_t)px >= g_fb.width) continue;
|
||||
g_fb.buffer[py * g_fb.pitch + px] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fb_draw_rect(int x, int y, int w, int h, uint32_t color) {
|
||||
fb_fill_rect(x, y, w, 1, color);
|
||||
fb_fill_rect(x, y + h - 1, w, 1, color);
|
||||
fb_fill_rect(x, y, 1, h, color);
|
||||
fb_fill_rect(x + w - 1, y, 1, h, color);
|
||||
}
|
||||
|
||||
void fb_draw_char(int x, int y, char c, uint32_t fg, uint32_t bg) {
|
||||
if (!g_fb.is_initialized) return;
|
||||
if ((unsigned char)c < 32 || (unsigned char)c > 127) c = ' ';
|
||||
const uint8_t *glyph = font8x16_data[(unsigned char)c - 32];
|
||||
|
||||
for (int row = 0; row < 16; row++) {
|
||||
int py = y + row;
|
||||
if (py < 0 || (uint32_t)py >= g_fb.height) continue;
|
||||
uint8_t bits = glyph[row];
|
||||
for (int col = 0; col < 8; col++) {
|
||||
int px = x + col;
|
||||
if (px < 0 || (uint32_t)px >= g_fb.width) continue;
|
||||
if (bits & (0x80 >> col)) {
|
||||
g_fb.buffer[py * g_fb.pitch + px] = fg;
|
||||
} else if (bg != 0xFFFFFFFF) {
|
||||
g_fb.buffer[py * g_fb.pitch + px] = bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fb_draw_string(int x, int y, const char *str, uint32_t fg, uint32_t bg) {
|
||||
int cur_x = x;
|
||||
while (*str) {
|
||||
if (*str == '\n') {
|
||||
y += 18;
|
||||
cur_x = x;
|
||||
} else {
|
||||
fb_draw_char(cur_x, y, *str, fg, bg);
|
||||
cur_x += 9;
|
||||
}
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
void fb_draw_window(int x, int y, int w, int h, const char *title) {
|
||||
// Window shadow
|
||||
fb_fill_rect(x + 4, y + 4, w, h, FB_BLACK);
|
||||
// Window background
|
||||
fb_fill_rect(x, y, w, h, FB_NAVY);
|
||||
// Window border
|
||||
fb_draw_rect(x, y, w, h, FB_DARK_GRAY);
|
||||
// Title bar
|
||||
fb_fill_rect(x, y, w, 24, FB_BLUE);
|
||||
fb_draw_string(x + 10, y + 4, title, FB_WHITE, 0xFFFFFFFF);
|
||||
// Close button (X)
|
||||
fb_fill_rect(x + w - 20, y + 4, 16, 16, FB_RED);
|
||||
fb_draw_char(x + w - 16, y + 4, 'X', FB_WHITE, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
void fb_demo_desktop(void) {
|
||||
if (fb_init() != 0) return;
|
||||
|
||||
// 1. Draw modern sleek desktop wallpaper
|
||||
fb_clear(FB_NAVY);
|
||||
|
||||
// 2. Draw Top Panel / Menu bar
|
||||
fb_fill_rect(0, 0, g_fb.width, 28, FB_DARK_GRAY);
|
||||
fb_draw_string(12, 6, "opencoreC OS (x86_64 SMP)", FB_WHITE, 0xFFFFFFFF);
|
||||
fb_draw_string(g_fb.width - 180, 6, "12:00 UTC | Ring 3", FB_CYAN, 0xFFFFFFFF);
|
||||
|
||||
// 3. Draw Main System Status Window
|
||||
int win_w = 420;
|
||||
int win_h = 240;
|
||||
int win_x = (g_fb.width - win_w) / 2;
|
||||
int win_y = (g_fb.height - win_h) / 2;
|
||||
|
||||
fb_draw_window(win_x, win_y, win_w, win_h, "opencoreC System Dashboard");
|
||||
|
||||
// Content inside window
|
||||
fb_draw_string(win_x + 16, win_y + 36, "Architecture: x86_64 Long Mode (SMP 4 Cores)", FB_WHITE, 0xFFFFFFFF);
|
||||
fb_draw_string(win_x + 16, win_y + 56, "Kernel: Rust Microkernel #![no_std]", FB_WHITE, 0xFFFFFFFF);
|
||||
fb_draw_string(win_x + 16, win_y + 76, "User Space: Isolated Ring 3 C++20 Tasks", FB_WHITE, 0xFFFFFFFF);
|
||||
fb_draw_string(win_x + 16, win_y + 96, "Scheduler: Preemptive 100Hz Round-Robin", FB_WHITE, 0xFFFFFFFF);
|
||||
fb_draw_string(win_x + 16, win_y + 116,"Network: Realtek RTL8139 (PCI) Active", FB_GREEN, 0xFFFFFFFF);
|
||||
fb_draw_string(win_x + 16, win_y + 136,"IPC Engine: Zero-Copy Synchronous Rendezvous", FB_CYAN, 0xFFFFFFFF);
|
||||
|
||||
// Progress bar widget: Memory consumption
|
||||
fb_draw_string(win_x + 16, win_y + 168, "RAM Usage: 24 MiB / 512 MiB [OK]", FB_LIGHT_GRAY, 0xFFFFFFFF);
|
||||
fb_fill_rect(win_x + 16, win_y + 188, 380, 12, FB_DARK_GRAY);
|
||||
fb_fill_rect(win_x + 16, win_y + 188, 120, 12, FB_GREEN);
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
#include "../include/rtl8139.h"
|
||||
#include "../include/pci.h"
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
|
||||
rtl8139_dev_t g_rtl8139 = {0};
|
||||
|
||||
/* Port I/O helpers */
|
||||
static inline void outb(uint16_t port, uint8_t val) {
|
||||
__asm__ volatile("outb %0, %1" : : "a"(val), "Nd"(port));
|
||||
}
|
||||
static inline void outw(uint16_t port, uint16_t val) {
|
||||
__asm__ volatile("outw %0, %1" : : "a"(val), "Nd"(port));
|
||||
}
|
||||
static inline void outl(uint16_t port, uint32_t val) {
|
||||
__asm__ volatile("outl %0, %1" : : "a"(val), "Nd"(port));
|
||||
}
|
||||
static inline uint8_t inb(uint16_t port) {
|
||||
uint8_t ret;
|
||||
__asm__ volatile("inb %1, %0" : "=a"(ret) : "Nd"(port));
|
||||
return ret;
|
||||
}
|
||||
static inline uint16_t inw(uint16_t port) {
|
||||
uint16_t ret;
|
||||
__asm__ volatile("inw %1, %0" : "=a"(ret) : "Nd"(port));
|
||||
return ret;
|
||||
}
|
||||
static inline uint32_t inl(uint16_t port) {
|
||||
uint32_t ret;
|
||||
__asm__ volatile("inl %1, %0" : "=a"(ret) : "Nd"(port));
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define RTL_CONFIG1 0x52
|
||||
#define RTL_COMMAND 0x37
|
||||
#define RTL_RBSTART 0x30
|
||||
#define RTL_IMR 0x3C
|
||||
#define RTL_ISR 0x3E
|
||||
#define RTL_RCR 0x44
|
||||
#define RTL_TCR 0x40
|
||||
#define RTL_TSD0 0x10
|
||||
#define RTL_TSAD0 0x20
|
||||
|
||||
static void pci_check_rtl8139(const pci_device_t *dev) {
|
||||
if (dev->vendor_id == 0x10EC && dev->device_id == 0x8139) {
|
||||
// Read BAR0 (I/O Port Base)
|
||||
uint32_t bar0 = pci_read_config_dword(dev->bus, dev->slot, dev->func, 0x10);
|
||||
g_rtl8139.io_base = (uint16_t)(bar0 & ~0x3);
|
||||
|
||||
// Enable Bus Mastering and I/O Space in PCI Command register
|
||||
uint32_t cmd = pci_read_config_dword(dev->bus, dev->slot, dev->func, 0x04);
|
||||
cmd |= (1 << 0) | (1 << 2); // I/O Space + Bus Master
|
||||
pci_write_config_dword(dev->bus, dev->slot, dev->func, 0x04, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
int rtl8139_init(void) {
|
||||
if (g_rtl8139.is_initialized) return 0;
|
||||
|
||||
// 1. Find device on PCI bus
|
||||
pci_scan_bus(pci_check_rtl8139);
|
||||
|
||||
if (g_rtl8139.io_base == 0) {
|
||||
// Fallback default port commonly assigned in QEMU
|
||||
g_rtl8139.io_base = 0xC000;
|
||||
}
|
||||
|
||||
uint16_t io = g_rtl8139.io_base;
|
||||
|
||||
// 2. Power on the card (Config1 = 0x00)
|
||||
outb(io + RTL_CONFIG1, 0x00);
|
||||
|
||||
// 3. Software Reset
|
||||
outb(io + RTL_COMMAND, 0x10);
|
||||
while ((inb(io + RTL_COMMAND) & 0x10) != 0) {
|
||||
// Wait for reset to complete
|
||||
}
|
||||
|
||||
// 4. Read MAC Address
|
||||
for (int i = 0; i < 6; i++) {
|
||||
g_rtl8139.mac[i] = inb(io + i);
|
||||
}
|
||||
// If MAC is all 0 or all FF, set standard QEMU virtual NIC MAC
|
||||
if ((g_rtl8139.mac[0] == 0 && g_rtl8139.mac[1] == 0) || g_rtl8139.mac[0] == 0xFF) {
|
||||
g_rtl8139.mac[0] = 0x52;
|
||||
g_rtl8139.mac[1] = 0x54;
|
||||
g_rtl8139.mac[2] = 0x00;
|
||||
g_rtl8139.mac[3] = 0x12;
|
||||
g_rtl8139.mac[4] = 0x34;
|
||||
g_rtl8139.mac[5] = 0x56;
|
||||
}
|
||||
|
||||
// 5. Initialize Receive Buffer
|
||||
outl(io + RTL_RBSTART, (uint32_t)(uintptr_t)g_rtl8139.rx_buffer);
|
||||
|
||||
// 6. Set IMR (Interrupt Mask) & RCR (Accept Broadcast, Multicast, Physical Match, All packets)
|
||||
outw(io + RTL_IMR, 0x0005); // ROK + TOK
|
||||
outl(io + RTL_RCR, 0x0F | (1 << 7)); // AB+AM+APM+AAP + Wrap
|
||||
|
||||
// 7. Enable Transmitter and Receiver
|
||||
outb(io + RTL_COMMAND, 0x0C);
|
||||
|
||||
g_rtl8139.tx_cur = 0;
|
||||
g_rtl8139.is_initialized = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtl8139_send_packet(const void *data, uint16_t len) {
|
||||
if (!g_rtl8139.is_initialized) {
|
||||
if (rtl8139_init() != 0) return -1;
|
||||
}
|
||||
|
||||
if (len > 1514) len = 1514;
|
||||
|
||||
uint16_t io = g_rtl8139.io_base;
|
||||
uint8_t tx_id = g_rtl8139.tx_cur % 4;
|
||||
|
||||
// Copy payload into TX buffer
|
||||
memcpy(g_rtl8139.tx_buffers[tx_id], data, len);
|
||||
|
||||
// Pad to minimum Ethernet frame size (60 bytes excluding 4-byte CRC)
|
||||
if (len < 60) {
|
||||
memset(g_rtl8139.tx_buffers[tx_id] + len, 0, 60 - len);
|
||||
len = 60;
|
||||
}
|
||||
|
||||
// Set TX buffer physical address
|
||||
outl(io + RTL_TSAD0 + (tx_id * 4), (uint32_t)(uintptr_t)g_rtl8139.tx_buffers[tx_id]);
|
||||
|
||||
// Set length and start transmission (clearing OWN bit)
|
||||
outl(io + RTL_TSD0 + (tx_id * 4), (uint32_t)len & 0x1FFF);
|
||||
|
||||
g_rtl8139.tx_cur = (g_rtl8139.tx_cur + 1) % 4;
|
||||
g_rtl8139.tx_packets++;
|
||||
g_rtl8139.tx_bytes += len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtl8139_poll_packet(void *out_buf, uint16_t max_len) {
|
||||
if (!g_rtl8139.is_initialized) return 0;
|
||||
|
||||
uint16_t io = g_rtl8139.io_base;
|
||||
uint16_t isr = inw(io + RTL_ISR);
|
||||
|
||||
// Check Receive OK (bit 0)
|
||||
if (isr & 0x01) {
|
||||
outw(io + RTL_ISR, 0x01); // Acknowledge RX interrupt
|
||||
|
||||
// Simple RX frame parsing from ring buffer
|
||||
uint16_t *header = (uint16_t *)g_rtl8139.rx_buffer;
|
||||
uint16_t status = header[0];
|
||||
uint16_t length = header[1];
|
||||
|
||||
if (status & 0x01 && length > 4 && length < 1600) {
|
||||
uint16_t payload_len = length - 4; // Exclude 4-byte CRC
|
||||
if (payload_len > max_len) payload_len = max_len;
|
||||
|
||||
memcpy(out_buf, g_rtl8139.rx_buffer + 4, payload_len);
|
||||
g_rtl8139.rx_packets++;
|
||||
g_rtl8139.rx_bytes += payload_len;
|
||||
return (int)payload_len;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user