mirror of
https://github.com/0Nera/BMOSP.git
synced 2024-11-22 08:31:23 +03:00
commit
ae0c7db85b
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -22,7 +22,7 @@ jobs:
|
|||||||
|
|
||||||
- name: install limine
|
- name: install limine
|
||||||
run: |
|
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 ..
|
cd limine && make && cd ..
|
||||||
|
|
||||||
- name: build
|
- name: build
|
||||||
|
3
.github/workflows/release.yml
vendored
3
.github/workflows/release.yml
vendored
@ -19,7 +19,7 @@ jobs:
|
|||||||
|
|
||||||
- name: install limine
|
- name: install limine
|
||||||
run: |
|
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 ..
|
cd limine && make && cd ..
|
||||||
|
|
||||||
- name: build
|
- name: build
|
||||||
@ -64,7 +64,6 @@ jobs:
|
|||||||
draft: true
|
draft: true
|
||||||
files: |
|
files: |
|
||||||
${{ github.workspace }}/rel/kernel.elf
|
${{ github.workspace }}/rel/kernel.elf
|
||||||
${{ github.workspace }}/rel/bmosp.hdd
|
|
||||||
${{ github.workspace }}/rel/bmosp.iso
|
${{ github.workspace }}/rel/bmosp.iso
|
||||||
${{ github.workspace }}/rel/LICENSE
|
${{ github.workspace }}/rel/LICENSE
|
||||||
|
|
||||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -5,8 +5,7 @@ limine/
|
|||||||
ovmf/
|
ovmf/
|
||||||
iso_root/
|
iso_root/
|
||||||
output/
|
output/
|
||||||
sdk/
|
sdk*/
|
||||||
_sdk/
|
|
||||||
*.so
|
*.so
|
||||||
*.o
|
*.o
|
||||||
*.ko
|
*.ko
|
||||||
|
4
build.sh
4
build.sh
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
dos2unix *.sh
|
dos2unix *.sh
|
||||||
|
|
||||||
|
python3 scripts/pbuild.py
|
||||||
|
|
||||||
cd modlib/lib/
|
cd modlib/lib/
|
||||||
dos2unix build.sh
|
dos2unix build.sh
|
||||||
chmod +x build.sh
|
chmod +x build.sh
|
||||||
@ -22,5 +24,3 @@ for dir in */; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
python3 scripts/pbuild.py
|
|
@ -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/simd.ko
|
|
||||||
MODULE_CMDLINE=[MOD]simd.ko
|
|
||||||
|
|
||||||
MODULE_PATH=boot:///mod/pci_data.ko
|
MODULE_PATH=boot:///mod/pci_data.ko
|
||||||
MODULE_CMDLINE=[MOD]pci_data.ko
|
MODULE_CMDLINE=[MOD]pci_data.ko
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ void arch_init( );
|
|||||||
void task_init( );
|
void task_init( );
|
||||||
void task_after_init( );
|
void task_after_init( );
|
||||||
void task_switch( );
|
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_current( );
|
||||||
void task_del(uint64_t id);
|
void task_del(uint64_t id);
|
||||||
void cpu_init( );
|
void cpu_init( );
|
||||||
@ -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_b( );
|
||||||
uint64_t arch_get_tick_l( );
|
uint64_t arch_get_tick_l( );
|
||||||
uint64_t arch_get_tick( );
|
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);
|
void com_write_bytes(char *c, uint64_t n);
|
||||||
time_t rtc_get_time( );
|
time_t rtc_get_time( );
|
||||||
|
|
||||||
@ -105,6 +105,26 @@ static inline void io_wait( ) {
|
|||||||
outb(0x80, 0);
|
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_BIG arch_get_tick_b( )
|
||||||
#define GET_TICK_lOW arch_get_tick_l( )
|
#define GET_TICK_lOW arch_get_tick_l( )
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
void log_init( );
|
void log_init( );
|
||||||
void log_init_mem( );
|
void log_init_mem( );
|
||||||
void log_printf(char *str, ...);
|
void log_printf(char *str, ...);
|
||||||
|
char *utf8cp(char *str);
|
||||||
|
|
||||||
#ifndef NO_DEBUG
|
#ifndef NO_DEBUG
|
||||||
#define LOG(...) \
|
#define LOG(...) \
|
||||||
|
@ -25,6 +25,24 @@
|
|||||||
#define ELFMAG3 'F'
|
#define ELFMAG3 'F'
|
||||||
#define SHT_SYMTAB 2
|
#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_addr_t; // Адрес
|
||||||
typedef uint64_t elf64_offset_t; // Смещение
|
typedef uint64_t elf64_offset_t; // Смещение
|
||||||
typedef uint64_t elf64_xword_t; // Целочисленное длинное слово без знака
|
typedef uint64_t elf64_xword_t; // Целочисленное длинное слово без знака
|
||||||
|
@ -62,6 +62,7 @@ typedef struct {
|
|||||||
void *irq_handler; // Адрес обработчика прерываний
|
void *irq_handler; // Адрес обработчика прерываний
|
||||||
void *(*get_func)(uint64_t id);
|
void *(*get_func)(uint64_t id);
|
||||||
void (*after_init)( );
|
void (*after_init)( );
|
||||||
|
void *env; // env_t
|
||||||
} __attribute__((packed)) module_info_t;
|
} __attribute__((packed)) module_info_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -76,9 +77,10 @@ typedef struct {
|
|||||||
sys_info_t *(*get_info)( );
|
sys_info_t *(*get_info)( );
|
||||||
module_info_t *(*get_module)(char *module_id);
|
module_info_t *(*get_module)(char *module_id);
|
||||||
module_info_t *(*mod_list_get)(uint64_t *count);
|
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)( );
|
void (*delete_thread)( );
|
||||||
time_t (*get_time)( );
|
time_t (*get_time)( );
|
||||||
|
module_info_t *ret;
|
||||||
} __attribute__((packed)) env_t;
|
} __attribute__((packed)) env_t;
|
||||||
|
|
||||||
env_t *sys_install(env_t *module);
|
env_t *sys_install(env_t *module);
|
||||||
|
@ -41,8 +41,10 @@ static inline void pause( ) {
|
|||||||
|
|
||||||
void tool_memcpy(void *dest, void *src, uint64_t n);
|
void tool_memcpy(void *dest, void *src, uint64_t n);
|
||||||
void *tool_memset(void *ptr, uint8_t n, uint64_t size);
|
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);
|
uint64_t tool_strlen(const char *str);
|
||||||
void tool_strcpy(char *dest, char *src);
|
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_starts_with(const char *str, const char *prefix);
|
||||||
uint64_t tool_str_contains(const char *str, const char *substr);
|
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);
|
void tool_format(void (*putc)(char c), const char *format_string, va_list args);
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
#define VERSION_MAJOR 0
|
#define VERSION_MAJOR 0
|
||||||
#define VERSION_MINOR 2
|
#define VERSION_MINOR 2
|
||||||
#define VERSION_BUILD 58
|
#define VERSION_BUILD 162
|
||||||
|
@ -12,7 +12,7 @@ static inline int com_is_transmit_empty(uint16_t com) {
|
|||||||
return inb(com + 5) & 0x20;
|
return inb(com + 5) & 0x20;
|
||||||
}
|
}
|
||||||
|
|
||||||
void com_write_byte(uint8_t byte) {
|
void com_write_byte(char byte) {
|
||||||
while (!com_is_transmit_empty(0x3F8)) {}
|
while (!com_is_transmit_empty(0x3F8)) {}
|
||||||
|
|
||||||
outb(0x3F8, byte);
|
outb(0x3F8, byte);
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <tool.h>
|
#include <tool.h>
|
||||||
|
|
||||||
static bool acpi_msrs_support = false;
|
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) {
|
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));
|
asm volatile("cpuid" : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) : "a"(leaf));
|
||||||
@ -142,4 +143,21 @@ void cpu_init( ) {
|
|||||||
if ((edx >> 5) & 1) { LOG("Программный терморегулятор (STC) поддерживается!\n"); }
|
if ((edx >> 5) & 1) { LOG("Программный терморегулятор (STC) поддерживается!\n"); }
|
||||||
|
|
||||||
brandname( );
|
brandname( );
|
||||||
|
|
||||||
|
cpuid(1, &eax, &ebx, &ecx, &edx);
|
||||||
|
|
||||||
|
if ((edx >> 0) & 1) {
|
||||||
|
asm volatile("finit");
|
||||||
|
LOG("FPU(x87) поддерживается!\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"); }
|
||||||
}
|
}
|
@ -44,7 +44,7 @@ void task_switch( ) {
|
|||||||
task_switch_asm(last, next);
|
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");
|
LOG("Выделение потока\n");
|
||||||
|
|
||||||
uint64_t cr3;
|
uint64_t cr3;
|
||||||
@ -64,6 +64,7 @@ uint64_t task_new_thread(void (*func)(void *), char *name) {
|
|||||||
stack[--stack_top] = (uint64_t)0;
|
stack[--stack_top] = (uint64_t)0;
|
||||||
|
|
||||||
new_task->rsp = (uint64_t)new_task->stack + sizeof(uint64_t) * stack_top;
|
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 = 500;
|
||||||
new_task->cpu_time_expired = new_task->cpu_time;
|
new_task->cpu_time_expired = new_task->cpu_time;
|
||||||
new_task->id = next_thread_id++;
|
new_task->id = next_thread_id++;
|
||||||
@ -120,9 +121,11 @@ void task_del_current( ) {
|
|||||||
prev->next = next;
|
prev->next = next;
|
||||||
next->last = prev;
|
next->last = prev;
|
||||||
|
|
||||||
|
LOG("Очистка потока ID: %u, %s\n", current_task->id, current_task->id_str);
|
||||||
mem_free(current_task->stack);
|
mem_free(current_task->stack);
|
||||||
mem_free(current_task);
|
mem_free(current_task);
|
||||||
|
|
||||||
|
LOG("Смена ID: %u, %s\n", next->id, next->id_str);
|
||||||
current_task = next;
|
current_task = next;
|
||||||
if (full_init) { task_switch( ); }
|
if (full_init) { task_switch( ); }
|
||||||
}
|
}
|
||||||
|
65
kernel/elf.c
65
kernel/elf.c
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <mod.h>
|
#include <mod.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <tool.h>
|
||||||
|
|
||||||
elf64_header_t *elf64_get_header(void *data) {
|
elf64_header_t *elf64_get_header(void *data) {
|
||||||
return (elf64_header_t *)(data);
|
return (elf64_header_t *)(data);
|
||||||
@ -52,7 +53,7 @@ unsigned long elf64_hash(unsigned char *name) {
|
|||||||
while (*name) {
|
while (*name) {
|
||||||
h = (h << 4) + *name++;
|
h = (h << 4) + *name++;
|
||||||
// Проверка на overflow
|
// Проверка на overflow
|
||||||
if (g = h & 0xf0000000) h ^= g >> 24;
|
if (g = (h & 0xf0000000)) h ^= g >> 24;
|
||||||
// Ограничение хэша
|
// Ограничение хэша
|
||||||
h &= 0xffffffff;
|
h &= 0xffffffff;
|
||||||
}
|
}
|
||||||
@ -70,22 +71,28 @@ void *elf_entry(void *module_bin) {
|
|||||||
LOG("\t\tОшибка! Модуль неправильно собран!\n");
|
LOG("\t\tОшибка! Модуль неправильно собран!\n");
|
||||||
for (;;) { asm volatile("pause"); }
|
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( ) {
|
||||||
|
LOG("123");
|
||||||
}
|
}
|
||||||
|
|
||||||
void *elf_parse(elf64_header_t *head) {
|
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 ||
|
if (head->e_ident[0] != ELFMAG0 || head->e_ident[1] != ELFMAG1 || head->e_ident[2] != ELFMAG2 ||
|
||||||
head->e_ident[3] != ELFMAG3) {
|
head->e_ident[3] != ELFMAG3) {
|
||||||
LOG("Ошибка: Неправильный формат!\n");
|
LOG("Ошибка: Неправильный формат!\n");
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG("Точка входа: 0x%x\n", head->e_entry);
|
// LOG("Точка входа: 0x%x\n", head->e_entry);
|
||||||
|
|
||||||
elf64_section_header_t *symtab_section = NULL;
|
elf64_section_header_t *symtab_section = NULL;
|
||||||
char *string_table = NULL;
|
char *string_table = NULL;
|
||||||
@ -100,17 +107,59 @@ void *elf_parse(elf64_header_t *head) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (symtab_section && string_table) {
|
if (symtab_section && string_table) {
|
||||||
|
#ifdef DEBUG_ELF
|
||||||
LOG("\nТаблица символов:\n");
|
LOG("\nТаблица символов:\n");
|
||||||
LOG("%s %s %s %s\n", "Индекс", "Значение", "Размер", "Наименование");
|
LOG("%s %s %s %s\n", "Индекс", "Значение", "Размер", "Наименование");
|
||||||
|
#endif
|
||||||
|
|
||||||
int num_symbols = symtab_section->sh_size / symtab_section->sh_entsize;
|
int num_symbols = symtab_section->sh_size / symtab_section->sh_entsize;
|
||||||
for (int i = 0; i < num_symbols; i++) {
|
for (int i = 0; i < num_symbols; i++) {
|
||||||
elf64_sym_t *sym = elf64_get_symval(head, symtab_section - elf64_sheader(head), 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) {
|
||||||
|
#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:
|
||||||
|
|
||||||
|
#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;
|
||||||
|
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;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
#ifdef DEBUG_ELF
|
||||||
|
log_printf("???\n");
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG("Таблица символов не найдена!\n");
|
LOG("Таблица символов не найдена!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return (void *)0;
|
return (void *)head->e_entry;
|
||||||
}
|
}
|
@ -53,16 +53,17 @@ void fb_init( ) {
|
|||||||
|
|
||||||
for (uint64_t i = 0; i < width * height; i++) { fb_addr[i] = background; }
|
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; }
|
if (framebuffer_response->framebuffer_count == 1) { return; }
|
||||||
|
|
||||||
|
#ifdef DEBUG_FB
|
||||||
LOG("Инициализация дополнительных: %u мониторов\n", framebuffer_response->framebuffer_count);
|
LOG("Инициализация дополнительных: %u мониторов\n", framebuffer_response->framebuffer_count);
|
||||||
|
#endif
|
||||||
for (uint64_t i = 1; i < framebuffer_response->framebuffer_count; i++) {
|
for (uint64_t i = 1; i < framebuffer_response->framebuffer_count; i++) {
|
||||||
struct limine_framebuffer *framebuffer = framebuffer_response->framebuffers[i];
|
struct limine_framebuffer *framebuffer = framebuffer_response->framebuffers[i];
|
||||||
uint32_t *framebuffer_addr = (uint32_t *)framebuffer->address;
|
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);
|
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; }
|
for (uint64_t ij = 0; ij < width * height; ij++) { framebuffer_addr[ij] = background; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
30
kernel/log.c
30
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) {
|
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++) {
|
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) {
|
static void log_fb_putchar(char c) {
|
||||||
if (c == '\0' || fb_init_status < 1) { return; }
|
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;
|
fb_pos_x += FONT_6X8_SLIM_CHAR_WIDTH * 4;
|
||||||
} else if (c == '\n') {
|
} else if (c == '\n') {
|
||||||
fb_pos_x = 4;
|
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) {
|
if (fb_pos_y + FONT_6X8_SLIM_CHAR_HEIGHT >= SCREEN_HEIGHT) {
|
||||||
// Дошли до нижнего края экрана
|
// Дошли до нижнего края экрана
|
||||||
while (log_buffer[0] != '\n') {
|
while (log_buffer[0] != '\n') { tool_memmove(log_buffer, log_buffer + 1, --buf_pos); }
|
||||||
for (uint64_t i = 0; i < buf_max - 1; i++) { log_buffer[i] = log_buffer[i + 1]; }
|
tool_memmove(log_buffer, log_buffer + 1, --buf_pos);
|
||||||
buf_pos--;
|
|
||||||
}
|
|
||||||
for (uint64_t i = 0; i < buf_max - 1; i++) { log_buffer[i] = log_buffer[i + 1]; }
|
|
||||||
buf_pos--;
|
|
||||||
redraw_screen( );
|
redraw_screen( );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -75,7 +75,7 @@ static void log_fb_putchar(char c) {
|
|||||||
|
|
||||||
void redraw_screen( ) {
|
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_x = 4;
|
||||||
fb_pos_y = 0;
|
fb_pos_y = 0;
|
||||||
@ -87,8 +87,6 @@ void log_putchar(char c) {
|
|||||||
log_buffer[buf_pos] = c;
|
log_buffer[buf_pos] = c;
|
||||||
com_write_byte(c);
|
com_write_byte(c);
|
||||||
|
|
||||||
log_buffer[buf_pos] = c;
|
|
||||||
|
|
||||||
if (buf_pos + 1 == buf_max) {
|
if (buf_pos + 1 == buf_max) {
|
||||||
// Смещение буфера на 1 символ влево
|
// Смещение буфера на 1 символ влево
|
||||||
for (uint64_t i = 0; i < buf_max - 1; i++) { log_buffer[i] = log_buffer[i + 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_list args;
|
||||||
va_start(args, str);
|
va_start(args, str);
|
||||||
tool_format(&log_putchar, str, args);
|
tool_format(&log_putchar, str, args);
|
||||||
|
|
||||||
lock_release(log_lock);
|
lock_release(log_lock);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void log_init_mem( ) {
|
void log_init_mem( ) {
|
||||||
LOCK(log_lock);
|
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));
|
log_buffer = mem_alloc(((SCREEN_WIDTH - 4) / FONT_WIDTH) * (SCREEN_HEIGHT / FONT_HEIGHT));
|
||||||
tool_memcpy(log_buffer, start_buffer, buf_max);
|
tool_memcpy(log_buffer, start_buffer, buf_max);
|
||||||
buf_max = ((SCREEN_WIDTH - 4) / FONT_WIDTH) * (SCREEN_HEIGHT / FONT_HEIGHT);
|
buf_max = ((SCREEN_WIDTH - 4) / FONT_WIDTH) * (SCREEN_HEIGHT / FONT_HEIGHT);
|
||||||
LOG("Размер буффера: %u символов\n", buf_max);
|
LOG("Размер буффера: %u символов\n", buf_max);
|
||||||
|
LOG("%ux%u\n", width, height);
|
||||||
redraw_screen( );
|
redraw_screen( );
|
||||||
lock_release(log_lock);
|
lock_release(log_lock);
|
||||||
}
|
}
|
||||||
|
15
kernel/mem.c
15
kernel/mem.c
@ -51,9 +51,11 @@ static uint64_t mmmap_count = 0;
|
|||||||
extern task_t *current_task;
|
extern task_t *current_task;
|
||||||
extern uint64_t full_init;
|
extern uint64_t full_init;
|
||||||
|
|
||||||
|
#ifdef DEBUG_MEM
|
||||||
static const char memory_types[8][82] = { "Доступно", "Зарезервировано", "ACPI, можно освободить",
|
static const char memory_types[8][82] = { "Доступно", "Зарезервировано", "ACPI, можно освободить",
|
||||||
"ACPI NVS", "Плохая память", "Загрузчик, можно освободить",
|
"ACPI NVS", "Плохая память", "Загрузчик, можно освободить",
|
||||||
"Ядро и модули", "Буфер кадра" };
|
"Ядро и модули", "Буфер кадра" };
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct limine_memmap_response *memmap_response;
|
static struct limine_memmap_response *memmap_response;
|
||||||
|
|
||||||
@ -63,6 +65,7 @@ void mem_dump_memory( ) {
|
|||||||
mem_entry_t *curr = first_node;
|
mem_entry_t *curr = first_node;
|
||||||
|
|
||||||
while (curr) {
|
while (curr) {
|
||||||
|
#ifdef DEBUG_MEM
|
||||||
if (curr->next) {
|
if (curr->next) {
|
||||||
LOG("->0x%x | %u мегабайт | %s | 0x%x | поток %u\n", &curr->data, (curr->size) / 1024 / 1024,
|
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);
|
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,
|
LOG("->0x%x | %u мегабайт | %s | поток %u | Это последний блок\n", &curr->data, (curr->size) / 1024 / 1024,
|
||||||
curr->free ? memory_types[0] : memory_types[1], curr->task_id);
|
curr->free ? memory_types[0] : memory_types[1], curr->task_id);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
curr = curr->next;
|
curr = curr->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -284,8 +288,9 @@ void mem_init( ) {
|
|||||||
mmmap_count = memmap_response->entry_count;
|
mmmap_count = memmap_response->entry_count;
|
||||||
struct limine_memmap_entry **mmaps = memmap_response->entries;
|
struct limine_memmap_entry **mmaps = memmap_response->entries;
|
||||||
|
|
||||||
|
#ifdef DEBUG_MEM
|
||||||
LOG("Записей в карте памяти: %u\n", memmap_response->entry_count);
|
LOG("Записей в карте памяти: %u\n", memmap_response->entry_count);
|
||||||
|
#endif
|
||||||
// Обработка каждой записи в карте памяти
|
// Обработка каждой записи в карте памяти
|
||||||
for (uint64_t i = 0; i < mmmap_count; i++) {
|
for (uint64_t i = 0; i < mmmap_count; i++) {
|
||||||
available += mmaps[i]->length;
|
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,
|
// LOG("\t%d: 0x%x\tдлина: 0x%x\tтип: %s\n", i + 1, mmaps[i]->base, mmaps[i]->length,
|
||||||
// memory_types[mmaps[i]->type]);
|
// memory_types[mmaps[i]->type]);
|
||||||
if (mmaps[i]->type == LIMINE_MEMMAP_FRAMEBUFFER) {
|
if (mmaps[i]->type == LIMINE_MEMMAP_FRAMEBUFFER) {
|
||||||
|
#ifdef DEBUG_MEM
|
||||||
LOG("На видеопамять BIOS/UEFI выделено: %u мегабайт + %u "
|
LOG("На видеопамять 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);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (!(mmaps[i]->type == LIMINE_MEMMAP_USABLE)) { continue; }
|
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); }
|
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 / %u блоков доступно\n", bitmap_available, bitmap_limit);
|
||||||
LOG("Размер битовой карты: %u\n", bitmap_size);
|
LOG("Размер битовой карты: %u\n", bitmap_size);
|
||||||
|
#endif
|
||||||
|
|
||||||
alloc_init(mem_frame_alloc(1024), 1024 * BLOCK_SIZE);
|
alloc_init(mem_frame_alloc(1024), 1024 * BLOCK_SIZE);
|
||||||
|
#ifdef DEBUG_MEM
|
||||||
LOG("%u мегабайт выделено в динамичную память\n", (256 * 16 * BLOCK_SIZE + BLOCK_SIZE) / 1024 / 1024);
|
LOG("%u мегабайт выделено в динамичную память\n", (256 * 16 * BLOCK_SIZE + BLOCK_SIZE) / 1024 / 1024);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Выделяем по 4 мегабайта в аллокатор динамичной памяти
|
// Выделяем по 4 мегабайта в аллокатор динамичной памяти
|
||||||
for (uint64_t i = 0; i < 32; 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( );
|
||||||
|
#ifdef DEBUG_MEM
|
||||||
|
|
||||||
LOG("%u МБ объем доступной памяти, %u МБ объем виртуальной памяти\n", (bitmap_available * BLOCK_SIZE) / 1024 / 1024,
|
LOG("%u МБ объем доступной памяти, %u МБ объем виртуальной памяти\n", (bitmap_available * BLOCK_SIZE) / 1024 / 1024,
|
||||||
available / 1024 / 1024);
|
available / 1024 / 1024);
|
||||||
|
|
||||||
LOG("%u / %u блоков доступно\n", bitmap_available, bitmap_limit);
|
LOG("%u / %u блоков доступно\n", bitmap_available, bitmap_limit);
|
||||||
|
#endif
|
||||||
}
|
}
|
52
kernel/mod.c
52
kernel/mod.c
@ -24,7 +24,7 @@ module_info_t *module_list = NULL;
|
|||||||
static char *graphics_module_message = "Графический модуль-объект";
|
static char *graphics_module_message = "Графический модуль-объект";
|
||||||
static char *other_module_message = "Неизвестный тип модуля";
|
static char *other_module_message = "Неизвестный тип модуля";
|
||||||
|
|
||||||
static env_t main_env;
|
static env_t *main_env = NULL;
|
||||||
|
|
||||||
void *bootpng_ptr;
|
void *bootpng_ptr;
|
||||||
uint64_t bootpng_size;
|
uint64_t bootpng_size;
|
||||||
@ -49,7 +49,7 @@ void mod_after_init( ) {
|
|||||||
for (uint64_t i = 0; i < modules_count; i++) {
|
for (uint64_t i = 0; i < modules_count; i++) {
|
||||||
if (module_list[i].after_init != 0) {
|
if (module_list[i].after_init != 0) {
|
||||||
LOG("%s.after_init( );\n", module_list[i].name);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,40 +117,28 @@ void mod_init( ) {
|
|||||||
continue;
|
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);
|
// 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);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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++;
|
modules_count++;
|
||||||
}
|
}
|
||||||
LOG("Модулей обработано: %u\n", modules_count);
|
LOG("Модулей обработано: %u\n", modules_count);
|
||||||
|
@ -60,9 +60,10 @@ env_t *sys_install(env_t *module) {
|
|||||||
module->get_info = &sys_get_info;
|
module->get_info = &sys_get_info;
|
||||||
module->get_module = &sys_get_module;
|
module->get_module = &sys_get_module;
|
||||||
module->mod_list_get = &mod_list_get;
|
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->delete_thread = &task_del_current;
|
||||||
module->get_time = &rtc_get_time;
|
module->get_time = &rtc_get_time;
|
||||||
|
module->ret = NULL;
|
||||||
|
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,17 @@ void *tool_memset(void *ptr, uint8_t n, uint64_t size) {
|
|||||||
return ptr;
|
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 tool_strlen(const char *str) {
|
||||||
uint64_t length = 0;
|
uint64_t length = 0;
|
||||||
while (*str) {
|
while (*str) {
|
||||||
@ -101,6 +112,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"
|
// Преобразование целого числа "i" в системе счисления "base" в строку "buf"
|
||||||
void tool_int_to_str(int64_t i, uint8_t base, char *buf) {
|
void tool_int_to_str(int64_t i, uint8_t base, char *buf) {
|
||||||
bool negative = false;
|
bool negative = false;
|
||||||
|
65
kernel/utf8cp.c
Normal file
65
kernel/utf8cp.c
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#include <mem.h>
|
||||||
|
#include <tool.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
@ -25,6 +25,9 @@ time_t (*get_time)( );
|
|||||||
uint64_t offset;
|
uint64_t offset;
|
||||||
|
|
||||||
void init_env(env_t *loader_env) {
|
void init_env(env_t *loader_env) {
|
||||||
|
if (loader_env == NULL) {
|
||||||
|
for (;;) {}
|
||||||
|
}
|
||||||
offset = loader_env->offset;
|
offset = loader_env->offset;
|
||||||
log_printf = loader_env->log_printf;
|
log_printf = loader_env->log_printf;
|
||||||
alloc = loader_env->alloc;
|
alloc = loader_env->alloc;
|
||||||
|
@ -120,6 +120,7 @@ typedef struct {
|
|||||||
uint64_t (*new_thread)(void (*func)(void *), char *name);
|
uint64_t (*new_thread)(void (*func)(void *), char *name);
|
||||||
void (*delete_thread)( );
|
void (*delete_thread)( );
|
||||||
time_t (*get_time)( );
|
time_t (*get_time)( );
|
||||||
|
module_info_t *ret;
|
||||||
} __attribute__((packed)) env_t;
|
} __attribute__((packed)) env_t;
|
||||||
|
|
||||||
#endif // types.h
|
#endif // types.h
|
||||||
|
@ -57,7 +57,7 @@ static void cpu_info( ) {
|
|||||||
log_printf(" Узлы на процессор: %u\n", nodes_per_processor);
|
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;
|
uint32_t eax, ebx, ecx, edx;
|
||||||
|
|
||||||
init_env(env);
|
init_env(env);
|
||||||
@ -77,15 +77,16 @@ module_info_t __attribute__((section(".minit"))) init(env_t *env) {
|
|||||||
cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
|
cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
|
||||||
if (eax >= 0x8000001E) { cpu_info( ); }
|
if (eax >= 0x8000001E) { cpu_info( ); }
|
||||||
|
|
||||||
return (module_info_t){ .name = (char *)"CPUBENCH",
|
env->ret = &((module_info_t){ .name = (char *)"CPUBENCH",
|
||||||
.message = (char *)"Дополнительная информация о процессоре",
|
.message = (char *)"Дополнительная информация о процессоре",
|
||||||
.type = 0,
|
.type = 0,
|
||||||
.data_size = 0,
|
.data_size = 0,
|
||||||
.data = (void *)0,
|
.data = (void *)0,
|
||||||
.err_code = 0,
|
.err_code = 0,
|
||||||
.module_id = 0,
|
.module_id = 0,
|
||||||
.irq = 0,
|
.irq = 0,
|
||||||
.irq_handler = 0,
|
.irq_handler = 0,
|
||||||
.get_func = 0,
|
.get_func = 0,
|
||||||
.after_init = 0 };
|
.after_init = 0 });
|
||||||
|
delete_thread( );
|
||||||
}
|
}
|
@ -61,20 +61,21 @@ static int app_main( ) {
|
|||||||
return 2 + 2;
|
return 2 + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
module_info_t __attribute__((section(".minit"))) init(env_t *env) {
|
void __attribute__((section(".minit"))) init(env_t *env) {
|
||||||
init_env(env);
|
init_env(env);
|
||||||
log_printf("[%s]\n", message);
|
log_printf("[%s]\n", message);
|
||||||
log_printf("%s\n", logo);
|
log_printf("%s\n", logo);
|
||||||
log_printf("%s\n", logo_synapseos);
|
log_printf("%s\n", logo_synapseos);
|
||||||
return (module_info_t){ .name = (char *)&name,
|
env->ret = &((module_info_t){ .name = (char *)&name,
|
||||||
.message = (char *)&message,
|
.message = (char *)&message,
|
||||||
.type = 0,
|
.type = 0,
|
||||||
.data_size = 0,
|
.data_size = 0,
|
||||||
.data = (void *)&app_main,
|
.data = (void *)&app_main,
|
||||||
.err_code = 0,
|
.err_code = 0,
|
||||||
.module_id = 0,
|
.module_id = 0,
|
||||||
.irq = 0,
|
.irq = 0,
|
||||||
.irq_handler = 0,
|
.irq_handler = 0,
|
||||||
.get_func = 0,
|
.get_func = 0,
|
||||||
.after_init = 0 };
|
.after_init = 0 });
|
||||||
|
delete_thread( );
|
||||||
}
|
}
|
||||||
|
@ -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);
|
init_env(env);
|
||||||
create_folder("", NULL);
|
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);
|
file_t *readme = create_file("readme", "txt", root_folder);
|
||||||
write_file(readme, "БМПОС 2023-2024", 21);
|
write_file(readme, "БМПОС 2023-2024", 21);
|
||||||
|
|
||||||
return (module_info_t){
|
env->ret = &((module_info_t){
|
||||||
.name = (char *)"[FS][IMFS]",
|
.name = (char *)"[FS][IMFS]",
|
||||||
.message = (char *)"IMFS (in memory filesystem) - файловая система работающая исключительно в ОЗУ.",
|
.message = (char *)"IMFS (in memory filesystem) - файловая система работающая исключительно в ОЗУ.",
|
||||||
.type = 0,
|
.type = 0,
|
||||||
.data_size = 0,
|
.data_size = 0,
|
||||||
.data = (void *)0,
|
.data = (void *)0,
|
||||||
.err_code = 0,
|
.err_code = 0,
|
||||||
.module_id = 0,
|
.module_id = 0,
|
||||||
.irq = 0,
|
.irq = 0,
|
||||||
.irq_handler = 0,
|
.irq_handler = 0,
|
||||||
.get_func = 0,
|
.get_func = 0,
|
||||||
.after_init = 0
|
.after_init = 0 });
|
||||||
};
|
delete_thread( );
|
||||||
}
|
}
|
||||||
|
@ -98,18 +98,19 @@ static void main( ) {
|
|||||||
for (;;) { asm volatile("hlt"); }
|
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);
|
init_env(env);
|
||||||
|
|
||||||
return (module_info_t){ .name = (char *)"[IOS]",
|
env->ret = &((module_info_t){ .name = (char *)"[IOS]",
|
||||||
.message = (char *)"IOS (input-output shell) - оболочка ввода-вывода.",
|
.message = (char *)"IOS (input-output shell) - оболочка ввода-вывода.",
|
||||||
.type = 0,
|
.type = 0,
|
||||||
.data_size = 0,
|
.data_size = 0,
|
||||||
.data = (void *)0,
|
.data = (void *)0,
|
||||||
.err_code = 0,
|
.err_code = 0,
|
||||||
.module_id = 0,
|
.module_id = 0,
|
||||||
.irq = 0,
|
.irq = 0,
|
||||||
.irq_handler = 0,
|
.irq_handler = 0,
|
||||||
.get_func = 0,
|
.get_func = 0,
|
||||||
.after_init = main };
|
.after_init = main });
|
||||||
|
delete_thread( );
|
||||||
}
|
}
|
||||||
|
@ -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);
|
init_env(env);
|
||||||
|
|
||||||
|
log_printf("pci_data %x\n", 1);
|
||||||
module_info_t *pci_data = get_module("[PCI][ADAPTER]");
|
module_info_t *pci_data = get_module("[PCI][ADAPTER]");
|
||||||
|
log_printf("pci_data %x\n", pci_data);
|
||||||
|
|
||||||
if (pci_data == NULL) {
|
if (pci_data == NULL) {
|
||||||
log_printf("Адаптер PCI данных не найден!\n");
|
log_printf("Адаптер PCI данных не найден!\n");
|
||||||
@ -129,15 +143,6 @@ module_info_t __attribute__((section(".minit"))) init(env_t *env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
scan( );
|
scan( );
|
||||||
return (module_info_t){ .name = (char *)"[PCI]",
|
env->ret = &mod;
|
||||||
.message = (char *)"PCI драйвер",
|
delete_thread( );
|
||||||
.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 };
|
|
||||||
}
|
}
|
@ -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);
|
init_env(env);
|
||||||
|
|
||||||
module_info_t *pci_data = get_module("[PCI][DATA][VENDORS]");
|
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);
|
vendor_t **vendor_list = parse_file(pci_data->data, num_vendors, pci_data->data_size);
|
||||||
// print_vendors(num_vendors, vendor_list);
|
// print_vendors(num_vendors, vendor_list);
|
||||||
return (module_info_t){ .name = (char *)"[PCI][ADAPTER]",
|
mod.data_size = num_vendors;
|
||||||
.message = (char *)"PCI данные",
|
mod.data = vendor_list;
|
||||||
.type = 0,
|
env->ret = &mod;
|
||||||
.data_size = num_vendors,
|
log_printf("Готово22\n");
|
||||||
.data = vendor_list,
|
delete_thread( );
|
||||||
.err_code = 0,
|
|
||||||
.module_id = 0,
|
|
||||||
.irq = 0,
|
|
||||||
.irq_handler = 0,
|
|
||||||
.get_func = 0,
|
|
||||||
.after_init = 0 };
|
|
||||||
}
|
}
|
@ -145,20 +145,21 @@ static void handler( ) {
|
|||||||
after_interrupt( );
|
after_interrupt( );
|
||||||
}
|
}
|
||||||
|
|
||||||
module_info_t __attribute__((section(".minit"))) init(env_t *env) {
|
void __attribute__((section(".minit"))) init(env_t *env) {
|
||||||
init_env(env);
|
init_env(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;
|
||||||
|
|
||||||
return (module_info_t){ .name = (char *)"[KEYBOARD]",
|
env->ret = &((module_info_t){ .name = (char *)"[KEYBOARD]",
|
||||||
.message = (char *)"PS/2 драйвер",
|
.message = (char *)"PS/2 драйвер",
|
||||||
.type = 0,
|
.type = 0,
|
||||||
.data_size = 0,
|
.data_size = 0,
|
||||||
.data = (void *)0,
|
.data = (void *)0,
|
||||||
.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 });
|
||||||
|
delete_thread( );
|
||||||
}
|
}
|
@ -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"
|
|
@ -1,43 +0,0 @@
|
|||||||
#include <system.h>
|
|
||||||
|
|
||||||
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 };
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 47 KiB |
Binary file not shown.
@ -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"
|
|
@ -1,189 +0,0 @@
|
|||||||
#include <system.h>
|
|
||||||
|
|
||||||
#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 };
|
|
||||||
}
|
|
4
run.sh
4
run.sh
@ -1,10 +1,10 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
qemu-system-x86_64 -name "БМПОС" -cpu max -m 64M -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.iso,if=none,id=sata_drive -device ahci \
|
||||||
-device virtio-blk-pci,drive=sata_drive \
|
-device virtio-blk-pci,drive=sata_drive \
|
||||||
-rtc base=localtime,clock=host \
|
-rtc base=localtime,clock=host \
|
||||||
--no-reboot -no-shutdown \
|
--no-reboot -no-shutdown -boot d \
|
||||||
-net nic,model=pcnet # AMD PCnet Am79C970
|
-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 -hda bmosp.hdd --no-reboot
|
||||||
#qemu-system-x86_64 -name "БМПОС" -cpu max -m 1G -smp 1 -cdrom bmosp.iso -boot d --no-reboot
|
#qemu-system-x86_64 -name "БМПОС" -cpu max -m 1G -smp 1 -cdrom bmosp.iso -boot d --no-reboot
|
||||||
|
21
scripts/github_sync.sh
Normal file
21
scripts/github_sync.sh
Normal file
@ -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
|
@ -14,9 +14,9 @@ if "^.M" in output:
|
|||||||
ARCH_FLAGS = "-m64 -march=x86-64 -mabi=sysv -mno-red-zone -mcmodel=kernel -MMD -MP"
|
ARCH_FLAGS = "-m64 -march=x86-64 -mabi=sysv -mno-red-zone -mcmodel=kernel -MMD -MP"
|
||||||
WARN_FLAGS = "-Wall -Wextra -nostdlib"
|
WARN_FLAGS = "-Wall -Wextra -nostdlib"
|
||||||
STANDART_FLAGS = f"-std=gnu11 -DKERNEL_GIT_TAG=\\\"{__VERSION}\\\"" # -DNO_DEBUG=1
|
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 = "-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"
|
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"
|
CHARSET_FLAGS = "-finput-charset=UTF-8 -fexec-charset=cp1251" #""
|
||||||
LIBS_FLAGS = "-Ilimine -Iinclude"
|
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"""
|
FORMAT_CMD = """find . \( -name "*.c" -o -name "*.h" -o -name "*.cpp" -o -name "*.hpp" \) -print0 | xargs -0 clang-format -i -style=file"""
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ def compile_all():
|
|||||||
|
|
||||||
def check_limine():
|
def check_limine():
|
||||||
if not os.path.isdir("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:
|
else:
|
||||||
os.chdir("limine")
|
os.chdir("limine")
|
||||||
subprocess.run(["git", "pull"])
|
subprocess.run(["git", "pull"])
|
||||||
@ -100,19 +100,6 @@ def check_limine():
|
|||||||
subprocess.run(["make"])
|
subprocess.run(["make"])
|
||||||
os.chdir("..")
|
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 ::/mod ::/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 limine/BOOTX64.EFI limine/BOOTIA32.EFI ::/EFI/BOOT")
|
|
||||||
os.system(f"./limine/limine bios-install {IMAGE_NAME}.hdd")
|
|
||||||
|
|
||||||
|
|
||||||
def create_iso(IMAGE_NAME):
|
def create_iso(IMAGE_NAME):
|
||||||
os.system(f"rm -f {IMAGE_NAME}.iso")
|
os.system(f"rm -f {IMAGE_NAME}.iso")
|
||||||
os.system(f"rm -rf iso_root")
|
os.system(f"rm -rf iso_root")
|
||||||
@ -165,7 +152,4 @@ if __name__ == "__main__":
|
|||||||
print("Создание ISO образа")
|
print("Создание ISO образа")
|
||||||
create_iso("bmosp")
|
create_iso("bmosp")
|
||||||
|
|
||||||
print("Создание HDD образа")
|
|
||||||
create_hdd("bmosp")
|
|
||||||
|
|
||||||
print(f"Не забудьте сохранить изменения! Номер сборки: {major}.{minor}.{build}")
|
print(f"Не забудьте сохранить изменения! Номер сборки: {major}.{minor}.{build}")
|
||||||
|
Loading…
Reference in New Issue
Block a user