This commit is contained in:
2026-05-06 19:51:30 +07:00
commit 3958b0edcf
2704 changed files with 410390 additions and 0 deletions
+7
View File
@@ -0,0 +1,7 @@
FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.c)
idf_component_register(
SRCS ${app_sources}
INCLUDE_DIRS "." "${CMAKE_SOURCE_DIR}"
REQUIRES esp_littlefs espressif__tinyusb
)
+38
View File
@@ -0,0 +1,38 @@
#include "answer_code.h"
#include <stdlib.h>
const char* get_error(uint32_t code) {
switch (code) {
case OS_OK: return "Successfully";
case OS_ERR_NO_MEMORY: return "Error: Out of memory";
case OS_ERR_NOT_INIT: return "Error: The object or table is not initialized";
case OS_ERR_NOT_FOUND: return "Error: Not found";
case OS_ERR_INVALID_ARG: return "Error: Invalid argument";
case OS_ERR_FULL: return "Error: Object is full";
case OS_ERR_MAGIC: return "Error: Unknown file type";
case OS_WRN_ALREADY_INIT: return "Warning: Attempting to reinitialize an object";
case OS_WRN_NOT_NEED_INIT: return "Warning: Attempt to initialize an uninitializable object";
case VRAM_ERR_RANGE: return "Error: Attempt to write/read outside the video memory block";
case VRAM_ERR_HANDLE: return "Error: Invalid or non-existent Handle";
case VRAM_WRN_DEFRAG_REQ: return "Warning: Defragmentation required to allocate memory";
case VRAM_ERR_WR_or_RD: return "Error: Error reading record";
case VRAM_ERR_POOL_MEMORY: return "Error: Memory allocation error";
case PROC_ERR_STACK: return "Error: There was not enough memory for the task stack.";
case PROC_ERR_PRIORITY: return "Error: Invalid FreeRTOS priority";
case PROC_ERR_ALIVE: return "Error: Attempting to operate on an already dead process";
case DISP_ERR_UNSUPPORTED: return "Error: Screen mode or pixel format not supported";
case APIOS_ERR_DUPLICATE_NAME: return "Error: Attempting to register a driver with a name that is already taken.";
case APIOS_ERR_EMPTY_API: return "Error: The driver has an empty function table.";
case APIOS_ERR_DRIVER_CRASH: return "Error: Error calling function: The function returned a critical failure that requires unloading.";
case APIOS_WRN_PARTIAL_API: return "Warning: The driver is loaded, but some of its functions are not implemented.";
case APIOS_ERR_NOT_INITIALIZED: return "Error: Attempting to call an API when the apios table is not initialized";
case APIOS_ERR_DRIVER_NOT_FOUND: return "Error: Attempt to call API of non-existent driver";
default: return "Unknown system error";
}
}
+43
View File
@@ -0,0 +1,43 @@
#ifndef ANSWER_CODE_H
#define ANSWER_CODE_H
#include <stdlib.h>
#define OS_OK 0x00000000
// Общие системные ошибки (Generic)
#define OS_ERR_NO_MEMORY 0x00000001 // Ошибка malloc (не хватило ОЗУ)
#define OS_ERR_NOT_INIT 0x00000002 // Объект или таблица не инициализированы (NULL)
#define OS_ERR_NOT_FOUND 0x00000003 // Драйвер, функция или файл не найдены
#define OS_ERR_INVALID_ARG 0x00000004 // Переданы неверные аргументы (argc/argv)
#define OS_ERR_FULL 0x00000005 // Нет места в таблице или массиве
#define OS_ERR_MAGIC 0x00000006 // Ошибка проверки магического числа (структура битая)
#define OS_WRN_ALREADY_INIT 0x00000007 // Объект уже был инициализирован ранее
#define OS_WRN_NOT_NEED_INIT 0x00000008 // Попытка инициалезировать когда она этого не требует
// Специфические ошибки VRAM (0x10+)
#define VRAM_ERR_RANGE 0x00000010 // Попытка записи/чтения за пределами блока
#define VRAM_ERR_HANDLE 0x00000011 // Неверный или несуществующий Handle
#define VRAM_WRN_DEFRAG_REQ 0x00000012 // Требуется дефрагментация для выделения памяти
#define VRAM_ERR_WR_or_RD 0x00000013 // Ошибка чтения записи
#define VRAM_ERR_POOL_MEMORY 0x00000014 // Ошибка выделения памяти
// Ошибки процессов и планировщика (0x20+)
#define PROC_ERR_STACK 0x00000020 // Не хватило памяти под стек задачи
#define PROC_ERR_PRIORITY 0x00000021 // Недопустимый приоритет FreeRTOS
#define PROC_ERR_ALIVE 0x00000022 // Попытка действия над уже мертвым процессом
// Ошибки графической подсистемы (0x30+)
#define DISP_ERR_UNSUPPORTED 0x00000030 // Режим экрана или формат пикселя не поддерживается
// Ошибки APIOS (0x40+)
#define APIOS_ERR_DUPLICATE_NAME 0x00000040 // Попытка зарегистрировать драйвер с именем, которое уже занято
#define APIOS_ERR_EMPTY_API 0x00000041 // У драйвера пустая таблица функций (fn_count == 0)
#define APIOS_ERR_DRIVER_CRASH 0x00000042 // Ошибка при вызове функции: функция вернула критический сбой, требующий выгрузки
#define APIOS_WRN_PARTIAL_API 0x00000043 // Драйвер загружен, но некоторые его функции не реолизованны
#define APIOS_ERR_NOT_INITIALIZED 0x00000044 // Попытка вызова API при неинициализированной таблице APIOS
#define APIOS_ERR_DRIVER_NOT_FOUND 0x00000045 // Попытка вызвать API несущевствууещего драйвера
const char* get_error(uint32_t code);
#endif
+111
View File
@@ -0,0 +1,111 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "boot/apios.h"
#include "boot/typedef.h"
#include "boot/answer_code.h"
#include "boot/entry.h"
apios_main_table_t *apios_table = NULL;
int apios_dump() {
if (apios_table == NULL) {
printf("\033[31mError: APIOS table is NULL (not initialized)\033[0m\n");
return APIOS_ERR_NOT_INITIALIZED;
}
printf("\n--- \033[34mAPIOS System Dump\033[0m ---\n");
printf("Main Table Address: %p\n", (void*)apios_table);
printf("Magic: 0x%04X\n", apios_table->magic);
printf("Total Drivers: %d\n", apios_table->drivers_count);
printf("---------------------------\n");
for (int i = 0; i < apios_table->drivers_count; i++) {
driver_header_t *header = apios_table->drivers[i];
if (header == NULL) {
printf(" [%d] Header is NULL!\n", i);
continue;
}
printf(" [%d] Driver Name: \033[32m%s\033[0m\n", i, header->driver_name);
printf(" Header Addr: %p\n", (void*)header);
driver_api_t *api = header->api;
if (api == NULL) {
printf(" \033[31m! API Table is NULL\033[0m\n");
continue;
}
printf(" API Addr: %p (v%d)\n", (void*)api, api->driver_version);
printf(" Functions Count: %d\n", api->fn_count);
if (api->functions != NULL) {
printf(" Functions List:\n");
for (int f = 0; f < api->fn_count; f++) {
printf(" - [%d] %-15s -> Addr: %p\n",
f,
api->functions[f].name,
(void*)api->functions[f].driver_fn);
}
} else {
printf(" \033[31m! No functions array found\033[0m\n");
}
printf("---------------------------\n");
}
return OS_OK;
}
int hendle_func(int_fn_t *func, char driver_name[16], char func_name[16]) {
if (apios_table == NULL) return APIOS_ERR_NOT_INITIALIZED;
bool drv_found = false;
for (int i = 0; i < apios_table->drivers_count; i++) {
if (strcmp(apios_table->drivers[i]->driver_name, driver_name) == 0) {
drv_found = true;
driver_api_t *api = apios_table->drivers[i]->api;
bool fn_found = false;
for (int f = 0; f < api->fn_count; f++) {
if (strcmp(api->functions[f].name, func_name) == 0) {
*func = api->functions[f].driver_fn;
fn_found = true;
return OS_OK;
}
}
if (!fn_found) return APIOS_ERR_DRIVER_CRASH;
}
}
if (!drv_found) return APIOS_ERR_DRIVER_NOT_FOUND;
return OS_ERR_NOT_FOUND;
}
int init_apios(apios_main_table_t *apios_table_) {
if (apios_table == NULL) {
if (load_log) printf("APIOS initings...\n");
apios_table = (apios_main_table_t *)malloc(sizeof(apios_main_table_t));
if (apios_table == NULL){
if (load_log) printf("Failed to initialize table\n");
return OS_ERR_NO_MEMORY;
}
static driver_fn_t fs_function[] = {
{
.name = "dump",
.driver_fn = apios_dump,
}
};
driver_api_t *fs_api = (driver_api_t *)malloc(sizeof(driver_api_t));
fs_api->driver_version = 1;
fs_api->fn_count = (int)(sizeof(fs_function)/sizeof(fs_function[0]));
fs_api->functions = fs_function;
driver_header_t *driver_header = (driver_header_t *)malloc(sizeof(driver_header_t));
strcpy(driver_header->driver_name, "apios");
driver_header->api = fs_api;
apios_table->magic = 0xfa0c;
apios_table->drivers = (driver_header_t **)malloc(sizeof(driver_header_t *) * 100);
apios_table->drivers_count = 0;
apios_table->drivers[apios_table->drivers_count] = driver_header;
apios_table->drivers_count++;
}
else {
if (load_log) printf("The table does not require initialization\n");
return OS_WRN_NOT_NEED_INIT;
}
return OS_OK;
}
+10
View File
@@ -0,0 +1,10 @@
#ifndef APIOS_H
#define APIOS_H
#include "boot/typedef.h"
int init_apios(apios_main_table_t *apios_table_);
extern apios_main_table_t *apios_table;
#endif
+36
View File
@@ -0,0 +1,36 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "FreeRTOS.h"
#include "boot/apios.h"
#include "drivers/fs/fs.h"
#include "drivers/monitor/driver.h"
#include "lib/video/vram.h"
#include "boot/answer_code.h"
#include "nvs_flash.h"
#include "nvs.h"
void log_result(int res, char *service_name){
if (res == OS_OK) {
printf("[ \033[0;32mOK\033[0m ] APIOS initialization\n");
} else {
char *err_text = "Error";
const char *msg = get_error(res);
if (strncmp(msg, err_text, 5) == 0) {
printf("[ \033[0;31mEROR\033[0m ] %s initialization: %s (%d)\n", service_name, msg, res);
} else {
printf("[ \033[0;33mWARN\033[0m ] %s initialization: %s (%d)\n", service_name, msg, res);
}
}
}
void OS_entry(void *pvParameters)
{
printf("Initializing subsystems\n");
log_result(init_apios(apios_table), "APIOS");
}
+1
View File
@@ -0,0 +1 @@
void OS_entry(void *pvParameters);
+50
View File
@@ -0,0 +1,50 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "FreeRTOS.h"
#include "boot/recovery/boot.h"
#include "boot/boot.h"
#include "boot/entry.h"
bool load_log = true;
int main_entry()
{
printf("\033[2J\033[H");
printf("OS started\n");
load_log = false;
xTaskCreatePinnedToCore(
OS_entry,
"Os main task",
4096,
NULL,
10,
NULL,
0
);
return 0;
}
int recovery_entry()
{
printf("\033[2J\033[H");
printf("Recovery started\n");
load_log = true;
xTaskCreatePinnedToCore(
recovery_shell,
"Recovery Shell",
4096,
NULL,
10,
NULL,
0
);
return 0;
}
+11
View File
@@ -0,0 +1,11 @@
#ifndef ENTRY_H
#define ENTRY_H
#include <stdbool.h>
extern bool load_log;
int main_entry();
int recovery_entry();
#endif
+175
View File
@@ -0,0 +1,175 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "FreeRTOS.h"
#include "boot/recovery/boot.h"
#include "boot/recovery/typedef.h"
#include "boot/recovery/table.h"
#include "boot/apios.h"
void recovery_shell(void *pvParameters) {
vTaskDelay(pdMS_TO_TICKS(10));
char buffer[64];
char prm[8][16];
int current_pos = 0;
printf("\033[2J\033[H");
printf("\033[32mrecovery:\033[33m> \033[0m");
fflush(stdout);
memset(buffer, 0, 64);
while (1) {
int in = getchar();
if (in == EOF) {
vTaskDelay(pdMS_TO_TICKS(10));
continue;
}
if (in == 0x08 || in == 0x7F) {
if (current_pos > 0) {
current_pos--;
buffer[current_pos] = '\0';
printf("\b \b");
fflush(stdout);
}
continue;
}
if (in == '\r' || in == '\n') {
printf("\n");
if (current_pos > 0) {
memset(prm, 0, sizeof(prm));
int count = 0;
char *token = strtok(buffer, " ");
while (token != NULL && count < 8) {
strncpy(prm[count], token, 15);
prm[count][15] = '\0';
count++;
token = strtok(NULL, " ");
}
if (count > 0) {
if (strcmp(prm[0], "load") == 0) {
char source[16] = "none";
char name_load[16] = "none";
for (int q = 1; q < count; q++) {
char *key = strtok(prm[q], "=");
char *val = strtok(NULL, "=");
if (key && val) {
if (strcmp(key, "source") == 0) strncpy(source, val, 15);
else if (strcmp(key, "name") == 0) strncpy(name_load, val, 15);
}
}
printf("Action: Loading module [%s] from [%s]\n", name_load, source);
bool found = false;
int table_size = sizeof(moduls_table) / sizeof(moduls_table[0]);
for (int i = 0; i < table_size; i++) {
if (strcmp(moduls_table[i].module.name, name_load) == 0) {
printf("\033[32mFound!\033[0m Starting driver...\n");
int res = moduls_table[i].module.init_fn(apios_table);
printf("Driver exited with code: %d\n", res);
found = true;
break;
}
}
if (!found && strcmp(name_load, "none") != 0) {
printf("\033[31mError:\033[0m Module '%s' not found\n", name_load);
}
}
else if (strcmp(prm[0], "init") == 0) {
char name_load[16] = "none";
for (int q = 1; q < count; q++) {
char *key = strtok(prm[q], "=");
char *val = strtok(NULL, "=");
if (key && val) {
if (strcmp(key, "name") == 0) strncpy(name_load, val, 15);
}
}
int table_size = sizeof(service_init) / sizeof(service_init[0]);
bool found = false;
for (int i = 0; i < table_size; i++) {
if (strcmp(service_init[i].name, name_load) == 0) {
printf("\033[32mFound!\033[0m Starting service ...\n");
int res = service_init[i].init_fn(apios_table);
printf("Service exited with code: %d\n", res);
found = true;
break;
}
}
if (!found) {
printf("\033[31mError:\033[0m Service '%s' not found \n", name_load);
}
}
else if (strcmp(prm[0], "apios") == 0) {
char drv_name[16] = "none";
char fn_name[16] = "none";
for (int q = 1; q < count; q++) {
char *key = strtok(prm[q], "=");
char *val = strtok(NULL, "=");
if (key && val) {
if (strcmp(key, "driver") == 0) strncpy(drv_name, val, 15);
else if (strcmp(key, "func") == 0) strncpy(fn_name, val, 15);
}
}
if (apios_table == NULL) {
printf("\033[31mError:\033[0m APIOS table not initialized\n");
} else {
bool drv_found = false;
for (int i = 0; i < apios_table->drivers_count; i++) {
if (strcmp(apios_table->drivers[i]->driver_name, drv_name) == 0) {
drv_found = true;
driver_api_t *api = apios_table->drivers[i]->api;
bool fn_found = false;
for (int f = 0; f < api->fn_count; f++) {
if (strcmp(api->functions[f].name, fn_name) == 0) {
printf("\033[32mExecuting:\033[0m %s->%s()...\n", drv_name, fn_name);
int res = api->functions[f].driver_fn(NULL);
printf("\n\033[32mDone.\033[0m Return code: %d\n", res);
fn_found = true;
break;
}
}
if (!fn_found) printf("\033[31mError:\033[0m Function '%s' not found in driver '%s'\n", fn_name, drv_name);
break;
}
}
if (!drv_found) printf("\033[31mError:\033[0m Driver '%s' not found\n", drv_name);
}
}
else if (strcmp(prm[0], "help") == 0) {
printf("Commands: load source=X name=Y\n");
printf("Commands: init name=Y, help\n");
printf("Commands: apios driver=Y, func\n");
}
else {
printf("Unknown command: %s\n", prm[0]);
}
}
}
current_pos = 0;
memset(buffer, 0, 64);
printf("\033[32mrecovery:\033[33m> \033[0m");
fflush(stdout);
}
else {
if (current_pos < 63) {
buffer[current_pos] = (char)in;
current_pos++;
buffer[current_pos] = '\0';
putchar(in);
fflush(stdout);
}
}
}
}
+3
View File
@@ -0,0 +1,3 @@
void recovery_shell(void *pvParameters);
+27
View File
@@ -0,0 +1,27 @@
#ifndef TABLE_RECOVERY
#define TABLE_RECOVERY
#include "boot/recovery/typedef.h"
#include "drivers/fs/fs.h"
#include "boot/apios.h"
load_source_t moduls_table[] = {
{
.name = "drivers",
.module = {
.name = "fs",
.init_fn = init_fs,
}
}
};
module_t service_init[] = {
{
.name = "apios",
.init_fn = init_apios
}
};
#endif
+21
View File
@@ -0,0 +1,21 @@
#ifndef TYPEDEF_RECOVERY_H
#define TYPEDEF_RECOVERY_H
struct apios_main_table_t;
typedef struct apios_main_table_t apios_main_table_t;
typedef int (*init_fn_t)(apios_main_table_t *apios_table);
typedef struct
{
char name[16];
init_fn_t init_fn;
} module_t;
typedef struct
{
char name[16];
module_t module;
} load_source_t;
#endif
+42
View File
@@ -0,0 +1,42 @@
#pragma once
#ifndef TYPEDEF
#define TYPEDEF
struct apios_main_table_t;
typedef struct apios_main_table_t apios_main_table_t;
typedef int (*entry_fn_t)(void *args);
typedef int (*int_fn_t)();
typedef struct {
char name[128];
char type[128];
char path[256];
entry_fn_t entry_function;
} boot_entry_t;
typedef struct {
char name[16];
entry_fn_t driver_fn;
} driver_fn_t;
typedef struct {
int driver_version;
int fn_count;
driver_fn_t *functions;
} driver_api_t;
typedef struct {
char driver_name[16];
driver_api_t *api;
} driver_header_t;
struct apios_main_table_t {
int magic;
int drivers_count;
driver_header_t **drivers;
};
#endif
+28
View File
@@ -0,0 +1,28 @@
#include "boot/entry.h"
#include "boot/typedef.h"
#include "drivers/eft/eft.h"
boot_entry_t entry_data[] = {
{
.name = "ESP32S3-Linux",
.type = "operating system",
.path = "/boot/boot.bin",
.entry_function = main_entry
},
{
.name = "ESP32S3-Recovery",
.type = "recovery OS",
.path = "/boot/recovery.bin",
.entry_function = recovery_entry
},
{
.name = "EFT Server",
.type = "server shell",
.path = "/drivers/eft/eft_server.bin",
.entry_function = eft_server_shell
}
};
const int autostart_index = 0;
const int entry_table_count = 3;
+23
View File
@@ -0,0 +1,23 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "esp_system.h"
#include "esp_heap_caps.h"
int eft_server_shell() {
printf("\033[2J\033[H");
printf("EFT server shell running\n");
size_t internal = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
size_t total = esp_get_free_heap_size();
size_t max_block = heap_caps_get_largest_free_block(MALLOC_CAP_8BIT);
printf("\n--- Memory Check ---\n");
printf(" Internal RAM free: %u KB\n", internal / 1024);
printf(" Total Heap free: %u KB\n", total / 1024);
printf(" Max Alloc Block: %u KB\n", max_block / 1024);
printf("---------------------------\n");
return 0;
}
+3
View File
@@ -0,0 +1,3 @@
#pragma once
int eft_server_shell();
+86
View File
@@ -0,0 +1,86 @@
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "drivers/fs/fs.h"
#include "boot/typedef.h"
#include "boot/answer_code.h"
#include "boot/entry.h"
int mount() {
printf("fs: mount");
return 0;
}
int unmount() {
printf("fs: unmount");
return 0;
}
int format() {
printf("fs: format");
return 0;
}
int get_info() {
printf("fs: get_info");
return 0;
}
int is_present() {
printf("fs: is_present");
return 0;
}
int get_vfs_config() {
printf("fs: get_vfs_config");
return 0;
}
int init_fs(apios_main_table_t *apios_table) {
(void)apios_table;
if (apios_table == NULL) {
if (load_log) printf("The driver table is not initialized\n");
return APIOS_ERR_NOT_INITIALIZED;
}
static driver_fn_t fs_function[] = {
{
.name = "mount",
.driver_fn = mount,
},
{
.name = "unmount",
.driver_fn = unmount,
},
{
.name = "format",
.driver_fn = format,
},
{
.name = "get_info",
.driver_fn = get_info,
},
{
.name = "is_present",
.driver_fn = is_present,
},
{
.name = "get_vfs_config",
.driver_fn = get_vfs_config,
}
};
driver_api_t *fs_api = (driver_api_t *)malloc(sizeof(driver_api_t));
fs_api->driver_version = 1;
fs_api->fn_count = (int)(sizeof(fs_function)/sizeof(fs_function[0]));
fs_api->functions = fs_function;
driver_header_t *driver_header = (driver_header_t *)malloc(sizeof(driver_header_t));
strcpy(driver_header->driver_name, "FileSystem");
driver_header->api = fs_api;
apios_table->drivers[apios_table->drivers_count] = driver_header;
apios_table->drivers_count++;
return OS_OK;
}
+10
View File
@@ -0,0 +1,10 @@
#include "boot/typedef.h"
int init_fs(apios_main_table_t *apios_table);
int mount();
int unmount();
int format();
int get_info();
int is_present();
int get_vfs_config();
+3
View File
@@ -0,0 +1,3 @@
dependencies:
espressif/esp_tinyusb: "^1.4.2"
espressif/esp-dsp: "^1.4.11"
View File
View File
View File
View File
View File
View File
View File
+214
View File
@@ -0,0 +1,214 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "nvs_flash.h"
#include "nvs.h"
#include "lib/video/vram.h"
#include "boot/answer_code.h"
#include "boot/entry.h"
vram_manager_t *vram_sys = NULL;
int init_vram(apios_main_table_t *apios_table)
{
(void)apios_table;
if (vram_sys != NULL) return OS_WRN_NOT_NEED_INIT;
int vram_kb[3] = {128, 512, 1024};
int8_t val = 1;
nvs_handle_t h;
if (nvs_open("config", NVS_READONLY, &h) == ESP_OK) {
if (nvs_get_i8(h, "vram", &val) != ESP_OK || val < 0 || val > 2) {
val = 1;
}
nvs_close(h);
} else {
if (load_log) printf("VRAM: No saved config, using default 512kb\n");
val = 1;
}
vram_sys = (vram_manager_t*)malloc(sizeof(vram_manager_t));
if (!vram_sys) return OS_ERR_NO_MEMORY;
memset(vram_sys, 0, sizeof(vram_manager_t));
vram_sys->capacity = (uint32_t)(vram_kb[val] * 1024);
vram_sys->next_id = 1;
vram_sys->max_blocks = 256;
vram_sys->blocks_count = 1;
vram_sys->base_ptr = (uint8_t*)malloc(vram_sys->capacity);
vram_sys->blocks = (vram_block_t*)malloc(sizeof(vram_block_t) * vram_sys->max_blocks);
if (!vram_sys->base_ptr || !vram_sys->blocks) {
if (vram_sys->base_ptr) free(vram_sys->base_ptr);
if (vram_sys->blocks) free(vram_sys->blocks);
free(vram_sys);
vram_sys = NULL;
return OS_ERR_NO_MEMORY;
}
vram_sys->blocks[0].offset = 0;
vram_sys->blocks[0].size = vram_sys->capacity;
vram_sys->blocks[0].is_free = true;
vram_sys->blocks[0].id = -1;
if (load_log) {
printf("VRAM: Initialized %d kb at %p\n",
vram_kb[val],
(void*)vram_sys->base_ptr);
}
return OS_OK;
}
vram_handle_t vram_alloc(uint32_t size)
{
if (!vram_sys) return -1;
size = (size + 3) & ~3;
for (int i = 0; i < vram_sys->blocks_count; i++) {
if (vram_sys->blocks[i].is_free && vram_sys->blocks[i].size >= size) {
uint32_t remaining = vram_sys->blocks[i].size - size;
vram_sys->blocks[i].size = size;
vram_sys->blocks[i].is_free = false;
vram_sys->blocks[i].id = vram_sys->next_id++;
if (remaining > 0 && vram_sys->blocks_count < vram_sys->max_blocks) {
for (int j = vram_sys->blocks_count; j > i + 1; j--) {
vram_sys->blocks[j] = vram_sys->blocks[j - 1];
}
vram_sys->blocks[i + 1].offset = vram_sys->blocks[i].offset + size;
vram_sys->blocks[i + 1].size = remaining;
vram_sys->blocks[i + 1].is_free = true;
vram_sys->blocks[i + 1].id = -1;
vram_sys->blocks_count++;
}
return vram_sys->blocks[i].id;
}
}
if (load_log) printf("VRAM: No space for %lu bytes! Need defrag.\n", (unsigned long)size);
return VRAM_WRN_DEFRAG_REQ;
}
void* vram_get_ptr(vram_handle_t handle)
{
if (!vram_sys || handle <= 0) return NULL;
for (int i = 0; i < vram_sys->blocks_count; i++) {
if (vram_sys->blocks[i].id == handle) {
return (void*)(vram_sys->base_ptr + vram_sys->blocks[i].offset);
}
}
return NULL;
}
void vram_free(vram_handle_t handle)
{
if (!vram_sys) return;
for (int i = 0; i < vram_sys->blocks_count; i++) {
if (vram_sys->blocks[i].id == handle) {
vram_sys->blocks[i].is_free = true;
vram_sys->blocks[i].id = -1;
if (i + 1 < vram_sys->blocks_count && vram_sys->blocks[i + 1].is_free) {
vram_sys->blocks[i].size += vram_sys->blocks[i + 1].size;
for (int j = i + 1; j < vram_sys->blocks_count - 1; j++) {
vram_sys->blocks[j] = vram_sys->blocks[j + 1];
}
vram_sys->blocks_count--;
}
if (i > 0 && vram_sys->blocks[i - 1].is_free) {
vram_sys->blocks[i - 1].size += vram_sys->blocks[i].size;
for (int j = i; j < vram_sys->blocks_count - 1; j++) {
vram_sys->blocks[j] = vram_sys->blocks[j + 1];
}
vram_sys->blocks_count--;
}
return;
}
}
}
void vram_defrag(void)
{
if (!vram_sys) return;
uint32_t current_offset = 0;
int write_idx = 0;
for (int i = 0; i < vram_sys->blocks_count; i++) {
if (!vram_sys->blocks[i].is_free) {
if (vram_sys->blocks[i].offset != current_offset) {
memmove(vram_sys->base_ptr + current_offset,
vram_sys->base_ptr + vram_sys->blocks[i].offset,
vram_sys->blocks[i].size);
vram_sys->blocks[i].offset = current_offset;
}
vram_sys->blocks[write_idx] = vram_sys->blocks[i];
current_offset += vram_sys->blocks[write_idx].size;
write_idx++;
}
}
vram_sys->blocks_count = write_idx;
if (current_offset < vram_sys->capacity) {
vram_sys->blocks[write_idx].offset = current_offset;
vram_sys->blocks[write_idx].size = vram_sys->capacity - current_offset;
vram_sys->blocks[write_idx].is_free = true;
vram_sys->blocks[write_idx].id = -1;
vram_sys->blocks_count++;
}
if (load_log) {
printf("VRAM: Defrag complete. Free: %lu bytes\n",
(unsigned long)(vram_sys->capacity - current_offset));
}
}
int vram_write(vram_handle_t handle, const void *src, uint32_t size)
{
if (!vram_sys || handle <= 0 || !src) return -1;
for (int i = 0; i < vram_sys->blocks_count; i++) {
if (vram_sys->blocks[i].id == handle) {
uint32_t write_size = (size < vram_sys->blocks[i].size)
? size
: vram_sys->blocks[i].size;
memcpy(vram_sys->base_ptr + vram_sys->blocks[i].offset, src, write_size);
return OS_OK;
}
}
return VRAM_ERR_WR_or_RD;
}
int vram_read(vram_handle_t handle, void *dst, uint32_t size)
{
if (!vram_sys || handle <= 0 || !dst) return -1;
for (int i = 0; i < vram_sys->blocks_count; i++) {
if (vram_sys->blocks[i].id == handle) {
uint32_t read_size = (size < vram_sys->blocks[i].size)
? size
: vram_sys->blocks[i].size;
memcpy(dst, vram_sys->base_ptr + vram_sys->blocks[i].offset, read_size);
return OS_OK;
}
}
return VRAM_ERR_WR_or_RD;
}
+41
View File
@@ -0,0 +1,41 @@
#ifndef VRAM_H
#define VRAM_H
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include "boot/typedef.h"
typedef int32_t vram_handle_t;
typedef struct {
uint32_t offset;
uint32_t size;
bool is_free;
vram_handle_t id;
} vram_block_t;
typedef struct {
uint8_t* base_ptr;
uint32_t capacity;
vram_block_t* blocks;
int blocks_count;
int max_blocks;
vram_handle_t next_id;
} vram_manager_t;
extern vram_manager_t *vram_sys;
int init_vram(apios_main_table_t *apios_table_);
vram_handle_t vram_alloc(uint32_t size);
void vram_free(vram_handle_t handle);
void* vram_get_ptr(vram_handle_t handle);
int vram_write(vram_handle_t handle, const void* src, uint32_t size);
int vram_read(vram_handle_t handle, void* dst, uint32_t size);
void vram_defrag();
#endif
Executable
+1351
View File
File diff suppressed because it is too large Load Diff