From 230eecc911fca4e56ec872a9bb3a8ac07f92e139 Mon Sep 17 00:00:00 2001 From: Aren Date: Tue, 30 Apr 2024 13:34:47 +0300 Subject: [PATCH 01/12] =?UTF-8?q?=D0=94=D0=B8=D0=BD=D0=B0=D0=BC=D0=B8?= =?UTF-8?q?=D1=87=D0=B5=D1=81=D0=BA=D0=B0=D1=8F=20=D0=BB=D0=B8=D0=BD=D0=BA?= =?UTF-8?q?=D0=BE=D0=B2=D0=BA=D0=B0=20=D1=81=D0=B8=D0=BC=D0=B2=D0=BE=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20[1/3]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/mod.h | 18 ++++++++++++++++++ include/version.h | 2 +- kernel/elf.c | 31 +++++++++++++++++++++++++++++-- kernel/tool.c | 8 ++++++++ 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/include/mod.h b/include/mod.h index 402e48a..2bb29b7 100644 --- a/include/mod.h +++ b/include/mod.h @@ -25,6 +25,24 @@ #define ELFMAG3 'F' #define SHT_SYMTAB 2 +#define STT_NOTYPE 0 // Тип символа не указан +#define STT_OBJECT 1 // Символ является объектом данных +#define STT_FUNC 2 // Символ является объектом кода +#define STT_SECTION 3 // Символ связан с разделом +#define STT_FILE 4 // Имя символа является именем файла +#define STT_COMMON 5 // Символ является общим объектом данных +#define STT_TLS 6 // Символ является объектом данных локального потока +#define STT_NUM 7 // Количество определенных типов. +#define STT_GNU_IFUNC 10 // Символ является объектом непрямого кода + +#define ELF32_ST_BIND(val) (((unsigned char)(val)) >> 4) +#define ELF32_ST_TYPE(val) ((val)&0xf) +#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type)&0xf)) + +#define ELF64_ST_BIND(val) ELF32_ST_BIND(val) +#define ELF64_ST_TYPE(val) ELF32_ST_TYPE(val) +#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO((bind), (type)) + typedef uint64_t elf64_addr_t; // Адрес typedef uint64_t elf64_offset_t; // Смещение typedef uint64_t elf64_xword_t; // Целочисленное длинное слово без знака diff --git a/include/version.h b/include/version.h index 5807446..a6a0b1e 100644 --- a/include/version.h +++ b/include/version.h @@ -1,3 +1,3 @@ #define VERSION_MAJOR 0 #define VERSION_MINOR 2 -#define VERSION_BUILD 58 +#define VERSION_BUILD 94 diff --git a/kernel/elf.c b/kernel/elf.c index a1328e1..92a2c7e 100644 --- a/kernel/elf.c +++ b/kernel/elf.c @@ -76,6 +76,10 @@ void *elf_entry(void *module_bin) { return (void *)((uint64_t)elf_header->e_entry + (uint64_t)module_bin); } +void import_test( ) { + LOG("123"); +} + void *elf_parse(elf64_header_t *head) { elf64_section_header_t *symtab = NULL; @@ -85,7 +89,7 @@ void *elf_parse(elf64_header_t *head) { return -1; } - LOG("Точка входа: 0x%x\n", head->e_entry); + // LOG("Точка входа: 0x%x\n", head->e_entry); elf64_section_header_t *symtab_section = NULL; char *string_table = NULL; @@ -106,7 +110,30 @@ void *elf_parse(elf64_header_t *head) { int num_symbols = symtab_section->sh_size / symtab_section->sh_entsize; for (int i = 0; i < num_symbols; i++) { elf64_sym_t *sym = elf64_get_symval(head, symtab_section - elf64_sheader(head), i); - if (sym) { LOG("%6u %8x %6x %s\n", i, sym->st_value, sym->st_size, string_table + sym->st_name); } + if (sym) { + LOG("%6u %8x %6x %18s ", i, sym->st_value, sym->st_size, string_table + sym->st_name); + switch (ELF64_ST_TYPE(sym->st_info)) { + case STT_NOTYPE: log_printf("без типа\n"); break; + case STT_OBJECT: + log_printf("объект данных\n"); + if (!(string_table + sym->st_name)) { break; } + // log_printf("%u\n", tool_strcmp(string_table + sym->st_name, "import_test")); + if (tool_strcmp(string_table + sym->st_name, "import_test") == 0) { + log_printf("0x%x\n", head + sym->st_value); + void (*imp)( ) = (void *)head + sym->st_value; + *imp = &import_test; + } + break; + case STT_FUNC: log_printf("объект кода\n"); break; + case STT_SECTION: log_printf("символ раздела\n"); break; + case STT_FILE: log_printf("имя файла\n"); break; + case STT_COMMON: log_printf("общий объект данных\n"); break; + case STT_TLS: log_printf("объект данных локального потока\n"); break; + case STT_NUM: log_printf("количество определенных типов\n"); break; + case STT_GNU_IFUNC: log_printf("объект непрямого кода\n"); break; + default: log_printf("???\n"); break; + } + } } } else { LOG("Таблица символов не найдена!\n"); diff --git a/kernel/tool.c b/kernel/tool.c index c52e4dc..1865f46 100644 --- a/kernel/tool.c +++ b/kernel/tool.c @@ -101,6 +101,14 @@ void tool_reverse_str(char *str) { } } +int tool_strcmp(const char *s1, const char *s2) { + while (*s1 && (*s1 == *s2)) { + s1++; + s2++; + } + return *(const unsigned char *)s1 - *(const unsigned char *)s2; +} + // Преобразование целого числа "i" в системе счисления "base" в строку "buf" void tool_int_to_str(int64_t i, uint8_t base, char *buf) { bool negative = false; From ac3e6705d462d5918c1870062a9262958c1fec09 Mon Sep 17 00:00:00 2001 From: Aren Elchinyan Date: Thu, 1 Aug 2024 15:18:29 +0300 Subject: [PATCH 02/12] =?UTF-8?q?=D0=9D=D0=B5=D0=B1=D0=BE=D0=BB=D1=8C?= =?UTF-8?q?=D1=88=D0=B8=D0=B5=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/version.h | 2 +- kernel/elf.c | 13 ++++++++----- kernel/mod.c | 7 ++++++- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/include/version.h b/include/version.h index a6a0b1e..2d6bd32 100644 --- a/include/version.h +++ b/include/version.h @@ -1,3 +1,3 @@ #define VERSION_MAJOR 0 #define VERSION_MINOR 2 -#define VERSION_BUILD 94 +#define VERSION_BUILD 96 diff --git a/kernel/elf.c b/kernel/elf.c index 92a2c7e..3f91a11 100644 --- a/kernel/elf.c +++ b/kernel/elf.c @@ -9,6 +9,7 @@ #include #include + elf64_header_t *elf64_get_header(void *data) { return (elf64_header_t *)(data); } @@ -70,10 +71,12 @@ void *elf_entry(void *module_bin) { LOG("\t\tОшибка! Модуль неправильно собран!\n"); for (;;) { asm volatile("pause"); } } - elf_parse((elf64_header_t *)module_bin); + void *h = elf_parse((elf64_header_t *)module_bin); + + if (h == NULL) { return NULL; } // Возвращаем указатель на точку входа - return (void *)((uint64_t)elf_header->e_entry + (uint64_t)module_bin); + return (void *)((uint64_t)h + (uint64_t)module_bin); } void import_test( ) { @@ -86,7 +89,7 @@ void *elf_parse(elf64_header_t *head) { if (head->e_ident[0] != ELFMAG0 || head->e_ident[1] != ELFMAG1 || head->e_ident[2] != ELFMAG2 || head->e_ident[3] != ELFMAG3) { LOG("Ошибка: Неправильный формат!\n"); - return -1; + return NULL; } // LOG("Точка входа: 0x%x\n", head->e_entry); @@ -121,7 +124,7 @@ void *elf_parse(elf64_header_t *head) { if (tool_strcmp(string_table + sym->st_name, "import_test") == 0) { log_printf("0x%x\n", head + sym->st_value); void (*imp)( ) = (void *)head + sym->st_value; - *imp = &import_test; + // imp = &import_test; } break; case STT_FUNC: log_printf("объект кода\n"); break; @@ -139,5 +142,5 @@ void *elf_parse(elf64_header_t *head) { LOG("Таблица символов не найдена!\n"); } - return (void *)0; + return (void *)head->e_entry; } \ No newline at end of file diff --git a/kernel/mod.c b/kernel/mod.c index ca2ba6c..6db7e9f 100644 --- a/kernel/mod.c +++ b/kernel/mod.c @@ -117,7 +117,12 @@ void mod_init( ) { continue; } - module_info_t (*module_init)(env_t *env) = (module_info_t(*)(env_t * env)) elf_entry(module_ptr->address); + module_info_t (*module_init)(env_t * env) = (module_info_t(*)(env_t * env)) elf_entry(module_ptr->address); + + if (module_init == NULL) { + LOG("Модуль %s неисправен\n", module_ptr->cmdline); + continue; + } // LOG("\t->Точка входа: 0x%x\n", module_init); From 121c408a6c554d5a073361b36ed333c36308c6d6 Mon Sep 17 00:00:00 2001 From: Aren Elchinyan Date: Thu, 1 Aug 2024 15:24:47 +0300 Subject: [PATCH 03/12] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20=D1=81=D0=BA=D1=80=D0=B8=D0=BF=D1=82=20=D1=81?= =?UTF-8?q?=D0=B8=D0=BD=D1=85=D1=80=D0=BE=D0=BD=D0=B8=D0=B7=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- scripts/github_sync.sh | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 scripts/github_sync.sh diff --git a/README.md b/README.md index e235731..8aac203 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ - Номер карты: 2200 7009 4662 4201 - Номер счета: 40817810400099892231 - БИК: 044525974 -- Банк-получатель: АО «Тинькофф Банк» +- Банк-получатель: АО «Т-Банк» ## Сборка и запуск diff --git a/scripts/github_sync.sh b/scripts/github_sync.sh new file mode 100644 index 0000000..b3ae07b --- /dev/null +++ b/scripts/github_sync.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# URL исходного репозитория +SOURCE_REPO="https://github.com/0Nera/BMOSP" + +# Добавляем исходный репозиторий как удаленный +git remote add source $SOURCE_REPO + +# Получаем все ветки и теги из исходного репозитория +git fetch source + +# Синхронизируем все ветки и теги с исходным репозиторием +for branch in $(git branch -r | grep 'source/' | sed 's/source\///'); do + git checkout -b $branch source/$branch +done + +git push --all origin +git push --tags origin + +# Удаляем удаленный репозиторий +git remote remove source \ No newline at end of file From 5858814e6be36750b408ff85e7c89a6b23fa4d6d Mon Sep 17 00:00:00 2001 From: Aren Elchinyan Date: Thu, 1 Aug 2024 15:25:58 +0300 Subject: [PATCH 04/12] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD=20?= =?UTF-8?q?=D0=BF=D0=B0=D1=80=D1=82=D0=BD=D0=B5=D1=80=20"=D0=9D=D0=9F?= =?UTF-8?q?=D0=9E=20=D0=A2=D0=95-=D0=9E=D0=9D"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8aac203..8907395 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ ## Партнеры -- ООО **"НПО ТЕ-ОН"** +- Синапс ОС ## Помощь проекту From af1d9d80a9d296f3e1d50f240cacb4ea4300d28b Mon Sep 17 00:00:00 2001 From: Aren Elchinyan Date: Mon, 16 Sep 2024 16:58:28 +0300 Subject: [PATCH 05/12] =?UTF-8?q?=D0=9D=D0=B5=D0=B1=D0=BE=D0=BB=D1=8C?= =?UTF-8?q?=D1=88=D0=B8=D0=B5=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/arch.h | 2 +- include/tool.h | 1 + include/version.h | 2 +- kernel/cpu/task.c | 3 ++- kernel/elf.c | 10 +++++----- modlib/types.h | 1 + scripts/pbuild.py | 4 ++-- 7 files changed, 13 insertions(+), 10 deletions(-) diff --git a/include/arch.h b/include/arch.h index c7fd047..6cacd0f 100644 --- a/include/arch.h +++ b/include/arch.h @@ -66,7 +66,7 @@ void arch_init( ); void task_init( ); void task_after_init( ); void task_switch( ); -uint64_t task_new_thread(void (*func)(void *), char *name); +uint64_t task_new_thread(void (*func)(void *), char *name, void *arg); void task_del_current( ); void task_del(uint64_t id); void cpu_init( ); diff --git a/include/tool.h b/include/tool.h index 1974d60..d3759a2 100644 --- a/include/tool.h +++ b/include/tool.h @@ -43,6 +43,7 @@ void tool_memcpy(void *dest, void *src, uint64_t n); void *tool_memset(void *ptr, uint8_t n, uint64_t size); uint64_t tool_strlen(const char *str); void tool_strcpy(char *dest, char *src); +int tool_strcmp(const char *s1, const char *s2); uint64_t tool_starts_with(const char *str, const char *prefix); uint64_t tool_str_contains(const char *str, const char *substr); void tool_format(void (*putc)(char c), const char *format_string, va_list args); diff --git a/include/version.h b/include/version.h index 2d6bd32..06fc20e 100644 --- a/include/version.h +++ b/include/version.h @@ -1,3 +1,3 @@ #define VERSION_MAJOR 0 #define VERSION_MINOR 2 -#define VERSION_BUILD 96 +#define VERSION_BUILD 107 diff --git a/kernel/cpu/task.c b/kernel/cpu/task.c index efda6cb..cb98a10 100644 --- a/kernel/cpu/task.c +++ b/kernel/cpu/task.c @@ -44,7 +44,7 @@ void task_switch( ) { task_switch_asm(last, next); } -uint64_t task_new_thread(void (*func)(void *), char *name) { +uint64_t task_new_thread(void (*func)(void *), char *name, void *arg) { LOG("Выделение потока\n"); uint64_t cr3; @@ -64,6 +64,7 @@ uint64_t task_new_thread(void (*func)(void *), char *name) { stack[--stack_top] = (uint64_t)0; new_task->rsp = (uint64_t)new_task->stack + sizeof(uint64_t) * stack_top; + new_task->rdi = (uint64_t)arg; new_task->cpu_time = 500; new_task->cpu_time_expired = new_task->cpu_time; new_task->id = next_thread_id++; diff --git a/kernel/elf.c b/kernel/elf.c index 3f91a11..b982359 100644 --- a/kernel/elf.c +++ b/kernel/elf.c @@ -8,7 +8,7 @@ #include #include - +#include elf64_header_t *elf64_get_header(void *data) { return (elf64_header_t *)(data); @@ -53,7 +53,7 @@ unsigned long elf64_hash(unsigned char *name) { while (*name) { h = (h << 4) + *name++; // Проверка на overflow - if (g = h & 0xf0000000) h ^= g >> 24; + if (g = (h & 0xf0000000)) h ^= g >> 24; // Ограничение хэша h &= 0xffffffff; } @@ -84,7 +84,7 @@ void import_test( ) { } void *elf_parse(elf64_header_t *head) { - elf64_section_header_t *symtab = NULL; + // elf64_section_header_t *symtab = NULL; if (head->e_ident[0] != ELFMAG0 || head->e_ident[1] != ELFMAG1 || head->e_ident[2] != ELFMAG2 || head->e_ident[3] != ELFMAG3) { @@ -123,8 +123,8 @@ void *elf_parse(elf64_header_t *head) { // log_printf("%u\n", tool_strcmp(string_table + sym->st_name, "import_test")); if (tool_strcmp(string_table + sym->st_name, "import_test") == 0) { log_printf("0x%x\n", head + sym->st_value); - void (*imp)( ) = (void *)head + sym->st_value; - // imp = &import_test; + // void (*imp)( ) = (void *)head + sym->st_value; + // imp = &import_test; } break; case STT_FUNC: log_printf("объект кода\n"); break; diff --git a/modlib/types.h b/modlib/types.h index 842dcd1..54a6bab 100644 --- a/modlib/types.h +++ b/modlib/types.h @@ -120,6 +120,7 @@ typedef struct { uint64_t (*new_thread)(void (*func)(void *), char *name); void (*delete_thread)( ); time_t (*get_time)( ); + module_info_t *ret; } __attribute__((packed)) env_t; #endif // types.h diff --git a/scripts/pbuild.py b/scripts/pbuild.py index cbbb04c..e42f1dd 100644 --- a/scripts/pbuild.py +++ b/scripts/pbuild.py @@ -106,9 +106,9 @@ def create_hdd(IMAGE_NAME): os.system(f"sgdisk {IMAGE_NAME}.hdd -n 1:2048 -t 1:ef00") os.system(f"./limine/limine bios-install {IMAGE_NAME}.hdd") os.system(f"mformat -i {IMAGE_NAME}.hdd@@1M") - os.system(f"mmd -i {IMAGE_NAME}.hdd@@1M ::/mod ::/EFI ::/EFI/BOOT") + os.system(f"mmd -i {IMAGE_NAME}.hdd@@1M ::/EFI ::/EFI/BOOT") os.system(f"mcopy -i {IMAGE_NAME}.hdd@@1M kernel.elf configs/limine.cfg limine/limine-bios.sys ::/") - os.system(f"mcopy -i {IMAGE_NAME}.hdd@@1M modules/bin/* ::/mod") + os.system(f"mcopy -i {IMAGE_NAME}.hdd@@1M iso_root/mod/ ::/") os.system(f"mcopy -i {IMAGE_NAME}.hdd@@1M limine/BOOTX64.EFI limine/BOOTIA32.EFI ::/EFI/BOOT") os.system(f"./limine/limine bios-install {IMAGE_NAME}.hdd") From 89652e9819e71524a9d160e1acde7bbc20998cc5 Mon Sep 17 00:00:00 2001 From: Aren Elchinyan Date: Mon, 16 Sep 2024 17:01:28 +0300 Subject: [PATCH 06/12] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20CI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3ef6ad0..a05173c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,7 +22,7 @@ jobs: - name: install limine run: | - git clone https://git.synapseos.ru/Aren/limine.git --branch=v5.x-branch-binary --depth=1 + git clone https://git.synapseos.ru/mirrors/limine.git --branch=v5.x-branch-binary --depth=1 cd limine && make && cd .. - name: build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 440f5a0..03fda27 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,7 +19,7 @@ jobs: - name: install limine run: | - git clone https://git.synapseos.ru/Aren/limine.git --branch=v5.x-branch-binary --depth=1 + git clone https://git.synapseos.ru/mirrors/limine.git --branch=v5.x-branch-binary --depth=1 cd limine && make && cd .. - name: build From 6d414307dcb9eeb1b2e143081540940f8648207d Mon Sep 17 00:00:00 2001 From: Aren Elchinyan Date: Mon, 16 Sep 2024 18:29:16 +0300 Subject: [PATCH 07/12] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B0=20=D1=81=D0=B1=D0=BE=D1=80=D0=BA=D0=B0=20RAW=20=D0=BE?= =?UTF-8?q?=D0=B1=D1=80=D0=B0=D0=B7=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 1 - run.sh | 4 ++-- scripts/pbuild.py | 18 +----------------- 3 files changed, 3 insertions(+), 20 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 03fda27..b534d17 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -64,7 +64,6 @@ jobs: draft: true files: | ${{ github.workspace }}/rel/kernel.elf - ${{ github.workspace }}/rel/bmosp.hdd ${{ github.workspace }}/rel/bmosp.iso ${{ github.workspace }}/rel/LICENSE diff --git a/run.sh b/run.sh index afab044..5081f45 100755 --- a/run.sh +++ b/run.sh @@ -1,10 +1,10 @@ #!/bin/sh qemu-system-x86_64 -name "БМПОС" -cpu max -m 64M -smp 1 \ -serial file:serial.log \ - -drive file=bmosp.hdd,if=none,id=sata_drive -device ahci \ + -drive file=bmosp.iso,if=none,id=sata_drive -device ahci \ -device virtio-blk-pci,drive=sata_drive \ -rtc base=localtime,clock=host \ - --no-reboot -no-shutdown \ + --no-reboot -no-shutdown -boot d \ -net nic,model=pcnet # AMD PCnet Am79C970 #qemu-system-x86_64 -name "БМПОС" -cpu max -m 1G -smp 1 -hda bmosp.hdd --no-reboot #qemu-system-x86_64 -name "БМПОС" -cpu max -m 1G -smp 1 -cdrom bmosp.iso -boot d --no-reboot diff --git a/scripts/pbuild.py b/scripts/pbuild.py index e42f1dd..1ee7535 100644 --- a/scripts/pbuild.py +++ b/scripts/pbuild.py @@ -91,7 +91,7 @@ def compile_all(): def check_limine(): if not os.path.isdir("limine"): - subprocess.run(["git", "clone", "https://git.synapseos.ru/Aren/limine.git", "--branch=v5.x-branch-binary", "--depth=1"]) + subprocess.run(["git", "clone", "https://git.synapseos.ru/mirrors/limine.git", "--branch=v5.x-branch-binary", "--depth=1"]) else: os.chdir("limine") subprocess.run(["git", "pull"]) @@ -100,19 +100,6 @@ def check_limine(): subprocess.run(["make"]) os.chdir("..") -def create_hdd(IMAGE_NAME): - 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"sgdisk {IMAGE_NAME}.hdd -n 1:2048 -t 1:ef00") - os.system(f"./limine/limine bios-install {IMAGE_NAME}.hdd") - os.system(f"mformat -i {IMAGE_NAME}.hdd@@1M") - os.system(f"mmd -i {IMAGE_NAME}.hdd@@1M ::/EFI ::/EFI/BOOT") - os.system(f"mcopy -i {IMAGE_NAME}.hdd@@1M kernel.elf configs/limine.cfg limine/limine-bios.sys ::/") - os.system(f"mcopy -i {IMAGE_NAME}.hdd@@1M iso_root/mod/ ::/") - os.system(f"mcopy -i {IMAGE_NAME}.hdd@@1M limine/BOOTX64.EFI limine/BOOTIA32.EFI ::/EFI/BOOT") - os.system(f"./limine/limine bios-install {IMAGE_NAME}.hdd") - - def create_iso(IMAGE_NAME): os.system(f"rm -f {IMAGE_NAME}.iso") os.system(f"rm -rf iso_root") @@ -165,7 +152,4 @@ if __name__ == "__main__": print("Создание ISO образа") create_iso("bmosp") - print("Создание HDD образа") - create_hdd("bmosp") - print(f"Не забудьте сохранить изменения! Номер сборки: {major}.{minor}.{build}") From c41fe4a8a5582a823ed88924c60d6b6dab5ac0bc Mon Sep 17 00:00:00 2001 From: Aren Elchinyan Date: Mon, 16 Sep 2024 18:29:44 +0300 Subject: [PATCH 08/12] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D1=91=D0=BD=20?= =?UTF-8?q?=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D1=8C=20TGA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/tga/boot.jpg | Bin 47850 -> 0 bytes modules/tga/boot.tga | Bin 44740 -> 0 bytes modules/tga/build.sh | 19 ----- modules/tga/main.c | 189 ------------------------------------------- 4 files changed, 208 deletions(-) delete mode 100644 modules/tga/boot.jpg delete mode 100644 modules/tga/boot.tga delete mode 100755 modules/tga/build.sh delete mode 100644 modules/tga/main.c diff --git a/modules/tga/boot.jpg b/modules/tga/boot.jpg deleted file mode 100644 index f7bade6a8a2712433bcf8e95a8bd9c23750e2902..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47850 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 diff --git a/modules/tga/build.sh b/modules/tga/build.sh deleted file mode 100755 index 4136829..0000000 --- a/modules/tga/build.sh +++ /dev/null @@ -1,19 +0,0 @@ -#/bin/sh -echo "Название: TGA" -echo "Лицензия: Публичное достояние" - -CC=${CC:-gcc} -ARCH_FLAGS="-fno-stack-protector -ffreestanding -O0 -g -fPIC -static -nostdlib " - -if [ -d "../../sdk" ]; then - CC="../../sdk/bin/x86_64-elf-gcc" -fi - - -$CC $ARCH_FLAGS -I../../modlib -finput-charset=UTF-8 -fexec-charset=cp1251 -c main.c -o tga.o -$CC $ARCH_FLAGS -Wl,--entry=init,--build-id=none -T ../link.ld tga.o -L../../modlib/lib/ -lmod -o tga.ko - -cp boot.jpg ../bin/ -cp boot.tga ../bin/ -cp tga.ko ../bin/ -echo "Сборка завершена, файл: tga.ko" diff --git a/modules/tga/main.c b/modules/tga/main.c deleted file mode 100644 index 4661396..0000000 --- a/modules/tga/main.c +++ /dev/null @@ -1,189 +0,0 @@ -#include - -#define TGA_ERR( ) log_printf("Ошибка декодирования TGA на строчке: %u\n", __LINE__); - -typedef struct { - unsigned char magic1; // должно быть нулевым - unsigned char colormap; // должно быть нулевым - unsigned char encoding; // должно быть 2 - unsigned short cmaporig, cmaplen; // должны быть нулевыми - unsigned char cmapent; // должно быть нулевым - unsigned short x; // должно быть нулевым - unsigned short y; // высота изображения - unsigned short h; // высота изображения - unsigned short w; // ширина изображения - unsigned char bpp; // должно быть 32 - unsigned char pixeltype; // должно быть 40 -} __attribute__((packed)) tga_header_t; - -static unsigned int *tga_parse(unsigned char *ptr, int size) { - unsigned int *data; - int i, j, k, x, y, w = (ptr[13] << 8) + ptr[12], h = (ptr[15] << 8) + ptr[14], o = (ptr[11] << 8) + ptr[10]; - int m = ((ptr[1] ? (ptr[7] >> 3) * ptr[5] : 0) + 18); - - if (w < 1 || h < 1) return NULL; - - data = (unsigned int *)alloc((w * h + 2) * sizeof(unsigned int)); - if (!data) { return NULL; } - memset(data, 0, (w * h + 2) * sizeof(unsigned int)); - - switch (ptr[2]) { - case 1: - if (ptr[6] != 0 || ptr[4] != 0 || ptr[3] != 0 || (ptr[7] != 24 && ptr[7] != 32)) { - TGA_ERR( ); - free(data); - return NULL; - } - for (y = i = 0; y < h; y++) { - k = ((!o ? h - y - 1 : y) * w); - for (x = 0; x < w; x++) { - j = ptr[m + k++] * (ptr[7] >> 3) + 18; - data[2 + i++] = - ((ptr[7] == 32 ? ptr[j + 3] : 0xFF) << 24) | (ptr[j + 2] << 16) | (ptr[j + 1] << 8) | ptr[j]; - } - } - break; - case 2: - if (ptr[5] != 0 || ptr[6] != 0 || ptr[1] != 0 || (ptr[16] != 24 && ptr[16] != 32)) { - TGA_ERR( ); - free(data); - return NULL; - } - for (y = i = 0; y < h; y++) { - j = ((!o ? h - y - 1 : y) * w * (ptr[16] >> 3)); - for (x = 0; x < w; x++) { - data[2 + i++] = - ((ptr[16] == 32 ? ptr[j + 3] : 0xFF) << 24) | (ptr[j + 2] << 16) | (ptr[j + 1] << 8) | ptr[j]; - j += ptr[16] >> 3; - } - } - break; - case 9: - if (ptr[6] != 0 || ptr[4] != 0 || ptr[3] != 0 || (ptr[7] != 24 && ptr[7] != 32)) { - TGA_ERR( ); - free(data); - return NULL; - } - y = i = 0; - for (x = 0; x < w * h && m < size;) { - k = ptr[m++]; - if (k > 127) { - k -= 127; - x += k; - j = ptr[m++] * (ptr[7] >> 3) + 18; - while (k--) { - if (!(i % w)) { - i = ((!o ? h - y - 1 : y) * w); - y++; - } - data[2 + i++] = ((ptr[7] == 32 ? ptr[j + 3] : 0xFF) << 24) | (ptr[j + 2] << 16) | - (ptr[j + 1] << 8) | ptr[j]; - } - } else { - k++; - x += k; - while (k--) { - j = ptr[m++] * (ptr[7] >> 3) + 18; - if (!(i % w)) { - i = ((!o ? h - y - 1 : y) * w); - y++; - } - data[2 + i++] = ((ptr[7] == 32 ? ptr[j + 3] : 0xFF) << 24) | (ptr[j + 2] << 16) | - (ptr[j + 1] << 8) | ptr[j]; - } - } - } - break; - case 10: - if (ptr[5] != 0 || ptr[6] != 0 || ptr[1] != 0 || (ptr[16] != 24 && ptr[16] != 32)) { - TGA_ERR( ); - free(data); - return NULL; - } - y = i = 0; - for (x = 0; x < w * h && m < size;) { - k = ptr[m++]; - if (k > 127) { - k -= 127; - x += k; - while (k--) { - if (!(i % w)) { - i = ((!o ? h - y - 1 : y) * w); - y++; - } - data[2 + i++] = ((ptr[16] == 32 ? ptr[m + 3] : 0xFF) << 24) | (ptr[m + 2] << 16) | - (ptr[m + 1] << 8) | ptr[m]; - } - m += ptr[16] >> 3; - } else { - k++; - x += k; - while (k--) { - if (!(i % w)) { - i = ((!o ? h - y - 1 : y) * w); - y++; - } - data[2 + i++] = ((ptr[16] == 32 ? ptr[m + 3] : 0xFF) << 24) | (ptr[m + 2] << 16) | - (ptr[m + 1] << 8) | ptr[m]; - m += ptr[16] >> 3; - } - } - } - break; - default: { - TGA_ERR( ); - free(data); - return NULL; - } - } - data[0] = w; - data[1] = h; - return data; -} - -static void *handler(uint64_t func) { - switch (func) { - case 0: return tga_parse; - - default: return NULL; - } -} - -module_info_t __attribute__((section(".minit"))) init(env_t *env) { - init_env(env); - - module_info_t *boot_tga = get_module("[BOOTIMG]"); - - if (boot_tga != NULL) { -#if 0 - framebuffer_t screen = alloc_framebuffer( ); - uint32_t *screen_buf = screen.address; - - uint32_t *img = tga_parse(boot_tga->data, boot_tga->data_size); - uint32_t width = img[0]; - uint32_t height = img[1]; - uint32_t *img_data = (uint32_t *)img + 2; - - for (uint32_t w = 0; w < width; w++) { - for (uint32_t h = 0; h < height; h++) { - if (*img_data == 0x013220) { - *img_data++; - continue; - } - screen_buf[w * height + h] = *img_data++; - } - } -#endif - } - - return (module_info_t){ .name = (char *)"[MEDIA][TGA]", - .message = (char *)"Отрисовка TGA изображений", - .type = 0, - .data_size = 0, - .data = (void *)0, - .err_code = 0, - .module_id = 0, - .irq = 0, - .irq_handler = 0, - .get_func = handler }; -} From cce42f26e667ac05e2ec85b010942bf08661fd87 Mon Sep 17 00:00:00 2001 From: Aren Elchinyan Date: Mon, 16 Sep 2024 18:35:06 +0300 Subject: [PATCH 09/12] =?UTF-8?q?=D0=9C=D0=BE=D0=B4=D1=83=D0=BB=D1=8C=20SI?= =?UTF-8?q?MD=20=D0=B2=D1=8B=D0=BD=D0=B5=D1=81=D0=B5=D0=BD=20=D0=B2=20?= =?UTF-8?q?=D1=8F=D0=B4=D1=80=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- configs/limine.cfg | 3 --- kernel/cpu/cpu.c | 21 +++++++++++++++++++++ modules/simd/build.sh | 17 ----------------- modules/simd/main.c | 43 ------------------------------------------- 4 files changed, 21 insertions(+), 63 deletions(-) delete mode 100755 modules/simd/build.sh delete mode 100644 modules/simd/main.c diff --git a/configs/limine.cfg b/configs/limine.cfg index 574c283..55b7c71 100644 --- a/configs/limine.cfg +++ b/configs/limine.cfg @@ -19,9 +19,6 @@ TERM_WALLPAPER=boot:///mod/boot.jpg MODULE_PATH=boot:///mod/pci_vendors.txt MODULE_CMDLINE=[PCI][DATA][VENDORS] - MODULE_PATH=boot:///mod/simd.ko - MODULE_CMDLINE=[MOD]simd.ko - MODULE_PATH=boot:///mod/pci_data.ko MODULE_CMDLINE=[MOD]pci_data.ko diff --git a/kernel/cpu/cpu.c b/kernel/cpu/cpu.c index a3e4ada..a179c08 100644 --- a/kernel/cpu/cpu.c +++ b/kernel/cpu/cpu.c @@ -142,4 +142,25 @@ void cpu_init( ) { if ((edx >> 5) & 1) { LOG("Программный терморегулятор (STC) поддерживается!\n"); } brandname( ); + + + uint32_t eax, ebx, ecx, edx; + cpuid(1, &eax, &ebx, &ecx, &edx); + + if ((edx >> 0) & 1) { + asm volatile("finit"); + LOG("FPU(x87) поддерживается!\n"); + } + + if ((edx >> 23) & 1) { LOG("MMX поддерживается!\n"); } + + if ((edx >> 25) & 1) { + LOG("SSE2 поддерживается!\n"); + LOG("Адрес региона fxsave 0x%x\n", &fxsave_region); + asm volatile(" fxsave %0 " ::"m"(fxsave_region)); + uint32_t sse_version = (ecx >> 25) & 0x7; + LOG("SSE%u включен\n", sse_version); + } + + if ((ecx >> 28) & 1) { LOG("AVX поддерживается!\n"); } } \ No newline at end of file diff --git a/modules/simd/build.sh b/modules/simd/build.sh deleted file mode 100755 index 78614a3..0000000 --- a/modules/simd/build.sh +++ /dev/null @@ -1,17 +0,0 @@ -#/bin/sh -echo "Название: SIMD" -echo "Лицензия: Публичное достояние" - -CC=${CC:-gcc} -ARCH_FLAGS="-fno-stack-protector -ffreestanding -O0 -g -fPIC -static -nostdlib " - -if [ -d "../../sdk" ]; then - CC="../../sdk/bin/x86_64-elf-gcc" -fi - - -$CC $ARCH_FLAGS -I../../modlib -finput-charset=UTF-8 -fexec-charset=cp1251 -c main.c -o simd.o -$CC $ARCH_FLAGS -Wl,--entry=init,--build-id=none -T ../link.ld simd.o -L../../modlib/lib/ -lmod -o simd.ko - -cp simd.ko ../bin/ -echo "Сборка завершена, файл: simd.ko" diff --git a/modules/simd/main.c b/modules/simd/main.c deleted file mode 100644 index c27f665..0000000 --- a/modules/simd/main.c +++ /dev/null @@ -1,43 +0,0 @@ -#include - -static char fxsave_region[512] __attribute__((aligned(16))); - -static inline void cpuid(uint32_t leaf, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) { - asm volatile("cpuid" : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) : "a"(leaf)); -} - -module_info_t __attribute__((section(".minit"))) init(env_t *env) { - init_env(env); - - uint32_t eax, ebx, ecx, edx; - cpuid(1, &eax, &ebx, &ecx, &edx); - - if ((edx >> 0) & 1) { - asm volatile("finit"); - log_printf("FPU(x87) поддерживается!\n"); - } - - if ((edx >> 23) & 1) { log_printf("MMX поддерживается!\n"); } - - if ((edx >> 25) & 1) { - log_printf("SSE2 поддерживается!\n"); - log_printf("Адрес региона fxsave 0x%x\n", &fxsave_region); - asm volatile(" fxsave %0 " ::"m"(fxsave_region)); - uint32_t sse_version = (ecx >> 25) & 0x7; - log_printf("SSE%u включен\n", sse_version); - } - - if ((ecx >> 28) & 1) { log_printf("AVX поддерживается!\n"); } - - return (module_info_t){ .name = (char *)"SIMD", - .message = (char *)"SIMD инструкции", - .type = 0, - .data_size = 0, - .data = (void *)0, - .err_code = 0, - .module_id = 0, - .irq = 0, - .irq_handler = 0, - .get_func = 0, - .after_init = 0 }; -} \ No newline at end of file From 9a56ff681a4148f83de77d7b484b5bd507e9b8e4 Mon Sep 17 00:00:00 2001 From: Aren Elchinyan Date: Mon, 16 Sep 2024 21:42:02 +0300 Subject: [PATCH 10/12] =?UTF-8?q?=D0=A3=D1=81=D0=BA=D0=BE=D1=80=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B2=D1=8B=D0=B2=D0=BE=D0=B4=D0=B0=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D1=8D=D0=BA=D1=80=D0=B0=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/arch.h | 22 +++++++++++++++++++++- include/log.h | 1 + include/tool.h | 1 + kernel/fb.c | 7 ++++--- kernel/log.c | 30 +++++++++++------------------- kernel/tool.c | 11 +++++++++++ 6 files changed, 49 insertions(+), 23 deletions(-) diff --git a/include/arch.h b/include/arch.h index 6cacd0f..a880637 100644 --- a/include/arch.h +++ b/include/arch.h @@ -77,7 +77,7 @@ void idt_set_int(uint8_t vector, int_entry_t handler); uint64_t arch_get_tick_b( ); uint64_t arch_get_tick_l( ); uint64_t arch_get_tick( ); -void com_write_byte(uint8_t byte); +void com_write_byte(char byte); void com_write_bytes(char *c, uint64_t n); time_t rtc_get_time( ); @@ -105,6 +105,26 @@ static inline void io_wait( ) { outb(0x80, 0); } +static inline void *hal_memset(void *s, char c, int64_t count) { + int64_t d0, d1; + asm volatile("rep\n\t" + "stosb" + : "=&c"(d0), "=&D"(d1) + : "a"(c), "1"(s), "0"(count) + : "memory"); + return s; +} + +static inline void *hal_memset_32(void *s, uint32_t c, int64_t count) { + int64_t d0, d1; + asm volatile("rep\n\t" + "stosl" + : "=&c"(d0), "=&D"(d1) + : "a"(c), "1"(s), "0"(count) + : "memory"); + return s; +} + #define GET_TICK_BIG arch_get_tick_b( ) #define GET_TICK_lOW arch_get_tick_l( ) diff --git a/include/log.h b/include/log.h index 376be91..859a655 100644 --- a/include/log.h +++ b/include/log.h @@ -21,6 +21,7 @@ void log_init( ); void log_init_mem( ); void log_printf(char *str, ...); +char *utf8cp(char *str); #ifndef NO_DEBUG #define LOG(...) \ diff --git a/include/tool.h b/include/tool.h index d3759a2..9abc2c5 100644 --- a/include/tool.h +++ b/include/tool.h @@ -41,6 +41,7 @@ static inline void pause( ) { void tool_memcpy(void *dest, void *src, uint64_t n); void *tool_memset(void *ptr, uint8_t n, uint64_t size); +void tool_memmove(void *dest, void *src, uint64_t n); uint64_t tool_strlen(const char *str); void tool_strcpy(char *dest, char *src); int tool_strcmp(const char *s1, const char *s2); diff --git a/kernel/fb.c b/kernel/fb.c index 867f00e..04b4b0f 100644 --- a/kernel/fb.c +++ b/kernel/fb.c @@ -53,16 +53,17 @@ void fb_init( ) { for (uint64_t i = 0; i < width * height; i++) { fb_addr[i] = background; } - LOG("0x%x %ux%u\n", fb_addr, width, height); - if (framebuffer_response->framebuffer_count == 1) { return; } +#ifdef DEBUG_FB LOG("Инициализация дополнительных: %u мониторов\n", framebuffer_response->framebuffer_count); - +#endif for (uint64_t i = 1; i < framebuffer_response->framebuffer_count; i++) { struct limine_framebuffer *framebuffer = framebuffer_response->framebuffers[i]; uint32_t *framebuffer_addr = (uint32_t *)framebuffer->address; +#ifdef DEBUG_FB LOG("[%u]->0x%x %ux%u\n", i, framebuffer->address, framebuffer->width, framebuffer->height); +#endif for (uint64_t ij = 0; ij < width * height; ij++) { framebuffer_addr[ij] = background; } } } diff --git a/kernel/log.c b/kernel/log.c index 5d66210..a465332 100644 --- a/kernel/log.c +++ b/kernel/log.c @@ -34,8 +34,9 @@ static inline uint32_t analyze(char glyth) { // Вывод символа по координатам static void print_char(uint64_t x, uint64_t y, char glyth) { + uint32_t glyth_index = analyze(glyth); for (uint64_t i = 0; i < FONT_6X8_SLIM_CHAR_HEIGHT; i++) { - fb_print_bits(x, y + i, font_6x8_slim[analyze(glyth) + i]); + fb_print_bits(x, y + i, font_6x8_slim[glyth_index + i]); } } @@ -45,7 +46,10 @@ void log_dump_buffer( ) { static void log_fb_putchar(char c) { if (c == '\0' || fb_init_status < 1) { return; } - if (c == '\t') { + + if (c == '\r') { + log_buffer[--buf_pos] = 0; + } else if (c == '\t') { fb_pos_x += FONT_6X8_SLIM_CHAR_WIDTH * 4; } else if (c == '\n') { fb_pos_x = 4; @@ -58,12 +62,8 @@ static void log_fb_putchar(char c) { if (fb_pos_y + FONT_6X8_SLIM_CHAR_HEIGHT >= SCREEN_HEIGHT) { // Дошли до нижнего края экрана - while (log_buffer[0] != '\n') { - for (uint64_t i = 0; i < buf_max - 1; i++) { log_buffer[i] = log_buffer[i + 1]; } - buf_pos--; - } - for (uint64_t i = 0; i < buf_max - 1; i++) { log_buffer[i] = log_buffer[i + 1]; } - buf_pos--; + while (log_buffer[0] != '\n') { tool_memmove(log_buffer, log_buffer + 1, --buf_pos); } + tool_memmove(log_buffer, log_buffer + 1, --buf_pos); redraw_screen( ); return; } @@ -75,7 +75,7 @@ static void log_fb_putchar(char c) { void redraw_screen( ) { // Перерисовка экрана - for (uint64_t i = 0; i < SCREEN_WIDTH * SCREEN_HEIGHT; i++) { SCREEN_BUFFER[i] = DARK_GREEN; } + hal_memset_32(SCREEN_BUFFER, DARK_GREEN, SCREEN_WIDTH * SCREEN_HEIGHT); fb_pos_x = 4; fb_pos_y = 0; @@ -87,8 +87,6 @@ void log_putchar(char c) { log_buffer[buf_pos] = c; com_write_byte(c); - log_buffer[buf_pos] = c; - if (buf_pos + 1 == buf_max) { // Смещение буфера на 1 символ влево for (uint64_t i = 0; i < buf_max - 1; i++) { log_buffer[i] = log_buffer[i + 1]; } @@ -109,24 +107,18 @@ void log_printf(char *str, ...) { va_list args; va_start(args, str); tool_format(&log_putchar, str, args); + lock_release(log_lock); va_end(args); } void log_init_mem( ) { LOCK(log_lock); - if (fb_init_status < 1) { - LOG("Нет доступных фреймбуфферов для вывода\n"); - return; - } - - LOG("Полная инициализация отладчика занимает %u килобайт озу\n", - (((SCREEN_WIDTH - 4) / FONT_WIDTH) * (SCREEN_HEIGHT / FONT_HEIGHT)) / 1024); - log_buffer = mem_alloc(((SCREEN_WIDTH - 4) / FONT_WIDTH) * (SCREEN_HEIGHT / FONT_HEIGHT)); tool_memcpy(log_buffer, start_buffer, buf_max); buf_max = ((SCREEN_WIDTH - 4) / FONT_WIDTH) * (SCREEN_HEIGHT / FONT_HEIGHT); LOG("Размер буффера: %u символов\n", buf_max); + LOG("%ux%u\n", width, height); redraw_screen( ); lock_release(log_lock); } diff --git a/kernel/tool.c b/kernel/tool.c index 1865f46..a91c59d 100644 --- a/kernel/tool.c +++ b/kernel/tool.c @@ -23,6 +23,17 @@ void *tool_memset(void *ptr, uint8_t n, uint64_t size) { return ptr; } +void tool_memmove(void *dest, void *src, uint64_t n) { + unsigned char *cdest = (unsigned char *)dest; + unsigned char *csrc = (unsigned char *)src; + + if (cdest < csrc) { + for (uint64_t i = 0; i < n; i++) { cdest[i] = csrc[i]; } + } else { + for (uint64_t i = n; i > 0; i--) { cdest[i - 1] = csrc[i - 1]; } + } +} + uint64_t tool_strlen(const char *str) { uint64_t length = 0; while (*str) { From 5175bba9354443e24f46925e2a9c6f3c78f0d68f Mon Sep 17 00:00:00 2001 From: Aren Elchinyan Date: Mon, 16 Sep 2024 21:42:47 +0300 Subject: [PATCH 11/12] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D1=85=D0=BE?= =?UTF-8?q?=D0=B4=20=D0=BD=D0=B0=20=D0=BD=D0=BE=D0=B2=D1=8B=D0=B9=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +-- build.sh | 4 ++-- include/sys.h | 4 +++- include/version.h | 2 +- kernel/cpu/com.c | 2 +- kernel/cpu/cpu.c | 5 +---- kernel/cpu/task.c | 2 ++ kernel/elf.c | 23 ++++++++++++++++++-- kernel/mem.c | 15 ++++++++++++- kernel/mod.c | 45 ++++++++++++--------------------------- kernel/sys.c | 3 ++- modlib/lib/system.c | 3 +++ modules/cpubench/main.c | 25 +++++++++++----------- modules/helloworld/main.c | 25 +++++++++++----------- modules/imfs/main.c | 28 ++++++++++++------------ modules/ios/main.c | 25 +++++++++++----------- modules/pci/main.c | 29 ++++++++++++++----------- modules/pci/pci_data.c | 30 +++++++++++++++----------- modules/ps2/main.c | 23 ++++++++++---------- scripts/pbuild.py | 6 +++--- 20 files changed, 168 insertions(+), 134 deletions(-) diff --git a/.gitignore b/.gitignore index cb83d58..15fdbec 100644 --- a/.gitignore +++ b/.gitignore @@ -5,8 +5,7 @@ limine/ ovmf/ iso_root/ output/ -sdk/ -_sdk/ +sdk*/ *.so *.o *.ko diff --git a/build.sh b/build.sh index cf81a5f..748859e 100755 --- a/build.sh +++ b/build.sh @@ -2,6 +2,8 @@ dos2unix *.sh +python3 scripts/pbuild.py + cd modlib/lib/ dos2unix build.sh chmod +x build.sh @@ -22,5 +24,3 @@ for dir in */; do done cd .. - -python3 scripts/pbuild.py \ No newline at end of file diff --git a/include/sys.h b/include/sys.h index e9c38b5..64f5eb7 100644 --- a/include/sys.h +++ b/include/sys.h @@ -62,6 +62,7 @@ typedef struct { void *irq_handler; // Адрес обработчика прерываний void *(*get_func)(uint64_t id); void (*after_init)( ); + void *env; // env_t } __attribute__((packed)) module_info_t; typedef struct { @@ -76,9 +77,10 @@ typedef struct { sys_info_t *(*get_info)( ); module_info_t *(*get_module)(char *module_id); module_info_t *(*mod_list_get)(uint64_t *count); - uint64_t (*new_thread)(void (*func)(void *), char *name); + uint64_t (*new_thread)(void (*func)(void *), char *name, void *arg); void (*delete_thread)( ); time_t (*get_time)( ); + module_info_t *ret; } __attribute__((packed)) env_t; env_t *sys_install(env_t *module); diff --git a/include/version.h b/include/version.h index 06fc20e..2877895 100644 --- a/include/version.h +++ b/include/version.h @@ -1,3 +1,3 @@ #define VERSION_MAJOR 0 #define VERSION_MINOR 2 -#define VERSION_BUILD 107 +#define VERSION_BUILD 162 diff --git a/kernel/cpu/com.c b/kernel/cpu/com.c index 020db0c..907c2d0 100644 --- a/kernel/cpu/com.c +++ b/kernel/cpu/com.c @@ -12,7 +12,7 @@ static inline int com_is_transmit_empty(uint16_t com) { return inb(com + 5) & 0x20; } -void com_write_byte(uint8_t byte) { +void com_write_byte(char byte) { while (!com_is_transmit_empty(0x3F8)) {} outb(0x3F8, byte); diff --git a/kernel/cpu/cpu.c b/kernel/cpu/cpu.c index a179c08..23e31ec 100644 --- a/kernel/cpu/cpu.c +++ b/kernel/cpu/cpu.c @@ -14,6 +14,7 @@ #include static bool acpi_msrs_support = false; +static char fxsave_region[512] __attribute__((aligned(16))); static void cpuid(uint32_t leaf, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) { asm volatile("cpuid" : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) : "a"(leaf)); @@ -143,8 +144,6 @@ void cpu_init( ) { brandname( ); - - uint32_t eax, ebx, ecx, edx; cpuid(1, &eax, &ebx, &ecx, &edx); if ((edx >> 0) & 1) { @@ -152,8 +151,6 @@ void cpu_init( ) { LOG("FPU(x87) поддерживается!\n"); } - if ((edx >> 23) & 1) { LOG("MMX поддерживается!\n"); } - if ((edx >> 25) & 1) { LOG("SSE2 поддерживается!\n"); LOG("Адрес региона fxsave 0x%x\n", &fxsave_region); diff --git a/kernel/cpu/task.c b/kernel/cpu/task.c index cb98a10..1003743 100644 --- a/kernel/cpu/task.c +++ b/kernel/cpu/task.c @@ -121,9 +121,11 @@ void task_del_current( ) { prev->next = next; next->last = prev; + LOG("Очистка потока ID: %u, %s\n", current_task->id, current_task->id_str); mem_free(current_task->stack); mem_free(current_task); + LOG("Смена ID: %u, %s\n", next->id, next->id_str); current_task = next; if (full_init) { task_switch( ); } } diff --git a/kernel/elf.c b/kernel/elf.c index b982359..5851038 100644 --- a/kernel/elf.c +++ b/kernel/elf.c @@ -107,26 +107,40 @@ void *elf_parse(elf64_header_t *head) { } if (symtab_section && string_table) { +#ifdef DEBUG_ELF LOG("\nТаблица символов:\n"); LOG("%s %s %s %s\n", "Индекс", "Значение", "Размер", "Наименование"); +#endif int num_symbols = symtab_section->sh_size / symtab_section->sh_entsize; for (int i = 0; i < num_symbols; i++) { elf64_sym_t *sym = elf64_get_symval(head, symtab_section - elf64_sheader(head), i); if (sym) { +#ifdef DEBUG_ELF LOG("%6u %8x %6x %18s ", i, sym->st_value, sym->st_size, string_table + sym->st_name); +#endif switch (ELF64_ST_TYPE(sym->st_info)) { - case STT_NOTYPE: log_printf("без типа\n"); break; + case STT_NOTYPE: + +#ifdef DEBUG_ELF + log_printf("без типа\n"); +#endif + break; case STT_OBJECT: +#ifdef DEBUG_ELF log_printf("объект данных\n"); +#endif if (!(string_table + sym->st_name)) { break; } // log_printf("%u\n", tool_strcmp(string_table + sym->st_name, "import_test")); if (tool_strcmp(string_table + sym->st_name, "import_test") == 0) { +#ifdef DEBUG_ELF log_printf("0x%x\n", head + sym->st_value); +#endif // void (*imp)( ) = (void *)head + sym->st_value; // imp = &import_test; } break; +#ifdef DEBUG_ELF case STT_FUNC: log_printf("объект кода\n"); break; case STT_SECTION: log_printf("символ раздела\n"); break; case STT_FILE: log_printf("имя файла\n"); break; @@ -134,7 +148,12 @@ void *elf_parse(elf64_header_t *head) { case STT_TLS: log_printf("объект данных локального потока\n"); break; case STT_NUM: log_printf("количество определенных типов\n"); break; case STT_GNU_IFUNC: log_printf("объект непрямого кода\n"); break; - default: log_printf("???\n"); break; +#endif + default: +#ifdef DEBUG_ELF + log_printf("???\n"); +#endif + break; } } } diff --git a/kernel/mem.c b/kernel/mem.c index c0d6ef7..139d899 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -51,9 +51,11 @@ static uint64_t mmmap_count = 0; extern task_t *current_task; extern uint64_t full_init; +#ifdef DEBUG_MEM static const char memory_types[8][82] = { "Доступно", "Зарезервировано", "ACPI, можно освободить", "ACPI NVS", "Плохая память", "Загрузчик, можно освободить", "Ядро и модули", "Буфер кадра" }; +#endif static struct limine_memmap_response *memmap_response; @@ -63,6 +65,7 @@ void mem_dump_memory( ) { mem_entry_t *curr = first_node; while (curr) { +#ifdef DEBUG_MEM if (curr->next) { LOG("->0x%x | %u мегабайт | %s | 0x%x | поток %u\n", &curr->data, (curr->size) / 1024 / 1024, curr->free ? memory_types[0] : memory_types[1], curr->next, curr->task_id); @@ -70,6 +73,7 @@ void mem_dump_memory( ) { LOG("->0x%x | %u мегабайт | %s | поток %u | Это последний блок\n", &curr->data, (curr->size) / 1024 / 1024, curr->free ? memory_types[0] : memory_types[1], curr->task_id); } +#endif curr = curr->next; } } @@ -284,8 +288,9 @@ void mem_init( ) { mmmap_count = memmap_response->entry_count; struct limine_memmap_entry **mmaps = memmap_response->entries; +#ifdef DEBUG_MEM LOG("Записей в карте памяти: %u\n", memmap_response->entry_count); - +#endif // Обработка каждой записи в карте памяти for (uint64_t i = 0; i < mmmap_count; i++) { available += mmaps[i]->length; @@ -293,9 +298,11 @@ void mem_init( ) { // LOG("\t%d: 0x%x\tдлина: 0x%x\tтип: %s\n", i + 1, mmaps[i]->base, mmaps[i]->length, // memory_types[mmaps[i]->type]); if (mmaps[i]->type == LIMINE_MEMMAP_FRAMEBUFFER) { +#ifdef DEBUG_MEM LOG("На видеопамять BIOS/UEFI выделено: %u мегабайт + %u " "килобайт\n", mmaps[i]->length / 1024 / 1024, (mmaps[i]->length / 1024) % 1024); +#endif } if (!(mmaps[i]->type == LIMINE_MEMMAP_USABLE)) { continue; } @@ -330,20 +337,26 @@ void mem_init( ) { for (uint64_t t = 0; t < mmaps[i]->length; t += BLOCK_SIZE) { mem_frame_free((void *)mmaps[i]->base + t, 1); } } +#ifdef DEBUG_MEM LOG("%u / %u блоков доступно\n", bitmap_available, bitmap_limit); LOG("Размер битовой карты: %u\n", bitmap_size); +#endif alloc_init(mem_frame_alloc(1024), 1024 * BLOCK_SIZE); +#ifdef DEBUG_MEM LOG("%u мегабайт выделено в динамичную память\n", (256 * 16 * BLOCK_SIZE + BLOCK_SIZE) / 1024 / 1024); +#endif // Выделяем по 4 мегабайта в аллокатор динамичной памяти for (uint64_t i = 0; i < 32; i += 8) { mem_add_block(mem_frame_alloc(1024), 1024 * BLOCK_SIZE); } mem_merge_all_blocks( ); mem_dump_memory( ); +#ifdef DEBUG_MEM LOG("%u МБ объем доступной памяти, %u МБ объем виртуальной памяти\n", (bitmap_available * BLOCK_SIZE) / 1024 / 1024, available / 1024 / 1024); LOG("%u / %u блоков доступно\n", bitmap_available, bitmap_limit); +#endif } \ No newline at end of file diff --git a/kernel/mod.c b/kernel/mod.c index 6db7e9f..8668e3e 100644 --- a/kernel/mod.c +++ b/kernel/mod.c @@ -24,7 +24,7 @@ module_info_t *module_list = NULL; static char *graphics_module_message = "Графический модуль-объект"; static char *other_module_message = "Неизвестный тип модуля"; -static env_t main_env; +static env_t *main_env = NULL; void *bootpng_ptr; uint64_t bootpng_size; @@ -49,7 +49,7 @@ void mod_after_init( ) { for (uint64_t i = 0; i < modules_count; i++) { if (module_list[i].after_init != 0) { LOG("%s.after_init( );\n", module_list[i].name); - task_new_thread(module_list[i].after_init, module_list[i].name); + task_new_thread(module_list[i].after_init, module_list[i].name, NULL); } } } @@ -125,37 +125,20 @@ void mod_init( ) { } // LOG("\t->Точка входа: 0x%x\n", module_init); + main_env = (env_t *)mem_alloc(sizeof(env_t)); + tool_memset(main_env, 0, sizeof(env_t)); + main_env->offset = (uint64_t)module_ptr->address; - main_env.offset = (uint64_t)module_ptr->address; - - sys_install(&main_env); - - uint64_t id = task_new_thread((void *)1, module_list[i].name); - - module_info_t ret = module_init(&main_env); - LOG("\t->%s\n", ret.message); - - task_del(id); - - module_list[modules_count].name = ret.name; - module_list[modules_count].message = ret.message; - 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].after_init = ret.after_init; - - if (module_list[modules_count].after_init) { - task_new_thread(module_list[modules_count].after_init, module_list[modules_count].name); - } - - if (ret.irq != 0) { - if (ret.irq_handler != 0) { - LOG("Установлен обработчик прерывания [%u] по адресу 0x%x в модуле %s\n", ret.irq, ret.irq_handler, - ret.name); - idt_set_int(ret.irq, ret.irq_handler); - } - } + sys_install(main_env); + uint64_t id = task_new_thread((void (*)(void *))module_init, module_list[i].name, main_env); + module_list[modules_count].env = (void *)main_env; + module_list[modules_count].name = 0; + module_list[modules_count].message = 0; + module_list[modules_count].data_size = 0; + module_list[modules_count].data = 0; + module_list[modules_count].get_func = 0; + module_list[modules_count].after_init = 0; modules_count++; } LOG("Модулей обработано: %u\n", modules_count); diff --git a/kernel/sys.c b/kernel/sys.c index c3d563f..de928f7 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -60,9 +60,10 @@ env_t *sys_install(env_t *module) { module->get_info = &sys_get_info; module->get_module = &sys_get_module; module->mod_list_get = &mod_list_get; - module->new_thread = &task_new_thread; + module->new_thread = task_new_thread; module->delete_thread = &task_del_current; module->get_time = &rtc_get_time; + module->ret = NULL; return module; } diff --git a/modlib/lib/system.c b/modlib/lib/system.c index 69a8372..8c15e32 100644 --- a/modlib/lib/system.c +++ b/modlib/lib/system.c @@ -25,6 +25,9 @@ time_t (*get_time)( ); uint64_t offset; void init_env(env_t *loader_env) { + if (loader_env == NULL) { + for (;;) {} + } offset = loader_env->offset; log_printf = loader_env->log_printf; alloc = loader_env->alloc; diff --git a/modules/cpubench/main.c b/modules/cpubench/main.c index 4a314b1..4ae91dc 100644 --- a/modules/cpubench/main.c +++ b/modules/cpubench/main.c @@ -57,7 +57,7 @@ static void cpu_info( ) { log_printf(" Узлы на процессор: %u\n", nodes_per_processor); } -module_info_t __attribute__((section(".minit"))) init(env_t *env) { +void __attribute__((section(".minit"))) init(env_t *env) { uint32_t eax, ebx, ecx, edx; init_env(env); @@ -77,15 +77,16 @@ module_info_t __attribute__((section(".minit"))) init(env_t *env) { cpuid(0x80000000, &eax, &ebx, &ecx, &edx); if (eax >= 0x8000001E) { cpu_info( ); } - return (module_info_t){ .name = (char *)"CPUBENCH", - .message = (char *)"Дополнительная информация о процессоре", - .type = 0, - .data_size = 0, - .data = (void *)0, - .err_code = 0, - .module_id = 0, - .irq = 0, - .irq_handler = 0, - .get_func = 0, - .after_init = 0 }; + env->ret = &((module_info_t){ .name = (char *)"CPUBENCH", + .message = (char *)"Дополнительная информация о процессоре", + .type = 0, + .data_size = 0, + .data = (void *)0, + .err_code = 0, + .module_id = 0, + .irq = 0, + .irq_handler = 0, + .get_func = 0, + .after_init = 0 }); + delete_thread( ); } \ No newline at end of file diff --git a/modules/helloworld/main.c b/modules/helloworld/main.c index 04a4d41..aad9193 100644 --- a/modules/helloworld/main.c +++ b/modules/helloworld/main.c @@ -61,20 +61,21 @@ static int app_main( ) { return 2 + 2; } -module_info_t __attribute__((section(".minit"))) init(env_t *env) { +void __attribute__((section(".minit"))) init(env_t *env) { init_env(env); log_printf("[%s]\n", message); log_printf("%s\n", logo); log_printf("%s\n", logo_synapseos); - return (module_info_t){ .name = (char *)&name, - .message = (char *)&message, - .type = 0, - .data_size = 0, - .data = (void *)&app_main, - .err_code = 0, - .module_id = 0, - .irq = 0, - .irq_handler = 0, - .get_func = 0, - .after_init = 0 }; + env->ret = &((module_info_t){ .name = (char *)&name, + .message = (char *)&message, + .type = 0, + .data_size = 0, + .data = (void *)&app_main, + .err_code = 0, + .module_id = 0, + .irq = 0, + .irq_handler = 0, + .get_func = 0, + .after_init = 0 }); + delete_thread( ); } diff --git a/modules/imfs/main.c b/modules/imfs/main.c index e43434c..bd40ab2 100644 --- a/modules/imfs/main.c +++ b/modules/imfs/main.c @@ -142,7 +142,7 @@ void print_folder_contents(folder_t *folder, size_t depth) { } } -module_info_t __attribute__((section(".minit"))) init(env_t *env) { +void __attribute__((section(".minit"))) init(env_t *env) { init_env(env); create_folder("", NULL); @@ -154,17 +154,17 @@ module_info_t __attribute__((section(".minit"))) init(env_t *env) { file_t *readme = create_file("readme", "txt", root_folder); write_file(readme, "БМПОС 2023-2024", 21); - return (module_info_t){ - .name = (char *)"[FS][IMFS]", - .message = (char *)"IMFS (in memory filesystem) - файловая система работающая исключительно в ОЗУ.", - .type = 0, - .data_size = 0, - .data = (void *)0, - .err_code = 0, - .module_id = 0, - .irq = 0, - .irq_handler = 0, - .get_func = 0, - .after_init = 0 - }; + env->ret = &((module_info_t){ + .name = (char *)"[FS][IMFS]", + .message = (char *)"IMFS (in memory filesystem) - файловая система работающая исключительно в ОЗУ.", + .type = 0, + .data_size = 0, + .data = (void *)0, + .err_code = 0, + .module_id = 0, + .irq = 0, + .irq_handler = 0, + .get_func = 0, + .after_init = 0 }); + delete_thread( ); } diff --git a/modules/ios/main.c b/modules/ios/main.c index c6b4de1..018d5b2 100644 --- a/modules/ios/main.c +++ b/modules/ios/main.c @@ -98,18 +98,19 @@ static void main( ) { for (;;) { asm volatile("hlt"); } } -module_info_t __attribute__((section(".minit"))) init(env_t *env) { +void __attribute__((section(".minit"))) init(env_t *env) { init_env(env); - return (module_info_t){ .name = (char *)"[IOS]", - .message = (char *)"IOS (input-output shell) - оболочка ввода-вывода.", - .type = 0, - .data_size = 0, - .data = (void *)0, - .err_code = 0, - .module_id = 0, - .irq = 0, - .irq_handler = 0, - .get_func = 0, - .after_init = main }; + env->ret = &((module_info_t){ .name = (char *)"[IOS]", + .message = (char *)"IOS (input-output shell) - оболочка ввода-вывода.", + .type = 0, + .data_size = 0, + .data = (void *)0, + .err_code = 0, + .module_id = 0, + .irq = 0, + .irq_handler = 0, + .get_func = 0, + .after_init = main }); + delete_thread( ); } diff --git a/modules/pci/main.c b/modules/pci/main.c index c349ead..c9aeeef 100644 --- a/modules/pci/main.c +++ b/modules/pci/main.c @@ -114,10 +114,24 @@ static inline void scan( ) { } } -module_info_t __attribute__((section(".minit"))) init(env_t *env) { +module_info_t mod = { .name = (char *)"[PCI]", + .message = (char *)"PCI драйвер", + .type = 0, + .data_size = 0, + .data = (void *)0, + .err_code = 0, + .module_id = 0, + .irq = 0, + .irq_handler = 0, + .get_func = 0, + .after_init = 0 }; + +void __attribute__((section(".minit"))) init(env_t *env) { init_env(env); + log_printf("pci_data %x\n", 1); module_info_t *pci_data = get_module("[PCI][ADAPTER]"); + log_printf("pci_data %x\n", pci_data); if (pci_data == NULL) { log_printf("Адаптер PCI данных не найден!\n"); @@ -129,15 +143,6 @@ module_info_t __attribute__((section(".minit"))) init(env_t *env) { } scan( ); - return (module_info_t){ .name = (char *)"[PCI]", - .message = (char *)"PCI драйвер", - .type = 0, - .data_size = 0, - .data = (void *)0, - .err_code = 0, - .module_id = 0, - .irq = 0, - .irq_handler = 0, - .get_func = 0, - .after_init = 0 }; + env->ret = &mod; + delete_thread( ); } \ No newline at end of file diff --git a/modules/pci/pci_data.c b/modules/pci/pci_data.c index e679a4a..5433e63 100644 --- a/modules/pci/pci_data.c +++ b/modules/pci/pci_data.c @@ -59,7 +59,19 @@ static void print_vendors(uint64_t num_vendors, vendor_t **vendor_list) { } } -module_info_t __attribute__((section(".minit"))) init(env_t *env) { +module_info_t mod = { .name = (char *)"[PCI][ADAPTER]", + .message = (char *)"PCI данные", + .type = 0, + .data_size = 0, + .data = 0, + .err_code = 0, + .module_id = 0, + .irq = 0, + .irq_handler = 0, + .get_func = 0, + .after_init = 0 }; + +void __attribute__((section(".minit"))) init(env_t *env) { init_env(env); module_info_t *pci_data = get_module("[PCI][DATA][VENDORS]"); @@ -71,15 +83,9 @@ module_info_t __attribute__((section(".minit"))) init(env_t *env) { vendor_t **vendor_list = parse_file(pci_data->data, num_vendors, pci_data->data_size); // print_vendors(num_vendors, vendor_list); - return (module_info_t){ .name = (char *)"[PCI][ADAPTER]", - .message = (char *)"PCI данные", - .type = 0, - .data_size = num_vendors, - .data = vendor_list, - .err_code = 0, - .module_id = 0, - .irq = 0, - .irq_handler = 0, - .get_func = 0, - .after_init = 0 }; + mod.data_size = num_vendors; + mod.data = vendor_list; + env->ret = &mod; + log_printf("Готово22\n"); + delete_thread( ); } \ No newline at end of file diff --git a/modules/ps2/main.c b/modules/ps2/main.c index 8b02107..1eca59a 100644 --- a/modules/ps2/main.c +++ b/modules/ps2/main.c @@ -145,20 +145,21 @@ static void handler( ) { after_interrupt( ); } -module_info_t __attribute__((section(".minit"))) init(env_t *env) { +void __attribute__((section(".minit"))) init(env_t *env) { init_env(env); current_state = NORMAL_STATE; keyboard_buffer.ctrl_pressed = 0; keyboard_buffer.shift_pressed = 0; - return (module_info_t){ .name = (char *)"[KEYBOARD]", - .message = (char *)"PS/2 драйвер", - .type = 0, - .data_size = 0, - .data = (void *)0, - .err_code = 0, - .module_id = 0, - .irq = 33, - .irq_handler = &handler, - .get_func = __get_func }; + env->ret = &((module_info_t){ .name = (char *)"[KEYBOARD]", + .message = (char *)"PS/2 драйвер", + .type = 0, + .data_size = 0, + .data = (void *)0, + .err_code = 0, + .module_id = 0, + .irq = 33, + .irq_handler = &handler, + .get_func = __get_func }); + delete_thread( ); } \ No newline at end of file diff --git a/scripts/pbuild.py b/scripts/pbuild.py index 1ee7535..25e55ad 100644 --- a/scripts/pbuild.py +++ b/scripts/pbuild.py @@ -14,9 +14,9 @@ if "^.M" in output: ARCH_FLAGS = "-m64 -march=x86-64 -mabi=sysv -mno-red-zone -mcmodel=kernel -MMD -MP" WARN_FLAGS = "-Wall -Wextra -nostdlib" STANDART_FLAGS = f"-std=gnu11 -DKERNEL_GIT_TAG=\\\"{__VERSION}\\\"" # -DNO_DEBUG=1 -PROTECT_FLAGS = "-O0 -g -pipe -ffreestanding -fno-stack-protector -fno-lto -fno-stack-check -fno-PIC -fno-PIE" -PROTECT_FLAGS += " -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx" -CHARSET_FLAGS = "-finput-charset=UTF-8 -fexec-charset=cp1251" +PROTECT_FLAGS = "-O0 -pipe -ffreestanding -fno-stack-protector -fno-lto -fno-stack-check -fno-PIC -fno-PIE" +PROTECT_FLAGS += " -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -ffunction-sections -fdata-sections" +CHARSET_FLAGS = "-finput-charset=UTF-8 -fexec-charset=cp1251" #"" LIBS_FLAGS = "-Ilimine -Iinclude" FORMAT_CMD = """find . \( -name "*.c" -o -name "*.h" -o -name "*.cpp" -o -name "*.hpp" \) -print0 | xargs -0 clang-format -i -style=file""" From 03742e31bbf8634adc4620744b8cae19d724db73 Mon Sep 17 00:00:00 2001 From: Aren Elchinyan Date: Mon, 16 Sep 2024 21:43:13 +0300 Subject: [PATCH 12/12] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=BF=D1=80=D0=B5=D0=BE=D0=B1=D1=80=D0=B0=D0=B7?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20UTF8->CP1251?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/utf8cp.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 kernel/utf8cp.c diff --git a/kernel/utf8cp.c b/kernel/utf8cp.c new file mode 100644 index 0000000..4dafce7 --- /dev/null +++ b/kernel/utf8cp.c @@ -0,0 +1,65 @@ +#include +#include + +#define NONS (0x98) +#define SKIP_OR_NOT (dest != NONS) +#define M(W40, W45, W201) ((((W40)-0x80) << 10) | (((W45) - (W40)) << 5) | ((W201)-0x80)) + +unsigned int utf8_2_win1251(const char *utf8, char *win) { + unsigned int dest, p, l1, l2, l3, inc, i, j, b1, b2, b3; + const unsigned short AR[16] = { + M(NONS, NONS, 0x86), M(0xA8, 0xB8, 0x87), M(0x80, 0x90, 0x95), M(0x81, 0x83, 0x96), + M(0xAA, 0xBA, 0x97), M(0xBD, 0xBE, NONS), M(0xB2, 0xB3, NONS), M(0xAF, 0xBF, NONS), + M(0xA3, 0xBC, 0x91), M(0x8A, 0x9A, 0x92), M(0x8C, 0x9C, 0x82), M(0x8E, 0x9E, NONS), + M(0x8D, 0x9D, 0x93), M(NONS, NONS, 0x94), M(0xA1, 0xA2, 0x84), M(0x8F, 0x9F, NONS) + }; + + for (i = 0, j = 0; utf8[i] != 0; i += inc) { + b1 = utf8[i]; + b2 = utf8[i + 1]; + b3 = utf8[i + 2]; + + // Utf8 переводим в Unicode. + inc = (0xE5000000u >> (((b1) >> 4) << 1)) & 0x3; + p = ((((b1) << 12) + (((b2)&0x3F) << 6) + ((b3)&0x3F)) & (0x7FFFF >> inc)) >> + (((0xC5FFAAAAu >> (((b1) >> 4) << 1)) & 0x3) * 6); + + // Добавляем все остающиеся на месте. + dest = (((inc != 0) & (((p >> 5) != 0x5) | (0xF71C852E >> b2))) - 1) & p; + inc++; + + // Добавляем русские буквы кроме ё и Ё. + dest += ((((p - 0x10) >> 6) != 0x10) - 1) & (p - 0x350); + + // Добавляем символы из диапазонов: 0x401-0x40F, 0x451-0x45F, 0x2013-0x2022. + l1 = ((p >> 4) != 0x40) - 1; + l2 = ((p >> 4) != 0x45) - 1; + l3 = (((p - 3) >> 4) != 0x201) - 1; + dest += ((((l2 & (AR[p & 0xF] >> 5)) | (l3 & AR[p & 0xF])) & 0x1F) + ((l1 | l2) & (AR[p & 0xF] >> 10))) + + ((l1 | l2 | l3) & 0x80); + + // Добавляем оставшиеся. + dest += (((p != 0x490) - 1) & 0xA5) | (((p != 0x491) - 1) & 0xB4) | (((p != 0x2026) - 1) & 0x85) | + (((p != 0x2030) - 1) & 0x89) | (((p != 0x2039) - 1) & 0x8B) | (((p != 0x203A) - 1) & 0x9B) | + (((p != 0x20AC) - 1) & 0x88) | (((p != 0x2116) - 1) & 0xB9) | (((p != 0x2122) - 1) & 0x99); + + // Отличаем настоящий 0 от просто отсутствующих в win 1251 символов. + dest += (((b1 == 0) | (dest != 0)) - 1) & NONS; + + win[j] = dest; + j += SKIP_OR_NOT; + } + win[j] = 0; + return j; +} + +#undef M +#undef NONS +#undef SKIP_OR_NOT + +char *utf8cp(char *str) { + size_t len = tool_strlen(str); + char *result = (char *)mem_alloc(len + 1); + if (result) { utf8_2_win1251(str, result); } + return result; +} \ No newline at end of file