Добавлены описания

This commit is contained in:
Aren Elchinyan 2023-10-21 21:23:51 +03:00
parent 1ca922bb15
commit 02a31cdff7
24 changed files with 250 additions and 174 deletions

View File

@ -1,4 +1,4 @@
ColumnLimit: 80 ColumnLimit: 100
IndentWidth: 4 IndentWidth: 4
UseTab: ForIndentation UseTab: ForIndentation
TabWidth: 4 TabWidth: 4

View File

@ -8,6 +8,9 @@
"complex": "cpp", "complex": "cpp",
"string": "cpp", "string": "cpp",
"limine.h": "c", "limine.h": "c",
"tool.h": "c" "tool.h": "c",
"sys.h": "c",
"arch.h": "c",
"fb.h": "c"
} }
} }

20
API.md
View File

@ -19,7 +19,7 @@
- `-1 блок не найден`. - `-1 блок не найден`.
## sys::alloc_framebuffer() ## sys_alloc_framebuffer()
Выделяет память под буфер кадра для отображения графического интерфейса. Выделяет память под буфер кадра для отображения графического интерфейса.
Возвращает указатель на структуру `framebuffer_t` или 0, если произошла ошибка. Возвращает указатель на структуру `framebuffer_t` или 0, если произошла ошибка.
@ -28,7 +28,7 @@
- `-1 не удалось выделить память для буфера кадра`. - `-1 не удалось выделить память для буфера кадра`.
## sys::free_framebuffer(framebuffer_t *frame) ## sys_free_framebuffer(framebuffer_t *frame)
Освобождает ранее выделенную память `frame` для буфера кадра. Возвращает 0 в случае успеха или -1, если произошла ошибка. Освобождает ранее выделенную память `frame` для буфера кадра. Возвращает 0 в случае успеха или -1, если произошла ошибка.
@ -36,23 +36,23 @@
- `-1 ошибка при освобождении памяти для буфера кадра`. - `-1 ошибка при освобождении памяти для буфера кадра`.
## sys::exit(int code) ## sys_exit(int code)
Завершает выполнение текущего потока с кодом `code`. Завершает выполнение текущего потока с кодом `code`.
## sys::get_error() ## sys_get_error()
Получает код ошибки последней операции. Возвращает целочисленное значение, представляющее код ошибки. Получает код ошибки последней операции. Возвращает целочисленное значение, представляющее код ошибки.
## sys::get_info() ## sys_get_info()
Получает информацию о текущей системе. Возвращает структуру `sys_info_t` содержащую информацию о системе. Получает информацию о текущей системе. Возвращает структуру `sys_info_t` содержащую информацию о системе.
## sys::get_module(uid_t module_id) ## sys_get_module(uid_t module_id)
Получает информацию о модуле `module_id`. Возвращает структуру, содержащую информацию о модуле. Получает информацию о модуле `module_id`. Возвращает структуру, содержащую информацию о модуле.
## sys::new_thread(func_t func) ## sys_new_thread(func_t func)
Создает новый поток выполнения для функции `func`. Возвращает идентификатор созданного потока или 0 в случае ошибки. Создает новый поток выполнения для функции `func`. Возвращает идентификатор созданного потока или 0 в случае ошибки.
@ -60,7 +60,7 @@
- `-1 ошибка при создании потока`. - `-1 ошибка при создании потока`.
## sys::delete_thread(uid_t thread_id) ## sys_delete_thread(uid_t thread_id)
Удаляет указанный поток выполнения `thread_id`. Возвращает 0 в случае успеха или -1 в случае ошибки. Удаляет указанный поток выполнения `thread_id`. Возвращает 0 в случае успеха или -1 в случае ошибки.
@ -69,11 +69,11 @@
- `-1 поток не найден`. - `-1 поток не найден`.
<!-- <!--
## sys::get_time() ## sys_get_time()
Получает текущее время системы в формате timestamp. Возвращает целое число, представляющее количество секунд с начала эпохи. Получает текущее время системы в формате timestamp. Возвращает целое число, представляющее количество секунд с начала эпохи.
## sys::set_alarm(time_t time, func_t func) ## sys_set_alarm(time_t time, func_t func)
Устанавливает сигнал будильника на время time. При наступлении указанного времени будет вызвана функция func. Устанавливает сигнал будильника на время time. При наступлении указанного времени будет вызвана функция func.

21
AUTHORS.md Normal file
View File

@ -0,0 +1,21 @@
# Авторы
## Руководство
### Арен Елчинян
Автор идеи, главный разработчик
* aren@synapseos.ru
* https://t.me/nera00
* https://vk.com/0nera
* https://github.com/0nera
* https://0nera.ru
## Основные участники
__Тут могло быть ваше имя__
## Другие участники
__Тут могло быть ваше имя__

14
HISTORY.md Normal file
View File

@ -0,0 +1,14 @@
# История разработки
## 25.10.2023
Создание проекта
## 12.10.2023
Смена вектора и названия проекта МСООС (минимальная студенческая обучающая операционная система) -> БМПОС (базовая модульная платформа операционных систем)
## 21.10.2023
- Выпуск релиза 0.1.231
- Перевод кодовой базы с C++ на язык C

View File

