This commit is contained in:
Aren 2024-02-12 16:42:55 +03:00
commit e1e88ada09
15 changed files with 166 additions and 106 deletions

View File

@ -12,7 +12,7 @@
Модули: Модули:
- [ ] Оболочка ввода-вывода - [X] Оболочка ввода-вывода
Драйвера: Драйвера:

View File

@ -19,9 +19,6 @@ TERM_WALLPAPER=boot:///mod/boot.jpg
MODULE_PATH=boot:///mod/pci_vendors.txt MODULE_PATH=boot:///mod/pci_vendors.txt
MODULE_CMDLINE=[PCI][DATA][VENDORS] MODULE_CMDLINE=[PCI][DATA][VENDORS]
MODULE_PATH=boot:///mod/boot.tga
MODULE_CMDLINE=[BOOTIMG]
MODULE_PATH=boot:///mod/simd.ko MODULE_PATH=boot:///mod/simd.ko
MODULE_CMDLINE=[MOD]simd.ko MODULE_CMDLINE=[MOD]simd.ko
@ -37,12 +34,6 @@ TERM_WALLPAPER=boot:///mod/boot.jpg
MODULE_PATH=boot:///mod/cpubench.ko MODULE_PATH=boot:///mod/cpubench.ko
MODULE_CMDLINE=[MOD]cpubench.ko MODULE_CMDLINE=[MOD]cpubench.ko
MODULE_PATH=boot:///mod/tga.ko
MODULE_CMDLINE=[MOD]tga.ko
MODULE_PATH=boot:///mod/imfs.ko
MODULE_CMDLINE=[MOD]imfs.ko
MODULE_PATH=boot:///mod/hello.ko MODULE_PATH=boot:///mod/hello.ko
MODULE_CMDLINE=[MOD]hello.ko MODULE_CMDLINE=[MOD]hello.ko

View File

@ -13,7 +13,7 @@ sudo apt install unzip
## Ubuntu 18.04+ ## Ubuntu 18.04+
```bash ```bash
sudo apt install clang-format python3 git qemu-system-x86 qemu-system-gui gdisk dos2unix xorriso libc6 gcc make curl sudo apt install clang-format python3 git qemu-system-x86 qemu-system-gui gdisk dos2unix xorriso libc6 gcc make curl mtools
git clone https://git.synapseos.ru/Aren/BMOSP.git git clone https://git.synapseos.ru/Aren/BMOSP.git
cd BMOSP/ cd BMOSP/
chmod +x build.sh chmod +x build.sh
@ -26,23 +26,12 @@ chmod +x build.sh
В qemu недоступен флаг `-cpu max`, просто уберите его при запуске В qemu недоступен флаг `-cpu max`, просто уберите его при запуске
```bash ```bash
sudo apt install clang-format python3.7 git qemu-system-x86 gdisk dos2unix xorriso libc6 gcc make curl sudo apt install clang-format python3.7 git qemu-system-x86 gdisk dos2unix xorriso libc6 gcc make curl mtools
git clone https://git.synapseos.ru/Aren/BMOSP.git git clone https://git.synapseos.ru/Aren/BMOSP.git
cd BMOSP/ cd BMOSP/
python3.7 pbuild.py python3.7 pbuild.py
``` ```
## ArchLinux
```bash
yay -S clang-format
sudo pacman -S python3 git qemu-system-x86 qemu-system-gui xorriso libc6 gcc make curl
git clone https://git.synapseos.ru/Aren/BMOSP.git
cd BMOSP/
chmod +x build.sh
./build.sh
```
## Запуск ## Запуск
## Qemu ## Qemu

View File

@ -1,3 +1,3 @@
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 2 #define VERSION_MINOR 2
#define VERSION_BUILD 0 #define VERSION_BUILD 52

View File

