diff --git a/README.md b/README.md index 8006c27..b37552d 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,10 @@ БМПОС - Базовая Модульная Платформа Операционных Систем для платформы x86_64 (BIOS/UEFI). Это отечественное программное обеспечение, созданное при поддержке Синапс ОС на языке программирования C. +БМПОС не является операционной системой. Это платформа для изучения. + +Философия БМПОС - "всё есть модуль". + ![Скриншот вывода ядра в эмуляторе Qemu](https://0nera.github.io/BMOSP/assets/0_0.1.231.png) ## Реализовано @@ -15,6 +19,7 @@ - [x] Менеджер видеопамяти - [ ] Менеджер потоков - [x] Загрузчик модулей +- [ ] Буфферы ввода-вывода Модули: @@ -23,9 +28,39 @@ Драйвера: - [ ] PS/2 (Клавиатура) -- [ ] SATA (ACHI) (Чтение) +- [ ] SATA (AHCI) (Чтение) - [ ] EXT2 +Документация: + +- [X] Системные вызовы +- [ ] Ядро +- [ ] Стандартная библиотека + +Вебсайт: + +- [X] Домен +- [ ] Движок сайта +- [ ] Документация +- [ ] Статьи +- [ ] Примеры + +Примеры: + +- [ ] Пример модуля +- [ ] Пример драйвера +- [ ] Пример программы-модуля +- [ ] Пример модуля ввода-вывода + +Видеоуроки: + +- [ ] Основы языка C +- [ ] Основы ассемблера GAS +- [ ] Настройка окружения +- [ ] Сборка из исходного кода +- [ ] Привет мир! +- [ ] Написание драйвера + Общая работа: - [ ] Ядро @@ -49,9 +84,8 @@ Драйвера: - [ ] PS/2 (Мышь) -- [ ] SATA (ACHI) (Запись) -- [ ] ISOFS (ISO 9660) -- [ ] SIMD (SSE, SSE2, SSE3, SSE4, AVX) +- [ ] SATA (AHCI) (Запись) +- [ ] SIMD (SSE, SSE2, SSE3, SSE4, AVX) - отдельный драйвер для инициализации SIMD инструкций ## Партнеры diff --git a/include/version.h b/include/version.h index 19ed7f4..9a570c4 100644 --- a/include/version.h +++ b/include/version.h @@ -1,3 +1,3 @@ #define VERSION_MAJOR 0 #define VERSION_MINOR 1 -#define VERSION_BUILD 280 +#define VERSION_BUILD 290 diff --git a/kernel/arch/cpu.c b/kernel/arch/cpu.c index b4035c6..8679edd 100644 --- a/kernel/arch/cpu.c +++ b/kernel/arch/cpu.c @@ -154,15 +154,15 @@ void cpu_init( ) { } cpuid(0x80000000, &eax, &ebx, &ecx, &edx); - fb_printf("0x80000000 [EAX] = 0x%x (%u)\n", eax, eax); + fb_printf("Максимально поддерживаемая функция CPUID = 0x%x (%u)\n", eax, eax); cpuid(0x80000001, &eax, &ebx, &ecx, &edx); if ((edx >> 5) & 1) { fb_printf("Регистры MSR подерживаются!\n"); } - if ((edx >> 6) & 1) { fb_printf("Расширение физического адреса поддерживается!\n"); } + // if ((edx >> 6) & 1) { fb_printf("Расширение физического адреса поддерживается!\n"); } - if ((edx >> 7) & 1) { fb_printf("Исключение проверки компьютера (MCE) поддерживается!\n"); } + // if ((edx >> 7) & 1) { fb_printf("Исключение проверки компьютера (MCE) поддерживается!\n"); } if ((edx >> 9) & 1) { fb_printf("Усовершенствованный программируемый контроллер прерываний " @@ -174,27 +174,25 @@ void cpu_init( ) { } if ((edx >> 11) & 1) { fb_printf("SYSCALL/SYSRET подерживаются!\n"); } - if ((edx >> 26) & 1) { fb_printf("Гигабайтные страницы подерживаются!\n"); } + // if ((edx >> 26) & 1) { fb_printf("Гигабайтные страницы подерживаются!\n"); } if ((edx >> 29) & 1) { fb_printf("AMD64 поддерживается!\n"); } - if ((edx >> 30) & 1) { fb_printf("\"3DNow!\" поддерживается!\n"); } - if ((edx >> 31) & 1) { fb_printf("\"Extended 3DNow!\" поддерживается!\n"); } + // if ((edx >> 30) & 1) { fb_printf("\"3DNow!\" поддерживается!\n"); } + // if ((edx >> 31) & 1) { fb_printf("\"Extended 3DNow!\" поддерживается!\n"); } if ((ecx >> 6) & 1) { fb_printf("SSE4a поддерживается!\n"); } if ((ecx >> 7) & 1) { fb_printf("Смещенный режим SSE поддерживается!\n"); } cpuid(0x80000007, &eax, &ebx, &ecx, &edx); - if ((ebx >> 0) & 1) { fb_printf("Восстановление после переполнения MCA поддерживается!\n"); } - if ((ebx >> 1) & 1) { - fb_printf("Возможность локализации и восстановления неисправимых " - "программных ошибок поддерживается!\n"); - } + // if ((ebx >> 0) & 1) { fb_printf("Восстановление после переполнения MCA поддерживается!\n"); } + // if ((ebx >> 1) & 1) { fb_printf("Возможность локализации и восстановления неисправимых + // программных ошибок поддерживается!\n"); } if ((edx >> 0) & 1) { fb_printf("Датчик температуры поддерживается!\n"); } if ((edx >> 3) & 1) { fb_printf("Терморегулятор поддерживается!\n"); } if ((edx >> 4) & 1) { fb_printf("Аппаратный терморегулятор (HTC) поддерживается!\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); if (eax > 0xC0000000) { fb_printf("0xC0000000 [EAX] = 0x%x (%u)\n", eax, eax); } diff --git a/kernel/fb.c b/kernel/fb.c index b37d135..fae152c 100644 --- a/kernel/fb.c +++ b/kernel/fb.c @@ -41,13 +41,14 @@ uint64_t height; uint64_t pitch; uint16_t bpp; -size_t pos_x = 4; -size_t pos_y = 4; +uint64_t pos_x = 4; +uint64_t pos_y = 4; #define SCREEN_WIDTH width #define SCREEN_HEIGHT height #define SCREEN_BUFFER fb_addr +// Настройка прослойки графики ядра void fb_init( ) { framebuffer_response = framebuffer_request.response; boot_framebuffer = framebuffer_response->framebuffers[0]; @@ -62,46 +63,52 @@ void fb_init( ) { fb_printf("0x%x %ux%u\n", fb_addr, width, height); } -void fb_print_buf(size_t x, size_t y, size_t h, size_t w, uint32_t *buf) { - for (size_t j = 0; j < h; j++) { - for (size_t i = 0; i < w; i++) { +// Отрисовка буффера по координатам (полезно для картинок) +void fb_print_buf(uint64_t x, uint64_t y, uint64_t h, uint64_t w, uint32_t *buf) { + for (uint64_t j = 0; j < h; j++) { + for (uint64_t i = 0; i < w; i++) { uint64_t where = (i + x) + (j + y) * width; SCREEN_BUFFER[where] = buf[i + j * w]; } } } -static inline void print_bits(size_t x, size_t y, uint8_t num) { - for (size_t i = 0; i <= 7; i++) { +// Побитовый вывод из числа +static inline void print_bits(uint64_t x, uint64_t y, uint8_t num) { + for (uint64_t i = 0; i <= 7; i++) { if ((num >> i) & 1) { SCREEN_BUFFER[x + i + y * SCREEN_WIDTH] = text_color; } } } +// Получение кода символа в таблице static inline uint32_t analyze(char glyth) { return ((uint8_t)glyth - 32) * 8; } +// Вывод символа по координатам static void print_char(int x, int y, char glyth) { - for (size_t i = 0; i < FONT_6X8_SLIM_CHAR_HEIGHT; i++) { + for (uint64_t i = 0; i < FONT_6X8_SLIM_CHAR_HEIGHT; i++) { print_bits(x, y + i, font_6x8_slim[analyze(glyth) + i]); } } -void scroll_fb( ) { - size_t last_line_index = (SCREEN_HEIGHT - (FONT_6X8_SLIM_CHAR_HEIGHT)) * SCREEN_WIDTH; +// Прокрутка буффера вверх. Нижний слой удаляется +static void scroll_fb( ) { + uint64_t last_line_index = (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 x = 0; x < SCREEN_WIDTH; x++) { + for (uint64_t y = 0; y < SCREEN_HEIGHT - (FONT_6X8_SLIM_CHAR_HEIGHT); y++) { + for (uint64_t x = 0; x < SCREEN_WIDTH; x++) { SCREEN_BUFFER[x + y * SCREEN_WIDTH] = SCREEN_BUFFER[x + (y + (FONT_6X8_SLIM_CHAR_HEIGHT)) * SCREEN_WIDTH]; } } - for (size_t i = last_line_index; i < SCREEN_HEIGHT * SCREEN_WIDTH; i++) { + for (uint64_t i = last_line_index; i < SCREEN_HEIGHT * SCREEN_WIDTH; i++) { SCREEN_BUFFER[i] = background; } } +// Вывод одного символа static void fb_putchar(char c) { if (c == '\t') { pos_x += FONT_6X8_SLIM_CHAR_WIDTH * 4; @@ -123,6 +130,7 @@ static void fb_putchar(char c) { } } +// Вывод текстового сообщения void fb_printf(char *str, ...) { va_list args; va_start(args, str); @@ -130,13 +138,14 @@ void fb_printf(char *str, ...) { va_end(args); } -void fb_printf_at(size_t x, size_t y, char *str, ...) { +// Вывод текстового сообщения по координатам +void fb_printf_at(uint64_t x, uint64_t y, char *str, ...) { va_list args; va_start(args, str); // Сохраняем текущие значения pos_x и pos_y - size_t prev_pos_x = pos_x; - size_t prev_pos_y = pos_y; + uint64_t prev_x = pos_x; + uint64_t prev_y = pos_y; // Устанавливаем новые значения координат вывода pos_x = x; @@ -146,8 +155,8 @@ void fb_printf_at(size_t x, size_t y, char *str, ...) { tool_format(&fb_putchar, str, args); // Восстанавливаем предыдущие значения pos_x и pos_y - pos_x = prev_pos_x; - pos_y = prev_pos_y; + pos_x = prev_x; + pos_y = prev_y; va_end(args); } \ No newline at end of file diff --git a/kernel/lock.c b/kernel/lock.c index 0146b11..bb21675 100644 --- a/kernel/lock.c +++ b/kernel/lock.c @@ -11,10 +11,12 @@ #include #include +// Если не заблокировано - блокируем int lock_swap(lock_t *lock) { return __sync_bool_compare_and_swap(&lock->lock, 0, 1); } +// Запрос блокировки ресурса void lock_acquire(lock_t *lock) { uint64_t count = 0; @@ -30,6 +32,7 @@ void lock_acquire(lock_t *lock) { } } +// Запрос разблокировки ресурса void lock_release(lock_t *lock) { __sync_bool_compare_and_swap(&lock->lock, 1, 0); } \ No newline at end of file diff --git a/kernel/mod.c b/kernel/mod.c index 9fc799d..e0942f7 100644 --- a/kernel/mod.c +++ b/kernel/mod.c @@ -41,6 +41,7 @@ static void *elf_entry(void *module_bin, uint64_t size) { // Приводим заголовок ELF файла к типу elf64_header_t elf64_header_t *elf_header = (elf64_header_t *)module_bin; +#if 0 fb_printf(" Класс: ELF64\n"); fb_printf(" Версия: %u\n", elf_header->e_ident[6]); fb_printf(" ОС/ABI: %u\n", elf_header->e_ident[7]); @@ -48,6 +49,7 @@ static void *elf_entry(void *module_bin, uint64_t size) { fb_printf(" Машина: %u\n", elf_header->e_machine); fb_printf(" Версия: %u\n", elf_header->e_version); fb_printf(" Точка входа: 0x%x\n", elf_header->e_entry); +#endif // Возвращаем указатель на точку входа return (void *)((uint64_t)elf_header->e_entry + (uint64_t)module_bin); @@ -72,9 +74,11 @@ void mod_init( ) { module_ptr->address); fb_printf("->Размер: %u, тип носителя: %u, индекс раздела: %u\n", module_ptr->size, module_ptr->media_type, module_ptr->partition_index); +#if 0 fb_printf("->Идентификатор диска MBR: %u, TFTP IP: %u, TFTP порт: %u\n", module_ptr->mbr_disk_id, module_ptr->tftp_ip, module_ptr->tftp_port); +#endif if (tool_starts_with(module_ptr->cmdline, "[BOOTIMG]")) { fb_printf("\t\t[BOOTIMG]\n"); bootpng_ptr = module_ptr->address; diff --git a/modlib/system.h b/modlib/system.h index d5b8976..e877ff8 100644 --- a/modlib/system.h +++ b/modlib/system.h @@ -1,13 +1,20 @@ +/** + * system.h + * Системные вызовы + * + * Заголовочный файл содержащий заготовку для работы с системными вызовами + * + */ + +#ifndef SYSTEM_H +#define SYSTEM_H + typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; typedef unsigned long long uint64_t; typedef long long int64_t; -typedef struct { - void (*fb_printf)(char *str, ...); -} env_t; - typedef struct { int reserved; } framebuffer_t; @@ -46,4 +53,14 @@ typedef struct { uint8_t second; } time_t; -void (*fb_printf)(char *str, ...); \ No newline at end of file +typedef struct { + uint64_t offset; + module_info_t *info; + void (*fb_printf)(char *str, ...); +} env_t; + +void (*fb_printf)(char *str, ...); + +static inline void init_env(env_t *loader_env) {} + +#endif // system.h diff --git a/modules/helloworld/main.c b/modules/helloworld/main.c index 22e3532..d047c25 100644 --- a/modules/helloworld/main.c +++ b/modules/helloworld/main.c @@ -2,10 +2,11 @@ const char name[] = "Привет мир!"; const char message[] = "Привет из модуля!"; -module_info_t info = { +module_info_t static_info = { .name = (char *)&name, .message = (char *)&message, .err_code = 2023, .func_count = 1 }; uint64_t init(env_t *env) { - return info.err_code; + init_env(env); + return 0; } diff --git a/modules/music/main.c b/modules/music/main.c index ad94a75..1d4400a 100644 --- a/modules/music/main.c +++ b/modules/music/main.c @@ -17,8 +17,8 @@ static inline void usleep(uint64_t ticks) { static inline void play_sound(unsigned int frequency) {} int init(env_t *env) { - - + init_env(env); + return 0; // Массив с нотами unsigned int tetris_notes[] = { 0 };