@ -3,9 +3,9 @@
[![CI сборка](https://github.com/0Nera/BMOSP/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/0Nera/BMOSP/actions/workflows/build.yml) [![CI сборка](https://github.com/0Nera/BMOSP/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/0Nera/BMOSP/actions/workflows/build.yml)
[![Github pages сайт](https://github.com/0Nera/BMOSP/actions/workflows/pages/pages-build-deployment/badge.svg?branch=pages)](https://github.com/0Nera/BMOSP/actions/workflows/pages/pages-build-deployment) [![Github pages сайт](https://github.com/0Nera/BMOSP/actions/workflows/pages/pages-build-deployment/badge.svg?branch=pages)](https://github.com/0Nera/BMOSP/actions/workflows/pages/pages-build-deployment)
БМПОС - Базовая Модульная Платформа Операционных Систем для платформы x86_64 (BIOS/UEFI). Это отечественное программное обеспечение, созданное при поддержке Синапс ОС на языке программирования C++. БМПОС - Базовая Модульная Платформа Операционных Систем для платформы x86_64 (BIOS/UEFI). Это отечественное программное обеспечение, созданное при поддержке Синапс ОС на языке программирования C.
![Скриншот вывода ядра в эмуляторе Qemu](https://0nera.github.io/BMOSP/assets/0_0.1.231.png ![Скриншот вывода ядра в эмуляторе Qemu](https://0nera.github.io/BMOSP/assets/0_0.1.231.png)
## Реализовано ## Реализовано
@ -22,7 +22,6 @@
Драйвера: Драйвера:
- [ ] COM
- [ ] PS/2 (Клавиатура) - [ ] PS/2 (Клавиатура)
- [ ] SATA (ACHI) (Чтение) - [ ] SATA (ACHI) (Чтение)
- [ ] EXT2 - [ ] EXT2
@ -60,7 +59,7 @@
## Сборка из исходного кода ## Сборка из исходного кода
### Ubuntu 18+ ### Ubuntu 18.04+
```bash ```bash
sudo apt install clang-format python3 git qemu-system-x86 sudo apt install clang-format python3 git qemu-system-x86

View File

@ -21,8 +21,7 @@
#define FONT_6X8_SLIM_CHAR_WIDTH 6 #define FONT_6X8_SLIM_CHAR_WIDTH 6
#define FONT_6X8_SLIM_CHAR_HEIGHT 8 #define FONT_6X8_SLIM_CHAR_HEIGHT 8
#define FONT_6X8_SLIM_FONT_TYPE (FONT_TYPE_MONOSPACED) #define FONT_6X8_SLIM_FONT_TYPE (FONT_TYPE_MONOSPACED)
#define FONT_6X8_SLIM_ARRAY_LENGTH \ #define FONT_6X8_SLIM_ARRAY_LENGTH (FONT_6X8_SLIM_LENGTH * FONT_6X8_SLIM_CHAR_HEIGHT)
(FONT_6X8_SLIM_LENGTH * FONT_6X8_SLIM_CHAR_HEIGHT)
static const unsigned char font_6x8_slim[FONT_6X8_SLIM_ARRAY_LENGTH] = { static const unsigned char font_6x8_slim[FONT_6X8_SLIM_ARRAY_LENGTH] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Символ 32 < > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Символ 32 < >

View File

@ -17,9 +17,9 @@ typedef struct {
const char* file; const char* file;
} lock_t; } lock_t;
#define LOCK_INIT \ #define LOCK_INIT \
(lock_t) { \ (lock_t) { \
0, __FILE__ \ 0, __FILE__ \
} }
int lock_swap(lock_t* lock); int lock_swap(lock_t* lock);

View File

@ -15,19 +15,17 @@
#define abs(x) ((x) < 0 ? -(x) : (x)) #define abs(x) ((x) < 0 ? -(x) : (x))
#define assert(check) \ #define assert(check) \
do { \ do { \
if (!(check)) { \ if (!(check)) { \
fb_printf("\nassert() failed in %s() (%s:%d)\n", __func__, \ fb_printf("\nassert() failed in %s() (%s:%d)\n", __func__, __FILE__, __LINE__); \
__FILE__, __LINE__); \ for (;;) asm volatile("hlt"); \
for (;;) asm volatile("hlt"); \ } \
} \
} while (0) } while (0)
#define ALIGN_UP(NUM, ALIGN) (((NUM) + ALIGN - 1) & ~(ALIGN - 1)) #define ALIGN_UP(NUM, ALIGN) (((NUM) + ALIGN - 1) & ~(ALIGN - 1))
#define ALIGN_DOWN(NUM, ALIGN) ((NUM) & ~(ALIGN - 1)) #define ALIGN_DOWN(NUM, ALIGN) ((NUM) & ~(ALIGN - 1))
#define CONTAINER_OF(PTR, TYPE, MEMBER) \ #define CONTAINER_OF(PTR, TYPE, MEMBER) ((TYPE *)((void *)PTR - offsetof(TYPE, MEMBER)))
((TYPE *)((void *)PTR - offsetof(TYPE, MEMBER)))
#define BIT_SET(BIT) (bitmap[(BIT) / 8] |= (1 << ((BIT) % 8))) #define BIT_SET(BIT) (bitmap[(BIT) / 8] |= (1 << ((BIT) % 8)))
#define BIT_CLEAR(BIT) (bitmap[(BIT) / 8] &= ~(1 << ((BIT) % 8))) #define BIT_CLEAR(BIT) (bitmap[(BIT) / 8] &= ~(1 << ((BIT) % 8)))

View File

@ -1,3 +1,3 @@
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 1 #define VERSION_MINOR 1
#define VERSION_BUILD 244 #define VERSION_BUILD 249

View File

@ -1,16 +1,15 @@
/**
* arch.c
* Инициализация архитектуры
*
* Настройка архитектурнозависимых функций
*
*/
#include <arch.h> #include <arch.h>
#include <limine.h>
static volatile struct limine_kernel_address_request kernel_address_request = {
.id = LIMINE_KERNEL_ADDRESS_REQUEST,
.revision = 0,
.response = (struct limine_kernel_address_response *)0
};
struct limine_kernel_address_response *kernel_address_response;
void arch_init( ) { void arch_init( ) {
kernel_address_response = kernel_address_request.response;
gdt_init( ); gdt_init( );
idt_init( ); idt_init( );
cpu_init( );
} }

View File

@ -1,3 +1,12 @@
/**
* cpu.c
* Информация о процессоре
*
* Функционал получения дополнительной информации о процессоре и доступных
* процессорных инструкциях
*
*/
#include <fb.h> #include <fb.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
@ -22,11 +31,8 @@ static void sse_init( ) {
asm volatile("mov %%cr4, %0" : : "r"(_cr4) : "memory"); asm volatile("mov %%cr4, %0" : : "r"(_cr4) : "memory");
} }
static void cpuid(uint32_t leaf, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, static void cpuid(uint32_t leaf, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) {
uint32_t *edx) { asm volatile("cpuid" : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) : "a"(leaf));
asm volatile("cpuid"
: "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx)
: "a"(leaf));
} }
static void msr_get(uint32_t msr, uint32_t *lo, uint32_t *hi) { static void msr_get(uint32_t msr, uint32_t *lo, uint32_t *hi) {
@ -60,8 +66,7 @@ static void l2_cache( ) {
assoc = (ecx >> 12) & 0x07; assoc = (ecx >> 12) & 0x07;
cache = (ecx >> 16) & 0xFFFF; cache = (ecx >> 16) & 0xFFFF;
fb_printf("Размер строки: %u B, Тип ассоциации: %u, Размер кэша: %u КБ\n", fb_printf("Размер строки: %u B, Тип ассоциации: %u, Размер кэша: %u КБ\n", lsize, assoc, cache);
lsize, assoc, cache);
} }
static void do_amd( ) { static void do_amd( ) {
@ -90,8 +95,7 @@ static void brandname( ) {
uint32_t manufacturer[4]; uint32_t manufacturer[4];
char manufacturer_string[13]; char manufacturer_string[13];
cpuid(0, &manufacturer[3], &manufacturer[0], &manufacturer[2], cpuid(0, &manufacturer[3], &manufacturer[0], &manufacturer[2], &manufacturer[1]);
&manufacturer[1]);
tool_memcpy(manufacturer_string, manufacturer, 12); tool_memcpy(manufacturer_string, manufacturer, 12);
brand_string[48] = 0; brand_string[48] = 0;
@ -135,9 +139,7 @@ void cpu_init( ) {
} }
cpuid(1, &eax, &ebx, &ecx, &edx); cpuid(1, &eax, &ebx, &ecx, &edx);
if ((edx >> 29) & 1) { if ((edx >> 29) & 1) { fb_printf("Термоконтроллер автоматически ограничивает температуру\n"); }
fb_printf("Термоконтроллер автоматически ограничивает температуру\n");
}
if ((ecx >> 28) & 1) { if ((ecx >> 28) & 1) {
avx_support = true; avx_support = true;
@ -158,22 +160,17 @@ void cpu_init( ) {
if ((edx >> 5) & 1) { fb_printf("Регистры MSR подерживаются!\n"); } if ((edx >> 5) & 1) { fb_printf("Регистры MSR подерживаются!\n"); }
if ((edx >> 6) & 1) { if ((edx >> 6) & 1) { fb_printf("Расширение физического адреса подерживается!\n"); }
fb_printf("Расширение физического адреса подерживается!\n");
}
if ((edx >> 7) & 1) { if ((edx >> 7) & 1) { fb_printf("Исключение проверки компьютера (MCE) подерживается!\n"); }
fb_printf("Исключение проверки компьютера (MCE) подерживается!\n");
}
if ((edx >> 9) & 1) { if ((edx >> 9) & 1) {
fb_printf("Усовершенствованный программируемый контроллер прерываний " fb_printf("Усовершенствованный программируемый контроллер прерываний "
"подерживаются!\n"); "подерживается!\n");
} }
if ((edx >> 10) & 1) { if ((edx >> 10) & 1) {
fb_printf( fb_printf("SYSCALL/SYSRET(для AMD семейства 5 линейки 7) подерживаются!\n");
"SYSCALL/SYSRET(для AMD семейства 5 линейки 7) подерживаются!\n");
} }
if ((edx >> 11) & 1) { fb_printf("SYSCALL/SYSRET подерживаются!\n"); } if ((edx >> 11) & 1) { fb_printf("SYSCALL/SYSRET подерживаются!\n"); }
@ -186,31 +183,21 @@ void cpu_init( ) {
if ((ecx >> 7) & 1) { fb_printf("Смещенный режим SSE подерживается!\n"); } if ((ecx >> 7) & 1) { fb_printf("Смещенный режим SSE подерживается!\n"); }
cpuid(0x80000007, &eax, &ebx, &ecx, &edx); cpuid(0x80000007, &eax, &ebx, &ecx, &edx);
if ((ebx >> 0) & 1) { if ((ebx >> 0) & 1) { fb_printf("Восстановление после переполнения MCA подерживается!\n"); }
fb_printf("Восстановление после переполнения MCA подерживается!\n");
}
if ((ebx >> 1) & 1) { if ((ebx >> 1) & 1) {
fb_printf("Возможность локализации и восстановления неисправимых " fb_printf("Возможность локализации и восстановления неисправимых "
"программных ошибок подерживается!\n"); "программных ошибок подерживается!\n");
} }
if ((edx >> 0) & 1) { fb_printf("Датчик температуры подерживается!\n"); } if ((edx >> 0) & 1) { fb_printf("Датчик температуры подерживается!\n"); }
if ((edx >> 3) & 1) { fb_printf("Терморегулятор подерживается!\n"); } if ((edx >> 3) & 1) { fb_printf("Терморегулятор подерживается!\n"); }
if ((edx >> 4) & 1) { if ((edx >> 4) & 1) { fb_printf("Аппаратный терморегулятор (HTC) подерживается!\n"); }
fb_printf("Аппаратный терморегулятор (HTC) подерживается!\n"); if ((edx >> 5) & 1) { fb_printf("Программный терморегулятор (STC) подерживается!\n"); }
} if ((edx >> 6) & 1) { fb_printf("Управление множителем 100 МГц подерживается!\n"); }
if ((edx >> 5) & 1) {
fb_printf("Программный терморегулятор (STC) подерживается!\n");
}
if ((edx >> 6) & 1) {
fb_printf("Управление множителем 100 МГц подерживается!\n");
}
fb_printf("0x80000007[ECX] = 0x%x (%u)\n", ecx, ecx); fb_printf("0x80000007[ECX] = 0x%x (%u)\n", ecx, ecx);
cpuid(0xC0000000, &eax, &ebx, &ecx, &edx); cpuid(0xC0000000, &eax, &ebx, &ecx, &edx);
if (eax > 0xC0000000) { if (eax > 0xC0000000) { fb_printf("0xC0000000 [EAX] = 0x%x (%u)\n", eax, eax); }
fb_printf("0xC0000000 [EAX] = 0x%x (%u)\n", eax, eax);
}
brandname( ); brandname( );
l2_cache( ); l2_cache( );

View File

@ -1,3 +1,11 @@
/**
* gdt.c
* Функции таблицы глобальных дескрипторов
*
* Настройка таблицы глобальных дескрипторов для управления сегментами памяти
*
*/
#include <arch.h> #include <arch.h>
#include <fb.h> #include <fb.h>
#include <stdbool.h> #include <stdbool.h>
@ -30,8 +38,8 @@ void gdt_load( ) {
load_gdt((uint64_t)&gdtr); load_gdt((uint64_t)&gdtr);
} }
void set_gdt_entry(gdt_entry_t *entry, uint16_t limit, uint64_t base, void set_gdt_entry(gdt_entry_t *entry, uint16_t limit, uint64_t base, uint8_t access,
uint8_t access, uint8_t granularity) { uint8_t granularity) {
entry->limit = limit; entry->limit = limit;
entry->base_16 = base & 0xFFFF; entry->base_16 = base & 0xFFFF;
entry->base_middle_16 = (base >> 16) & 0xFF; entry->base_middle_16 = (base >> 16) & 0xFF;

View File

@ -1,3 +1,11 @@
/**
* idt.c
* Инициализация обработчика прерываний
*
* Настройка обработчика прерываний и системных исключений
*
*/
#include <arch.h> #include <arch.h>
#include <fb.h> #include <fb.h>
#include <stdbool.h> #include <stdbool.h>
@ -113,10 +121,9 @@ static void exception_handler(struct frame state) {
" RIP=%x RFLAGS=%x\n" " RIP=%x RFLAGS=%x\n"
" CS=%x SS=%x\n" " CS=%x SS=%x\n"
" ERR=%x INT=%u", " ERR=%x INT=%u",
state.rax, state.rbx, state.rcx, state.rdx, state.rsi, state.rdi, state.rax, state.rbx, state.rcx, state.rdx, state.rsi, state.rdi, state.rbp,
state.rbp, state.rsp, state.r8, state.r9, state.r10, state.r11, state.rsp, state.r8, state.r9, state.r10, state.r11, state.r12, state.r13, state.r14,
state.r12, state.r13, state.r14, state.r15, state.rip, state.r15, state.rip, state.rflags, state.cs, state.ss, state.err, state.int_number);
state.rflags, state.cs, state.ss, state.err, state.int_number);
asm volatile("cli; hlt"); asm volatile("cli; hlt");
} }

View File

@ -1,3 +1,12 @@
/**
* fb.c
* Функции управления фреймбуффером
*
* Функционал управления выводом на экранный буффер (фреймбуффер) текста и
* изображений
*
*/
#include <6x8_slim_font.h> #include <6x8_slim_font.h>
#include <fb.h> #include <fb.h>
#include <limine.h> #include <limine.h>
@ -64,9 +73,7 @@ void fb_print_buf(size_t x, size_t y, size_t h, size_t w, uint32_t *buf) {
static inline void print_bits(size_t x, size_t y, uint8_t num) { static inline void print_bits(size_t x, size_t y, uint8_t num) {
for (size_t i = 0; i <= 7; i++) { for (size_t i = 0; i <= 7; i++) {
if ((num >> i) & 1) { if ((num >> i) & 1) { SCREEN_BUFFER[x + i + y * SCREEN_WIDTH] = text_color; }
SCREEN_BUFFER[x + i + y * SCREEN_WIDTH] = text_color;
}
} }
} }
@ -81,14 +88,12 @@ static void print_char(int x, int y, char glyth) {
} }
void scroll_fb( ) { void scroll_fb( ) {
size_t last_line_index = size_t last_line_index = (SCREEN_HEIGHT - (FONT_6X8_SLIM_CHAR_HEIGHT)) * SCREEN_WIDTH;
(SCREEN_HEIGHT - (FONT_6X8_SLIM_CHAR_HEIGHT)) * SCREEN_WIDTH;
for (size_t y = 0; y < SCREEN_HEIGHT - (FONT_6X8_SLIM_CHAR_HEIGHT); y++) { for (size_t y = 0; y < SCREEN_HEIGHT - (FONT_6X8_SLIM_CHAR_HEIGHT); y++) {
for (size_t x = 0; x < SCREEN_WIDTH; x++) { for (size_t x = 0; x < SCREEN_WIDTH; x++) {
SCREEN_BUFFER[x + y * SCREEN_WIDTH] = SCREEN_BUFFER[x + y * SCREEN_WIDTH] =
SCREEN_BUFFER[x + SCREEN_BUFFER[x + (y + (FONT_6X8_SLIM_CHAR_HEIGHT)) * SCREEN_WIDTH];
(y + (FONT_6X8_SLIM_CHAR_HEIGHT)) * SCREEN_WIDTH];
} }
} }

View File

@ -1,3 +1,11 @@
/**
* lock.c
* Функции блокировок
*
* Функционал блокировок и синхронизации
*
*/
#include <fb.h> #include <fb.h>
#include <lock.h> #include <lock.h>
#include <stdint.h> #include <stdint.h>

View File

@ -1,27 +1,37 @@
/**
* main.c
* Точка входа окончания загрузки
*
* Функции эффектов после полной инициализации ядра
*
*/
#include <fb.h> #include <fb.h>
#include <mem.h> #include <mem.h>
#include <tool.h> #include <tool.h>
#define TGA_ERR( ) fb_printf("Ошибка декодирования TGA на строчке: %u\n", __LINE__);
extern void *bootpng_ptr; extern void *bootpng_ptr;
extern uint64_t bootpng_size; extern uint64_t bootpng_size;
typedef struct { typedef struct {
unsigned char magic1; // must be zero unsigned char magic1; // должно быть нулевым
unsigned char colormap; // must be zero unsigned char colormap; // должно быть нулевым
unsigned char encoding; // must be 2 unsigned char encoding; // должно быть 2
unsigned short cmaporig, cmaplen; // must be zero unsigned short cmaporig, cmaplen; // должны быть нулевыми
unsigned char cmapent; // must be zero unsigned char cmapent; // должно быть нулевым
unsigned short x; // must be zero unsigned short x; // должно быть нулевым
unsigned short y; // image's height unsigned short y; // высота изображения
unsigned short h; // image's height unsigned short h; // высота изображения
unsigned short w; // image's width unsigned short w; // ширина изображения
unsigned char bpp; // must be 32 unsigned char bpp; // должно быть 32
unsigned char pixeltype; // must be 40 unsigned char pixeltype; // должно быть 40
} __attribute__((packed)) tga_header_t; } __attribute__((packed)) tga_header_t;
unsigned int *tga_parse(unsigned char *ptr, int size) { unsigned int *tga_parse(unsigned char *ptr, int size) {
unsigned int *data; unsigned int *data;
int i, j, k, x, y, w = (ptr[13] << 8) + ptr[12], int i, j, k, x, y, w = (ptr[13] << 8) + ptr[12], h = (ptr[15] << 8) + ptr[14],
h = (ptr[15] << 8) + ptr[14],
o = (ptr[11] << 8) + ptr[10]; o = (ptr[11] << 8) + ptr[10];
int m = ((ptr[1] ? (ptr[7] >> 3) * ptr[5] : 0) + 18); int m = ((ptr[1] ? (ptr[7] >> 3) * ptr[5] : 0) + 18);
@ -29,16 +39,15 @@ unsigned int *tga_parse(unsigned char *ptr, int size) {
data = (unsigned int *)mem_alloc((w * h + 2) * sizeof(unsigned int)); data = (unsigned int *)mem_alloc((w * h + 2) * sizeof(unsigned int));
if (!data) { if (!data) {
fb_printf("Err %u, %x, %u kb\n", __LINE__, data, fb_printf("Ошибка декодирования TGA на строчке: %u, %x, %u kb\n", __LINE__, data,
((w * h + 2) * sizeof(unsigned int)) / 1024); ((w * h + 2) * sizeof(unsigned int)) / 1024);
return NULL; return NULL;
} }
switch (ptr[2]) { switch (ptr[2]) {
case 1: case 1:
if (ptr[6] != 0 || ptr[4] != 0 || ptr[3] != 0 || if (ptr[6] != 0 || ptr[4] != 0 || ptr[3] != 0 || (ptr[7] != 24 && ptr[7] != 32)) {
(ptr[7] != 24 && ptr[7] != 32)) { TGA_ERR( );
fb_printf("Err %u\n", __LINE__);
mem_free(data); mem_free(data);
return NULL; return NULL;
} }
@ -47,32 +56,28 @@ unsigned int *tga_parse(unsigned char *ptr, int size) {
for (x = 0; x < w; x++) { for (x = 0; x < w; x++) {
j = ptr[m + k++] * (ptr[7] >> 3) + 18; j = ptr[m + k++] * (ptr[7] >> 3) + 18;
data[2 + i++] = ((ptr[7] == 32 ? ptr[j + 3] : 0xFF) << 24) | data[2 + i++] = ((ptr[7] == 32 ? ptr[j + 3] : 0xFF) << 24) |
(ptr[j + 2] << 16) | (ptr[j + 1] << 8) | (ptr[j + 2] << 16) | (ptr[j + 1] << 8) | ptr[j];
ptr[j];
} }
} }
break; break;
case 2: case 2:
if (ptr[5] != 0 || ptr[6] != 0 || ptr[1] != 0 || if (ptr[5] != 0 || ptr[6] != 0 || ptr[1] != 0 || (ptr[16] != 24 && ptr[16] != 32)) {
(ptr[16] != 24 && ptr[16] != 32)) { TGA_ERR( );
fb_printf("Err %u\n", __LINE__);
mem_free(data); mem_free(data);
return NULL; return NULL;
} }
for (y = i = 0; y < h; y++) { for (y = i = 0; y < h; y++) {
j = ((!o ? h - y - 1 : y) * w * (ptr[16] >> 3)); j = ((!o ? h - y - 1 : y) * w * (ptr[16] >> 3));
for (x = 0; x < w; x++) { for (x = 0; x < w; x++) {
data[2 + i++] = data[2 + i++] = ((ptr[16] == 32 ? ptr[j + 3] : 0xFF) << 24) |
((ptr[16] == 32 ? ptr[j + 3] : 0xFF) << 24) | (ptr[j + 2] << 16) | (ptr[j + 1] << 8) | ptr[j];
(ptr[j + 2] << 16) | (ptr[j + 1] << 8) | ptr[j];
j += ptr[16] >> 3; j += ptr[16] >> 3;
} }
} }
break; break;
case 9: case 9:
if (ptr[6] != 0 || ptr[4] != 0 || ptr[3] != 0 || if (ptr[6] != 0 || ptr[4] != 0 || ptr[3] != 0 || (ptr[7] != 24 && ptr[7] != 32)) {
(ptr[7] != 24 && ptr[7] != 32)) { TGA_ERR( );
fb_printf("Err %u\n", __LINE__);
mem_free(data); mem_free(data);
return NULL; return NULL;
} }
@ -88,9 +93,8 @@ unsigned int *tga_parse(unsigned char *ptr, int size) {
i = ((!o ? h - y - 1 : y) * w); i = ((!o ? h - y - 1 : y) * w);
y++; y++;
} }
data[2 + i++] = data[2 + i++] = ((ptr[7] == 32 ? ptr[j + 3] : 0xFF) << 24) |
((ptr[7] == 32 ? ptr[j + 3] : 0xFF) << 24) | (ptr[j + 2] << 16) | (ptr[j + 1] << 8) | ptr[j];
(ptr[j + 2] << 16) | (ptr[j + 1] << 8) | ptr[j];
} }
} else { } else {
k++; k++;
@ -101,17 +105,15 @@ unsigned int *tga_parse(unsigned char *ptr, int size) {
i = ((!o ? h - y - 1 : y) * w); i = ((!o ? h - y - 1 : y) * w);
y++; y++;
} }
data[2 + i++] = data[2 + i++] = ((ptr[7] == 32 ? ptr[j + 3] : 0xFF) << 24) |
((ptr[7] == 32 ? ptr[j + 3] : 0xFF) << 24) | (ptr[j + 2] << 16) | (ptr[j + 1] << 8) | ptr[j];
(ptr[j + 2] << 16) | (ptr[j + 1] << 8) | ptr[j];
} }
} }
} }
break; break;
case 10: case 10:
if (ptr[5] != 0 || ptr[6] != 0 || ptr[1] != 0 || if (ptr[5] != 0 || ptr[6] != 0 || ptr[1] != 0 || (ptr[16] != 24 && ptr[16] != 32)) {
(ptr[16] != 24 && ptr[16] != 32)) { TGA_ERR( );
fb_printf("Err %u\n", __LINE__);
mem_free(data); mem_free(data);
return NULL; return NULL;
} }
@ -126,9 +128,8 @@ unsigned int *tga_parse(unsigned char *ptr, int size) {
i = ((!o ? h - y - 1 : y) * w); i = ((!o ? h - y - 1 : y) * w);
y++; y++;
} }
data[2 + i++] = data[2 + i++] = ((ptr[16] == 32 ? ptr[m + 3] : 0xFF) << 24) |
((ptr[16] == 32 ? ptr[m + 3] : 0xFF) << 24) | (ptr[m + 2] << 16) | (ptr[m + 1] << 8) | ptr[m];
(ptr[m + 2] << 16) | (ptr[m + 1] << 8) | ptr[m];
} }
m += ptr[16] >> 3; m += ptr[16] >> 3;
} else { } else {
@ -139,16 +140,15 @@ unsigned int *tga_parse(unsigned char *ptr, int size) {
i = ((!o ? h - y - 1 : y) * w); i = ((!o ? h - y - 1 : y) * w);
y++; y++;
} }
data[2 + i++] = data[2 + i++] = ((ptr[16] == 32 ? ptr[m + 3] : 0xFF) << 24) |
((ptr[16] == 32 ? ptr[m + 3] : 0xFF) << 24) | (ptr[m + 2] << 16) | (ptr[m + 1] << 8) | ptr[m];
(ptr[m + 2] << 16) | (ptr[m + 1] << 8) | ptr[m];
m += ptr[16] >> 3; m += ptr[16] >> 3;
} }
} }
} }
break; break;
default: { default: {
fb_printf("Err %u\n", __LINE__); TGA_ERR( );
mem_free(data); mem_free(data);
return NULL; return NULL;
} }
@ -165,9 +165,7 @@ void main( ) {
tga_header_t *head = (tga_header_t *)bootpng_ptr; tga_header_t *head = (tga_header_t *)bootpng_ptr;
if (res != NULL) { if (res != NULL) { fb_printf("Размер экрана загрузки: %ux%u \n", res[0], res[1]); }
fb_printf("Размер экрана загрузки: %ux%u \n", res[0], res[1]);
}
fb_printf("Размер экрана загрузки: %ux%u \n", head->h, head->w); fb_printf("Размер экрана загрузки: %ux%u \n", head->h, head->w);
mem_dump_memory( ); mem_dump_memory( );

View File

@ -1,3 +1,11 @@
/**
* mem.c
* Функции управления памятью
*
* Основной функционал менеджера памяти
*
*/
#include <fb.h> #include <fb.h>
#include <limine.h> #include <limine.h>
#include <lock.h> #include <lock.h>
@ -6,14 +14,10 @@
#include <tool.h> #include <tool.h>
static volatile struct limine_memmap_request memmap_request = { static volatile struct limine_memmap_request memmap_request = {
.id = LIMINE_MEMMAP_REQUEST, .id = LIMINE_MEMMAP_REQUEST, .revision = 0, .response = (struct limine_memmap_response *)0
.revision = 0,
.response = (struct limine_memmap_response *)0
}; };
static volatile struct limine_hhdm_request hhdm_request = { static volatile struct limine_hhdm_request hhdm_request = {
.id = LIMINE_HHDM_REQUEST, .id = LIMINE_HHDM_REQUEST, .revision = 0, .response = (struct limine_hhdm_response *)0
.revision = 0,
.response = (struct limine_hhdm_response *)0
}; };
struct mem_entry { struct mem_entry {
@ -56,9 +60,8 @@ void mem_dump_memory( ) {
mem_entry_t *curr = first_node; mem_entry_t *curr = first_node;
while (curr) { while (curr) {
fb_printf("->0x%x | %u.%u kb | %u | 0x%x\n", &curr->data, fb_printf("->0x%x | %u.%u kb | %u | 0x%x\n", &curr->data, (curr->size) / 1024,
(curr->size) / 1024, (curr->size) % 1024, curr->free, (curr->size) % 1024, curr->free, curr->next);
curr->next);
curr = curr->next; curr = curr->next;
} }
} }
@ -232,8 +235,7 @@ void mem_init( ) {
if (mmaps[i]->type == LIMINE_MEMMAP_FRAMEBUFFER) { if (mmaps[i]->type == LIMINE_MEMMAP_FRAMEBUFFER) {
fb_printf("На видеопамять BIOS/UEFI выделено: %u мегабайт + %u " fb_printf("На видеопамять BIOS/UEFI выделено: %u мегабайт + %u "
"килобайт\n", "килобайт\n",
mmaps[i]->length / 1024 / 1024, mmaps[i]->length / 1024 / 1024, (mmaps[i]->length / 1024) % 1024);
(mmaps[i]->length / 1024) % 1024);
} }
if (!(mmaps[i]->type == LIMINE_MEMMAP_USABLE)) { continue; } if (!(mmaps[i]->type == LIMINE_MEMMAP_USABLE)) { continue; }
@ -261,9 +263,7 @@ void mem_init( ) {
// Освобождаем все доступные фреймы памяти // Освобождаем все доступные фреймы памяти
for (uint64_t i = 0; i < mmmap_count; i++) { for (uint64_t i = 0; i < mmmap_count; i++) {
for (uint64_t t = 0; t < mmaps[i]->length; t += BLOCK_SIZE) { for (uint64_t t = 0; t < mmaps[i]->length; t += BLOCK_SIZE) { bitmap_limit++; }
bitmap_limit++;
}
if (!(mmaps[i]->type == LIMINE_MEMMAP_USABLE)) { continue; } if (!(mmaps[i]->type == LIMINE_MEMMAP_USABLE)) { continue; }
@ -283,8 +283,7 @@ void mem_init( ) {
fb_printf("%u мегабайт выделено в динамичную память\n", fb_printf("%u мегабайт выделено в динамичную память\n",
(256 * 1024 * BLOCK_SIZE + BLOCK_SIZE) / 1024 / 1024); (256 * 1024 * BLOCK_SIZE + BLOCK_SIZE) / 1024 / 1024);
fb_printf("%u МБ объем доступной памяти, %u МБ объем виртуальной памяти\n", fb_printf("%u МБ объем доступной памяти, %u МБ объем виртуальной памяти\n",
(bitmap_available * BLOCK_SIZE) / 1024 / 1024, (bitmap_available * BLOCK_SIZE) / 1024 / 1024, available / 1024 / 1024);
available / 1024 / 1024);
fb_printf("%u / %u блоков доступно\n", bitmap_available, bitmap_limit); fb_printf("%u / %u блоков доступно\n", bitmap_available, bitmap_limit);
fb_printf("Проверка менеджера памяти\n"); fb_printf("Проверка менеджера памяти\n");

View File

@ -1,3 +1,12 @@
/**
* mod.c
* Функции загрузки модулей
*
* Файл с функциями для загрузки модулей в формате ELF файлов полученных от
* загрузчика
*
*/
#include <fb.h> #include <fb.h>
#include <limine.h> #include <limine.h>
#include <mod.h> #include <mod.h>
@ -45,9 +54,7 @@ static void *elf_entry(void *module_bin, uint64_t size) {
} }
static volatile struct limine_module_request module_request = { static volatile struct limine_module_request module_request = {
.id = LIMINE_MODULE_REQUEST, .id = LIMINE_MODULE_REQUEST, .revision = 0, .response = (struct limine_module_response *)0
.revision = 0,
.response = (struct limine_module_response *)0
}; };
static struct limine_module_response *module_response; static struct limine_module_response *module_response;
@ -61,14 +68,12 @@ void mod_init( ) {
for (uint64_t i = 0; i < module_count; i++) { for (uint64_t i = 0; i < module_count; i++) {
module_ptr = module_response->modules[i]; module_ptr = module_response->modules[i];
fb_printf("[%d] %s [%s] 0x%x\n", i, module_ptr->path, fb_printf("[%d] %s [%s] 0x%x\n", i, module_ptr->path, module_ptr->cmdline,
module_ptr->cmdline, module_ptr->address); module_ptr->address);
fb_printf("->Размер: %u, тип носителя: %u, индекс раздела: %u\n", fb_printf("->Размер: %u, тип носителя: %u, индекс раздела: %u\n", module_ptr->size,
module_ptr->size, module_ptr->media_type, module_ptr->media_type, module_ptr->partition_index);
module_ptr->partition_index);
fb_printf("->Идентификатор диска MBR: %u, TFTP IP: %u, TFTP порт: %u\n", fb_printf("->Идентификатор диска MBR: %u, TFTP IP: %u, TFTP порт: %u\n",
module_ptr->mbr_disk_id, module_ptr->tftp_ip, module_ptr->mbr_disk_id, module_ptr->tftp_ip, module_ptr->tftp_port);
module_ptr->tftp_port);
if (tool_starts_with(module_ptr->cmdline, "[BOOTIMG]")) { if (tool_starts_with(module_ptr->cmdline, "[BOOTIMG]")) {
fb_printf("\t\t[BOOTIMG]\n"); fb_printf("\t\t[BOOTIMG]\n");
@ -79,8 +84,7 @@ void mod_init( ) {
if (!tool_starts_with(module_ptr->cmdline, "[MOD]")) { continue; } if (!tool_starts_with(module_ptr->cmdline, "[MOD]")) { continue; }
modules_count++; modules_count++;
module_info_t *(*module_init)(env_t * env) = module_info_t *(*module_init)(env_t * env) =
(module_info_t * (*)(env_t * env)) (module_info_t * (*)(env_t * env)) elf_entry(module_ptr->address, module_ptr->size);
elf_entry(module_ptr->address, module_ptr->size);
fb_printf("\t->Точка входа: 0x%x\n", module_init); fb_printf("\t->Точка входа: 0x%x\n", module_init);

View File

@ -1,3 +1,12 @@
/**
* start.c
* Файл с точкой входа
*
*
* Файл с функцией для инициализации системы
*
*/
#include <arch.h> #include <arch.h>
#include <fb.h> #include <fb.h>
#include <limine.h> #include <limine.h>
@ -12,9 +21,9 @@ void _start( ) {
fb_init( ); fb_init( );
arch_init( ); arch_init( );
cpu_init( );
mem_init( ); mem_init( );
mod_init( ); mod_init( );
fb_printf("\t\t\t\t *** Базовая Модульная Платформа Операционных Систем " fb_printf("\t\t\t\t *** Базовая Модульная Платформа Операционных Систем "
"версии %u.%u.%u ***\n", "версии %u.%u.%u ***\n",
VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD); VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD);

View File

@ -1,3 +1,10 @@
/**
* sys.c
* Файл с функциями управления системой
*
* Этот файл содержит имплементацию функций для управления системой
*/
#include <stdint.h> #include <stdint.h>
#include <sys.h> #include <sys.h>

View File

@ -1,4 +1,10 @@
/**
* task.c
* Управление потоками
*
* Данный файл содержит функции для создания и удаления потоков.
*
*/
void task_new_thread( ) { void task_new_thread( ) {
return; return;

View File

@ -1,4 +1,11 @@
#include <limine.h> /**
* tool.c
* Функции для упрощения разработки
*
* Данный файл содержит реализацию функций для упрощения написания кода
*
*/
#include <stdarg.h> #include <stdarg.h>
#include <stdint.h> #include <stdint.h>
@ -38,8 +45,7 @@ uint64_t tool_starts_with(const char *str, const char *prefix) {
} }
// Функция для форматированного вывода // Функция для форматированного вывода
void tool_format(void (*putc)(char c), const char *format_string, void tool_format(void (*putc)(char c), const char *format_string, va_list args) {
va_list args) {
while (*format_string != '\0') { while (*format_string != '\0') {
if (*format_string == '%') { if (*format_string == '%') {
format_string++; format_string++;

View File

@ -2,10 +2,9 @@
const char name[] = "Привет мир!"; const char name[] = "Привет мир!";
const char message[] = "Привет из модуля!"; const char message[] = "Привет из модуля!";
module_info_t info = { .name = (char *)&name, module_info_t info = {
.message = (char *)&message, .name = (char *)&name, .message = (char *)&message, .err_code = 2023, .func_count = 1
.err_code = 2023, };
.func_count = 1 };
env_t *env; env_t *env;
module_info_t *_start(env_t *env) { module_info_t *_start(env_t *env) {