@ -7,9 +7,70 @@
*/ */
#include <arch.h> #include <arch.h>
#include <log.h>
typedef struct __attribute__((packed)) {
uint16_t limit;
uint64_t base;
} gdt_reg_t;
struct gdt_desc {
uint16_t limit;
uint16_t base_low;
uint8_t base_mid;
uint8_t access;
uint8_t granularity;
uint8_t base_hi;
} __attribute__((packed));
static uint64_t kernel_start_ticks = 0; static uint64_t kernel_start_ticks = 0;
static uint64_t kernel_ticks = 0; static uint64_t kernel_ticks = 0;
static gdt_reg_t gdtr;
static struct gdt_desc gdt_descs[] = { { 0 },
{ .limit = 0xffff,
.base_low = 0x0000,
.base_mid = 0x00,
.access = 0b10011011,
.granularity = 0b00000000,
.base_hi = 0x00 },
{ .limit = 0xffff,
.base_low = 0x0000,
.base_mid = 0x00,
.access = 0b10010011,
.granularity = 0b00000000,
.base_hi = 0x00 },
{ .limit = 0xffff,
.base_low = 0x0000,
.base_mid = 0x00,
.access = 0b10011011,
.granularity = 0b11001111,
.base_hi = 0x00 },
{ .limit = 0xffff,
.base_low = 0x0000,
.base_mid = 0x00,
.access = 0b10010011,
.granularity = 0b11001111,
.base_hi = 0x00 },
{ .limit = 0x0000,
.base_low = 0x0000,
.base_mid = 0x00,
.access = 0b10011011,
.granularity = 0b00100000,
.base_hi = 0x00 },
{ .limit = 0x0000,
.base_low = 0x0000,
.base_mid = 0x00,
.access = 0b10010011,
.granularity = 0b00000000,
.base_hi = 0x00 } };
extern void load_gdt(uint64_t gdtr);
uint64_t rdtsc( ) { uint64_t rdtsc( ) {
unsigned int lo, hi; unsigned int lo, hi;
@ -41,6 +102,12 @@ uint64_t arch_get_tick_l( ) {
} }
void arch_init( ) { void arch_init( ) {
LOG("Установка сегментов\n");
gdtr.limit = (sizeof(gdt_descs) - 1);
gdtr.base = (uint64_t)&gdt_descs;
load_gdt((uint64_t)&gdtr);
LOG("Установка сегментов успешна!\n");
pic_init( ); pic_init( );
idt_init( ); idt_init( );
cpu_init( ); cpu_init( );

View File

@ -61,6 +61,24 @@ static void do_amd( ) {
LOG("cpu_family = [%u]\n", cpu_family); LOG("cpu_family = [%u]\n", cpu_family);
} }
static void do_intel( ) {
uint32_t eax, ebx, ecx, edx;
uint32_t cpu_model;
uint32_t cpu_family;
uint32_t cpu_brand_id;
cpuid(0, &eax, &ebx, &ecx, &edx);
cpu_brand_id = ebx;
cpu_family = ((eax >> 8) & 0xFF) + ((eax >> 20) & 0xFF);
cpu_model = ((eax >> 4) & 0xF) | ((eax >> 12) & 0xF0);
LOG("Используется процессор Intel\n");
LOG("cpu_brand_id = [%u]\n", cpu_brand_id);
LOG("cpu_family = [%u]\n", cpu_family);
LOG("cpu_model = [%u]\n", cpu_model);
}
static void brandname( ) { static void brandname( ) {
uint32_t eax, ebx, ecx, edx; uint32_t eax, ebx, ecx, edx;
char brand_string[49]; char brand_string[49];
@ -86,15 +104,13 @@ static void brandname( ) {
} }
if (manufacturer[0] == 0x68747541) { do_amd( ); } if (manufacturer[0] == 0x68747541) { do_amd( ); }
} if (manufacturer[0] == 0x756E6547) { do_intel( ); }
void cpu_idle( ) {
if (acpi_msrs_support) { LOG("Температура: %d (в QEMU/KVM всегда 0)\n", get_cpu_temperature_intel( )); }
} }
void cpu_init( ) { void cpu_init( ) {
uint32_t eax, ebx, ecx, edx; uint32_t eax, ebx, ecx, edx;
cpuid(1, &eax, &ebx, &ecx, &edx); cpuid(1, &eax, &ebx, &ecx, &edx);
if ((edx >> 22) & 1) { if ((edx >> 22) & 1) {
acpi_msrs_support = true; acpi_msrs_support = true;
LOG("Встроенный терморегулятор MSRS для ACPI\n"); LOG("Встроенный терморегулятор MSRS для ACPI\n");

View File

@ -1,8 +1,8 @@
.global load_gdt .global load_gdt
load_gdt: load_gdt:
cli cli
lgdt (%rdi) lgdt (%rdi) # Загружаем GDT
movw $0x30, %ax movw $0x30, %ax # Обновляем GDT
mov %ax, %ds mov %ax, %ds
mov %ax, %es mov %ax, %es
mov %ax, %fs mov %ax, %fs

View File

@ -334,10 +334,10 @@ void mem_init( ) {
LOG("Размер битовой карты: %u\n", bitmap_size); LOG("Размер битовой карты: %u\n", bitmap_size);
alloc_init(mem_frame_alloc(1024), 1024 * BLOCK_SIZE); alloc_init(mem_frame_alloc(1024), 1024 * BLOCK_SIZE);
LOG("%u мегабайт выделено в динамичную память\n", (256 * 32 * BLOCK_SIZE + BLOCK_SIZE) / 1024 / 1024); LOG("%u мегабайт выделено в динамичную память\n", (256 * 16 * BLOCK_SIZE + BLOCK_SIZE) / 1024 / 1024);
// Выделяем по 4 мегабайта в аллокатор динамичной памяти // Выделяем по 4 мегабайта в аллокатор динамичной памяти
for (uint64_t i = 0; i < 64; i += 8) { mem_add_block(mem_frame_alloc(1024), 1024 * BLOCK_SIZE); } for (uint64_t i = 0; i < 32; i += 8) { mem_add_block(mem_frame_alloc(1024), 1024 * BLOCK_SIZE); }
mem_merge_all_blocks( ); mem_merge_all_blocks( );
mem_dump_memory( ); mem_dump_memory( );

View File

@ -33,7 +33,7 @@ static void *elf_entry(elf64_header_t *module_bin) {
// Приводим заголовок ELF файла к типу elf64_header_t // Приводим заголовок ELF файла к типу elf64_header_t
elf64_header_t *elf_header = (elf64_header_t *)module_bin; elf64_header_t *elf_header = (elf64_header_t *)module_bin;
// LOG("(uint64_t)elf_header->e_entry = 0x%x, type = %u\n", (uint64_t)elf_header->e_entry, elf_header->e_type); LOG("(uint64_t)elf_header->e_entry = 0x%x, тип = %u\n", (uint64_t)elf_header->e_entry, elf_header->e_type);
if (elf_header->e_type != 2) { if (elf_header->e_type != 2) {
LOG("\t\tОшибка! Модуль неправильно собран!\n"); LOG("\t\tОшибка! Модуль неправильно собран!\n");
@ -92,6 +92,7 @@ void mod_init( ) {
LOG("Ошибка выделения памяти для массива module_list\n"); LOG("Ошибка выделения памяти для массива module_list\n");
return; return;
} }
LOG("module_list = 0x%x\n", module_list);
} }
for (uint64_t i = 0; i < module_count; i++) { for (uint64_t i = 0; i < module_count; i++) {
@ -146,6 +147,7 @@ void mod_init( ) {
module_list[modules_count].name = ret.name; module_list[modules_count].name = ret.name;
module_list[modules_count].message = ret.message; module_list[modules_count].message = ret.message;
module_list[modules_count].data_size = ret.data_size; module_list[modules_count].data_size = ret.data_size;
module_list[modules_count].data = ret.data;
module_list[modules_count].get_func = ret.get_func; module_list[modules_count].get_func = ret.get_func;
module_list[modules_count].after_init = ret.after_init; module_list[modules_count].after_init = ret.after_init;
@ -153,8 +155,6 @@ void mod_init( ) {
task_new_thread(module_list[modules_count].after_init, module_list[modules_count].name); task_new_thread(module_list[modules_count].after_init, module_list[modules_count].name);
} }
if (ret.data_size != 0) { module_list[modules_count].data = ret.data; }
if (ret.irq != 0) { if (ret.irq != 0) {
if (ret.irq_handler != 0) { if (ret.irq_handler != 0) {
LOG("Установлен обработчик прерывания [%u] по адресу 0x%x в модуле %s\n", ret.irq, ret.irq_handler, LOG("Установлен обработчик прерывания [%u] по адресу 0x%x в модуле %s\n", ret.irq, ret.irq_handler,

View File

@ -16,18 +16,6 @@
#include <version.h> #include <version.h>
uint64_t full_init = 0; uint64_t full_init = 0;
uint64_t dum = 0;
void finally( ) {
LOG("Готово! Для выхода из симуляции удерживайте: ESCAPE\n");
for (;;) { asm volatile("hlt"); }
}
void dummy( ) {
LOG("Поток %u\n", dum++);
task_del_current( );
for (;;) { asm volatile("hlt"); }
}
// Точка входа // Точка входа
void _start( ) { void _start( ) {
@ -52,12 +40,11 @@ void _start( ) {
time_t time = rtc_get_time( ); time_t time = rtc_get_time( );
LOG("Время: %u:%u.%u, %u.%u.%u\n", time.hours, time.minutes, time.second, time.day, time.month, time.year); LOG("Время: %u:%u.%u, %u.%u.%u\n", time.hours, time.minutes, time.second, time.day, time.month, time.year);
task_new_thread(finally, "fin");
full_init = 1; full_init = 1;
task_after_init( ); task_after_init( );
LOG("Готово! Для выхода из симуляции удерживайте: ESCAPE\n");
asm volatile("sti"); asm volatile("sti");
for (;;) { asm volatile("hlt"); } for (;;) { asm volatile("hlt"); }

View File

@ -3,6 +3,11 @@
static const char name[] = "[APP]Привет мир!"; static const char name[] = "[APP]Привет мир!";
static const char message[] = "Привет из модуля!"; static const char message[] = "Привет из модуля!";
static int app_main( ) {
fb_printf("[%s]\n", message);
return 2 + 2;
}
module_info_t __attribute__((section(".minit"))) init(env_t *env) { module_info_t __attribute__((section(".minit"))) init(env_t *env) {
init_env(env); init_env(env);
fb_printf("[%s]\n", message); fb_printf("[%s]\n", message);
@ -10,7 +15,7 @@ module_info_t __attribute__((section(".minit"))) init(env_t *env) {
.message = (char *)&message, .message = (char *)&message,
.type = 0, .type = 0,
.data_size = 0, .data_size = 0,
.data = (void *)0, .data = (void *)&app_main,
.err_code = 0, .err_code = 0,
.module_id = 0, .module_id = 0,
.irq = 0, .irq = 0,

View File

@ -4,6 +4,61 @@ static module_info_t *mod_list = NULL;
static uint64_t *mod_count = NULL; static uint64_t *mod_count = NULL;
static uint64_t app_count = 0; static uint64_t app_count = 0;
static module_info_t *app_list = NULL; static module_info_t *app_list = NULL;
static char (*getc)( ) = NULL;
static inline int is_digit(char c) {
if (c >= '0' && c <= '9') { return 1; }
return 0;
}
static int64_t char_to_digit(char c) {
if (is_digit(c)) { return (int64_t)(c - '0'); }
return -1;
}
void ios_main( ) {
module_info_t *kbd_mod = get_module("[KEYBOARD]");
if (kbd_mod == NULL) {
fb_printf("Клавиатура не найдена!\n");
delete_thread( );
for (;;) { asm volatile("hlt"); }
}
getc = kbd_mod->get_func(2);
while (1) {
fb_printf("Доступные программы:\n");
for (uint64_t i = 0; i < app_count; i++) { fb_printf(" %2u. %s\n", i, app_list[i].name); }
fb_printf(" %2u. Выход\n", app_count + 1);
fb_printf("[IOS]>");
char c = '\0';
do { c = getc( ); } while (!is_digit(c));
fb_printf(" %c\n", c);
int select = char_to_digit(c);
if (select == app_count + 1) {
fb_printf("Выход\n");
delete_thread( );
for (;;) { asm volatile("hlt"); }
}
if (select > app_count - 1) {
fb_printf("Ошибка! %u не входит в список\n");
continue;
}
fb_printf("Запуск %s...\n", app_list[select].name);
int (*app)( ) = (int (*)( ))app_list[select].data;
int ret = (*app)( );
fb_printf("\nПриложение %s завершилось с кодом: %d\n", app_list[select].name, ret);
}
}
static void main( ) { static void main( ) {
fb_printf("IOS (input-output shell) - оболочка ввода-вывода\n"); fb_printf("IOS (input-output shell) - оболочка ввода-вывода\n");
@ -22,7 +77,7 @@ static void main( ) {
for (uint64_t i = 0; i < *mod_count; i++) { for (uint64_t i = 0; i < *mod_count; i++) {
if (str_contains(mod_list[i].name, "[APP]")) { if (str_contains(mod_list[i].name, "[APP]")) {
fb_printf("%u. %s\n", app_count, mod_list[i].name); // fb_printf("%u. %s\n", app_count, mod_list[i].name);
app_list[app_count] = mod_list[i]; app_list[app_count] = mod_list[i];
app_count++; app_count++;
} }
@ -36,7 +91,7 @@ static void main( ) {
delete_thread( ); delete_thread( );
} else { } else {
app_list = realloc(app_list, app_count * sizeof(module_info_t)); app_list = realloc(app_list, app_count * sizeof(module_info_t));
for (uint64_t i = 0; i < app_count; i++) { fb_printf("%2u.\t%s\n", app_list[i]); } ios_main( );
for (;;) { asm volatile("hlt"); } for (;;) { asm volatile("hlt"); }
} }

View File

@ -7,17 +7,9 @@ static int ru = 1;
static char c_char = '\0'; static char c_char = '\0';
static key_event_t keyboard_buffer; static key_event_t keyboard_buffer;
void virt_exit( ) { static void virt_exit( ) {
fb_printf("Выход для Bochs\n");
outw(0xB004, 0x2000);
fb_printf("Выход для Qemu\n");
outw(0x604, 0x2000); outw(0x604, 0x2000);
fb_printf("Выход для Virtualbox\n");
outw(0x4004, 0x3400); outw(0x4004, 0x3400);
fb_printf("Выход для облачного гипервизора\n");
outw(0x600, 0x34); outw(0x600, 0x34);
} }
@ -80,8 +72,7 @@ static int is_ctrl(uint8_t scancode) {
} }
} }
void handler(struct frame *state) { static void handler( ) {
(void)state;
while (!(inb(0x64) & 1)) { asm volatile("pause"); } while (!(inb(0x64) & 1)) { asm volatile("pause"); }
uint8_t scancode = inb(0x60); uint8_t scancode = inb(0x60);
@ -159,7 +150,6 @@ module_info_t __attribute__((section(".minit"))) init(env_t *env) {
current_state = NORMAL_STATE; current_state = NORMAL_STATE;
keyboard_buffer.ctrl_pressed = 0; keyboard_buffer.ctrl_pressed = 0;
keyboard_buffer.shift_pressed = 0; keyboard_buffer.shift_pressed = 0;
fb_printf("\t\t[%u][%c]\n", 27, 27);
return (module_info_t){ .name = (char *)"[KEYBOARD]", return (module_info_t){ .name = (char *)"[KEYBOARD]",
.message = (char *)"PS/2 драйвер", .message = (char *)"PS/2 драйвер",
@ -169,6 +159,6 @@ module_info_t __attribute__((section(".minit"))) init(env_t *env) {
.err_code = 0, .err_code = 0,
.module_id = 0, .module_id = 0,
.irq = 33, .irq = 33,
.irq_handler = handler, .irq_handler = &handler,
.get_func = __get_func }; .get_func = __get_func };
} }

2
run.sh
View File

@ -1,5 +1,5 @@
#!/bin/sh #!/bin/sh
qemu-system-x86_64 -name "БМПОС" -cpu max -m 1G -smp 1 \ qemu-system-x86_64 -name "БМПОС" -cpu max -m 64M -smp 1 \
-serial file:serial.log \ -serial file:serial.log \
-drive file=bmosp.hdd,if=none,id=sata_drive -device ahci \ -drive file=bmosp.hdd,if=none,id=sata_drive -device ahci \
-device virtio-blk-pci,drive=sata_drive \ -device virtio-blk-pci,drive=sata_drive \

View File

@ -100,42 +100,6 @@ def check_limine():
subprocess.run(["make"]) subprocess.run(["make"])
os.chdir("..") os.chdir("..")
def check_os():
import platform
using_distro = False
try:
import distro
using_distro = True
except ImportError:
pass
if using_distro:
linux_distro = distro.like()
else:
try:
linux_distro = platform.linux_distribution()[0]
except Exception as E:
return 1
if linux_distro.lower() in ['debian', 'ubuntu', 'astra']:
return 1
return 0
def check_tools():
required_tools = ["gcc", "g++", "xorriso", "make", "mtools", "curl"]
missing_tools = []
for tool in required_tools:
if shutil.which(tool) is None:
missing_tools.append(tool)
if len(missing_tools) > 0:
if check_os():
subprocess.run(["sudo", "apt", "install"] + missing_tools)
return
subprocess.run(["sudo", "pacman", "-S"] + missing_tools)
def create_hdd(IMAGE_NAME): def create_hdd(IMAGE_NAME):
os.system(f"rm -f {IMAGE_NAME}.hdd".format()) os.system(f"rm -f {IMAGE_NAME}.hdd".format())
os.system(f"dd if=/dev/zero bs=1M count=0 seek=4 of={IMAGE_NAME}.hdd") os.system(f"dd if=/dev/zero bs=1M count=0 seek=4 of={IMAGE_NAME}.hdd")
@ -191,10 +155,6 @@ if __name__ == "__main__":
print("Установка Limine") print("Установка Limine")
check_limine() check_limine()
print("Проверка зависимостей")
check_tools()
major, minor, build = version_build() major, minor, build = version_build()
print("Сборка модульного ядра") print("Сборка модульного ядра")