Добавление программируемого интервального таймера

This commit is contained in:
Aren 2023-10-25 00:07:32 +03:00
parent fe63787821
commit 2ba30e85c6
20 changed files with 250 additions and 120 deletions

View File

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

View File

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

View File

@ -10,9 +10,22 @@
#ifndef ARCH_H #ifndef ARCH_H
#define ARCH_H #define ARCH_H
#include <stdint.h>
void arch_init( ); void arch_init( );
void cpu_init( ); void cpu_init( );
void gdt_init( ); void gdt_init( );
void idt_init( ); void idt_init( );
void idt_set_int(uint8_t vector, void *int_handler);
static inline void outb(uint16_t port, uint8_t val) {
asm volatile("outb %0, %1" : : "a"(val), "Nd"(port));
}
static inline uint8_t inb(uint16_t port) {
uint8_t ret;
asm volatile("inb %1, %0" : "=a"(ret) : "Nd"(port));
return ret;
}
#endif // arch.h #endif // arch.h

View File

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

View File

@ -1,3 +1,3 @@
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 1 #define VERSION_MINOR 1
#define VERSION_BUILD 293 #define VERSION_BUILD 297

View File

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

View File

@ -38,8 +38,8 @@ void gdt_load( ) {
load_gdt((uint64_t)&gdtr); load_gdt((uint64_t)&gdtr);
} }
void set_gdt_entry(gdt_entry_t *entry, uint16_t limit, uint64_t base, uint8_t access, void set_gdt_entry(gdt_entry_t *entry, uint16_t limit, uint64_t base,
uint8_t granularity) { uint8_t access, uint8_t granularity) {
entry->limit = limit; entry->limit = limit;
entry->base_16 = base & 0xFFFF; entry->base_16 = base & 0xFFFF;
entry->base_middle_16 = (base >> 16) & 0xFF; entry->base_middle_16 = (base >> 16) & 0xFF;

View File

@ -6,6 +6,7 @@
* *
*/ */
#include "idt.h"
#include <arch.h> #include <arch.h>
#include <fb.h> #include <fb.h>
#include <stdbool.h> #include <stdbool.h>
@ -57,39 +58,6 @@ void *isr[256];
extern void *isr_stubs[]; extern void *isr_stubs[];
static idt_ptr_t idtr; static idt_ptr_t idtr;
#define NO_NAME "Не задано название"
const char *exception_names[] = { "Деление на ноль",
"Отладка",
"NMI",
"Точка останова",
"Переполнение",
"Выход за границы",
"Недопустимая операция",
"Устройство недоступно",
"Двойное исключение",
NO_NAME,
"Недопустимый TSS",
"Сегмент не присутствует",
"Ошибка сегмента стека",
"Общая защитная ошибка",
"Ошибка страницы",
NO_NAME,
"x87 исключение",
"Проверка выравнивания",
"Ошибка машины",
"SIMD исключение",
"Виртуализация",
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
"Безопасность" };
void idt_load( ) { void idt_load( ) {
asm volatile("lidt %0" : : "m"(idtr)); asm volatile("lidt %0" : : "m"(idtr));
asm volatile("sti"); asm volatile("sti");
@ -121,9 +89,10 @@ static void exception_handler(struct frame state) {
" RIP=%x RFLAGS=%x\n" " RIP=%x RFLAGS=%x\n"
" CS=%x SS=%x\n" " CS=%x SS=%x\n"
" ERR=%x INT=%u", " ERR=%x INT=%u",
state.rax, state.rbx, state.rcx, state.rdx, state.rsi, state.rdi, state.rbp, state.rax, state.rbx, state.rcx, state.rdx, state.rsi, state.rdi,
state.rsp, state.r8, state.r9, state.r10, state.r11, state.r12, state.r13, state.r14, state.rbp, state.rsp, state.r8, state.r9, state.r10, state.r11,
state.r15, state.rip, state.rflags, state.cs, state.ss, state.err, state.int_number); state.r12, state.r13, state.r14, state.r15, state.rip,
state.rflags, state.cs, state.ss, state.err, state.int_number);
asm volatile("cli; hlt"); asm volatile("cli; hlt");
} }
@ -140,11 +109,11 @@ void idt_init( ) {
idtr = (idt_ptr_t){ .limit = sizeof(idt) - 1, .base = (uint64_t)idt }; idtr = (idt_ptr_t){ .limit = sizeof(idt) - 1, .base = (uint64_t)idt };
for (uint64_t i = 0; i < 256; i++) { for (uint64_t i = 0; i < 256; i++) {
if (i < 32) { if (i < 31) {
encode_idt_entry(i, isr_stubs[i], 0x8e); encode_idt_entry(i, isr_stubs[i], 0x8E);
isr[i] = (void *)exception_handler; isr[i] = (void *)exception_handler;
} else { } else {
encode_idt_entry(i, isr_stubs[i], 0x8e); encode_idt_entry(i, isr_stubs[i], 0x8E);
isr[i] = (void *)isr_generic; isr[i] = (void *)isr_generic;
} }
} }
@ -153,6 +122,8 @@ void idt_init( ) {
fb_printf("IDT инициализирован\n"); fb_printf("IDT инициализирован\n");
} }
void idt_set_ist(uint8_t vector, uint8_t ist) { void idt_set_int(uint8_t vector, void *int_handler) {
idt[vector].ist = ist; encode_idt_entry(vector, int_handler, 0x8E);
isr[vector] = int_handler;
idt_load( );
} }

32
kernel/arch/idt.h Normal file
View File

@ -0,0 +1,32 @@
#define NO_NAME "Не задано название"
const char *exception_names[] = { "Деление на ноль",
"Отладка",
"NMI",
"Точка останова",
"Переполнение",
"Выход за границы",
"Недопустимая операция",
"Устройство недоступно",
"Двойное исключение",
NO_NAME,
"Недопустимый TSS",
"Сегмент не присутствует",
"Ошибка сегмента стека",
"Общая защитная ошибка",
"Ошибка страницы",
NO_NAME,
"x87 исключение",
"Проверка выравнивания",
"Ошибка машины",
"SIMD исключение",
"Виртуализация",
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
"Безопасность" };

32
kernel/arch/pit.c Normal file
View File

@ -0,0 +1,32 @@
/**
* pit.c
* Программируемый интервальный таймер
*
* Настройка программируемого интервального таймера и
*
*/
#include <arch.h>
#include <fb.h>
#include <stdbool.h>
#include <stdint.h>
#include <tool.h>
static uint64_t count = 0;
static void isr_generic( ) {
fb_printf("\nТик! %u", count++);
}
void pit_set_interval(int hz) {
int divisor = 1193180 / hz; // Вычисляем делитель
outb(0x43, 0x36); // Устанавливаем байт команды 0x36
outb(0x40, divisor & 0xFF); // Устанавливаем младший байт делителя
outb(0x40, divisor >> 8); // Устанавливаем старший байт делителя
}
void pit_init( ) {
idt_set_int(32, isr_generic);
pit_set_interval(100);
asm volatile("sti");
}

View File

@ -73,10 +73,11 @@ void fb_print_buf(uint64_t x, uint64_t y, uint64_t h, uint64_t w, uint32_t *buf)
} }
} }
// Побитовый вывод из числа static inline void print_bits(size_t x, size_t y, uint8_t num) {
static inline void print_bits(uint64_t x, uint64_t y, uint8_t num) { for (size_t i = 0; i <= 7; i++) {
for (uint64_t i = 0; i <= 7; i++) { if ((num >> i) & 1) {
if ((num >> i) & 1) { SCREEN_BUFFER[x + i + y * SCREEN_WIDTH] = text_color; } SCREEN_BUFFER[x + i + y * SCREEN_WIDTH] = text_color;
}
} }
} }
@ -92,14 +93,15 @@ static void print_char(int x, int y, char glyth) {
} }
} }
// Прокрутка буффера вверх. Нижний слой удаляется void scroll_fb( ) {
static void scroll_fb( ) { size_t last_line_index =
uint64_t last_line_index = (SCREEN_HEIGHT - (FONT_6X8_SLIM_CHAR_HEIGHT)) * SCREEN_WIDTH; (SCREEN_HEIGHT - (FONT_6X8_SLIM_CHAR_HEIGHT)) * SCREEN_WIDTH;
for (uint64_t y = 0; y < SCREEN_HEIGHT - (FONT_6X8_SLIM_CHAR_HEIGHT); y++) { for (uint64_t y = 0; y < SCREEN_HEIGHT - (FONT_6X8_SLIM_CHAR_HEIGHT); y++) {
for (uint64_t x = 0; x < SCREEN_WIDTH; x++) { for (uint64_t x = 0; x < SCREEN_WIDTH; x++) {
SCREEN_BUFFER[x + y * SCREEN_WIDTH] = SCREEN_BUFFER[x + y * SCREEN_WIDTH] =
SCREEN_BUFFER[x + (y + (FONT_6X8_SLIM_CHAR_HEIGHT)) * SCREEN_WIDTH]; SCREEN_BUFFER[x +
(y + (FONT_6X8_SLIM_CHAR_HEIGHT)) * SCREEN_WIDTH];
} }
} }

View File

@ -10,7 +10,8 @@
#include <mem.h> #include <mem.h>
#include <tool.h> #include <tool.h>
#define TGA_ERR( ) fb_printf("Ошибка декодирования TGA на строчке: %u\n", __LINE__); #define TGA_ERR( ) \
fb_printf("Ошибка декодирования TGA на строчке: %u\n", __LINE__);
extern void *bootpng_ptr; extern void *bootpng_ptr;
extern uint64_t bootpng_size; extern uint64_t bootpng_size;
@ -31,7 +32,8 @@ typedef struct {
unsigned int *tga_parse(unsigned char *ptr, int size) { unsigned int *tga_parse(unsigned char *ptr, int size) {
unsigned int *data; unsigned int *data;
int i, j, k, x, y, w = (ptr[13] << 8) + ptr[12], h = (ptr[15] << 8) + ptr[14], int i, j, k, x, y, w = (ptr[13] << 8) + ptr[12],
h = (ptr[15] << 8) + ptr[14],
o = (ptr[11] << 8) + ptr[10]; o = (ptr[11] << 8) + ptr[10];
int m = ((ptr[1] ? (ptr[7] >> 3) * ptr[5] : 0) + 18); int m = ((ptr[1] ? (ptr[7] >> 3) * ptr[5] : 0) + 18);
@ -39,14 +41,15 @@ unsigned int *tga_parse(unsigned char *ptr, int size) {
data = (unsigned int *)mem_alloc((w * h + 2) * sizeof(unsigned int)); data = (unsigned int *)mem_alloc((w * h + 2) * sizeof(unsigned int));
if (!data) { if (!data) {
fb_printf("Ошибка декодирования TGA на строчке: %u, %x, %u kb\n", __LINE__, data, fb_printf("Ошибка декодирования TGA на строчке: %u, %x, %u kb\n",
((w * h + 2) * sizeof(unsigned int)) / 1024); __LINE__, data, ((w * h + 2) * sizeof(unsigned int)) / 1024);
return NULL; return NULL;
} }
switch (ptr[2]) { switch (ptr[2]) {
case 1: case 1:
if (ptr[6] != 0 || ptr[4] != 0 || ptr[3] != 0 || (ptr[7] != 24 && ptr[7] != 32)) { if (ptr[6] != 0 || ptr[4] != 0 || ptr[3] != 0 ||
(ptr[7] != 24 && ptr[7] != 32)) {
TGA_ERR( ); TGA_ERR( );
mem_free(data); mem_free(data);
return NULL; return NULL;
@ -56,12 +59,14 @@ unsigned int *tga_parse(unsigned char *ptr, int size) {
for (x = 0; x < w; x++) { for (x = 0; x < w; x++) {
j = ptr[m + k++] * (ptr[7] >> 3) + 18; j = ptr[m + k++] * (ptr[7] >> 3) + 18;
data[2 + i++] = ((ptr[7] == 32 ? ptr[j + 3] : 0xFF) << 24) | data[2 + i++] = ((ptr[7] == 32 ? ptr[j + 3] : 0xFF) << 24) |
(ptr[j + 2] << 16) | (ptr[j + 1] << 8) | ptr[j]; (ptr[j + 2] << 16) | (ptr[j + 1] << 8) |
ptr[j];
} }
} }
break; break;
case 2: case 2:
if (ptr[5] != 0 || ptr[6] != 0 || ptr[1] != 0 || (ptr[16] != 24 && ptr[16] != 32)) { if (ptr[5] != 0 || ptr[6] != 0 || ptr[1] != 0 ||
(ptr[16] != 24 && ptr[16] != 32)) {
TGA_ERR( ); TGA_ERR( );
mem_free(data); mem_free(data);
return NULL; return NULL;
@ -69,14 +74,16 @@ unsigned int *tga_parse(unsigned char *ptr, int size) {
for (y = i = 0; y < h; y++) { for (y = i = 0; y < h; y++) {
j = ((!o ? h - y - 1 : y) * w * (ptr[16] >> 3)); j = ((!o ? h - y - 1 : y) * w * (ptr[16] >> 3));
for (x = 0; x < w; x++) { for (x = 0; x < w; x++) {
data[2 + i++] = ((ptr[16] == 32 ? ptr[j + 3] : 0xFF) << 24) | data[2 + i++] =
((ptr[16] == 32 ? ptr[j + 3] : 0xFF) << 24) |
(ptr[j + 2] << 16) | (ptr[j + 1] << 8) | ptr[j]; (ptr[j + 2] << 16) | (ptr[j + 1] << 8) | ptr[j];
j += ptr[16] >> 3; j += ptr[16] >> 3;
} }
} }
break; break;
case 9: case 9:
if (ptr[6] != 0 || ptr[4] != 0 || ptr[3] != 0 || (ptr[7] != 24 && ptr[7] != 32)) { if (ptr[6] != 0 || ptr[4] != 0 || ptr[3] != 0 ||
(ptr[7] != 24 && ptr[7] != 32)) {
TGA_ERR( ); TGA_ERR( );
mem_free(data); mem_free(data);
return NULL; return NULL;
@ -93,7 +100,8 @@ unsigned int *tga_parse(unsigned char *ptr, int size) {
i = ((!o ? h - y - 1 : y) * w); i = ((!o ? h - y - 1 : y) * w);
y++; y++;
} }
data[2 + i++] = ((ptr[7] == 32 ? ptr[j + 3] : 0xFF) << 24) | data[2 + i++] =
((ptr[7] == 32 ? ptr[j + 3] : 0xFF) << 24) |
(ptr[j + 2] << 16) | (ptr[j + 1] << 8) | ptr[j]; (ptr[j + 2] << 16) | (ptr[j + 1] << 8) | ptr[j];
} }
} else { } else {
@ -105,14 +113,16 @@ unsigned int *tga_parse(unsigned char *ptr, int size) {
i = ((!o ? h - y - 1 : y) * w); i = ((!o ? h - y - 1 : y) * w);
y++; y++;
} }
data[2 + i++] = ((ptr[7] == 32 ? ptr[j + 3] : 0xFF) << 24) | data[2 + i++] =
((ptr[7] == 32 ? ptr[j + 3] : 0xFF) << 24) |
(ptr[j + 2] << 16) | (ptr[j + 1] << 8) | ptr[j]; (ptr[j + 2] << 16) | (ptr[j + 1] << 8) | ptr[j];
} }
} }
} }
break; break;
case 10: case 10:
if (ptr[5] != 0 || ptr[6] != 0 || ptr[1] != 0 || (ptr[16] != 24 && ptr[16] != 32)) { if (ptr[5] != 0 || ptr[6] != 0 || ptr[1] != 0 ||
(ptr[16] != 24 && ptr[16] != 32)) {
TGA_ERR( ); TGA_ERR( );
mem_free(data); mem_free(data);
return NULL; return NULL;
@ -128,7 +138,8 @@ unsigned int *tga_parse(unsigned char *ptr, int size) {
i = ((!o ? h - y - 1 : y) * w); i = ((!o ? h - y - 1 : y) * w);
y++; y++;
} }
data[2 + i++] = ((ptr[16] == 32 ? ptr[m + 3] : 0xFF) << 24) | data[2 + i++] =
((ptr[16] == 32 ? ptr[m + 3] : 0xFF) << 24) |
(ptr[m + 2] << 16) | (ptr[m + 1] << 8) | ptr[m]; (ptr[m + 2] << 16) | (ptr[m + 1] << 8) | ptr[m];
} }
m += ptr[16] >> 3; m += ptr[16] >> 3;
@ -140,7 +151,8 @@ unsigned int *tga_parse(unsigned char *ptr, int size) {
i = ((!o ? h - y - 1 : y) * w); i = ((!o ? h - y - 1 : y) * w);
y++; y++;
} }
data[2 + i++] = ((ptr[16] == 32 ? ptr[m + 3] : 0xFF) << 24) | data[2 + i++] =
((ptr[16] == 32 ? ptr[m + 3] : 0xFF) << 24) |
(ptr[m + 2] << 16) | (ptr[m + 1] << 8) | ptr[m]; (ptr[m + 2] << 16) | (ptr[m + 1] << 8) | ptr[m];
m += ptr[16] >> 3; m += ptr[16] >> 3;
} }
@ -165,7 +177,9 @@ void main( ) {
tga_header_t *head = (tga_header_t *)bootpng_ptr; tga_header_t *head = (tga_header_t *)bootpng_ptr;
if (res != NULL) { fb_printf("Размер экрана загрузки: %ux%u \n", res[0], res[1]); } if (res != NULL) {
fb_printf("Размер экрана загрузки: %ux%u \n", res[0], res[1]);
}
fb_printf("Размер экрана загрузки: %ux%u \n", head->h, head->w); fb_printf("Размер экрана загрузки: %ux%u \n", head->h, head->w);
mem_dump_memory( ); mem_dump_memory( );

View File

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

View File

@ -56,7 +56,9 @@ static void *elf_entry(void *module_bin, uint64_t size) {
} }
static volatile struct limine_module_request module_request = { static volatile struct limine_module_request module_request = {
.id = LIMINE_MODULE_REQUEST, .revision = 0, .response = (struct limine_module_response *)0 .id = LIMINE_MODULE_REQUEST,
.revision = 0,
.response = (struct limine_module_response *)0
}; };
static struct limine_module_response *module_response; static struct limine_module_response *module_response;
@ -74,8 +76,14 @@ void mod_init( ) {
fb_printf("->Размер: %u, тип носителя: %u, индекс раздела: %u\n", module_ptr->size, fb_printf("->Размер: %u, тип носителя: %u, индекс раздела: %u\n", module_ptr->size,
module_ptr->media_type, module_ptr->partition_index); module_ptr->media_type, module_ptr->partition_index);
#if 0 #if 0
fb_printf("[%d] %s [%s] 0x%x\n", i, module_ptr->path,
module_ptr->cmdline, module_ptr->address);
fb_printf("->Размер: %u, тип носителя: %u, индекс раздела: %u\n",
module_ptr->size, module_ptr->media_type,
module_ptr->partition_index);
fb_printf("->Идентификатор диска MBR: %u, TFTP IP: %u, TFTP порт: %u\n", fb_printf("->Идентификатор диска MBR: %u, TFTP IP: %u, TFTP порт: %u\n",
module_ptr->mbr_disk_id, module_ptr->tftp_ip, module_ptr->tftp_port); module_ptr->mbr_disk_id, module_ptr->tftp_ip,
module_ptr->tftp_port);
#endif #endif
if (tool_starts_with(module_ptr->cmdline, "[BOOTIMG]")) { if (tool_starts_with(module_ptr->cmdline, "[BOOTIMG]")) {
@ -86,8 +94,8 @@ void mod_init( ) {
} }
if (!tool_starts_with(module_ptr->cmdline, "[MOD]")) { continue; } if (!tool_starts_with(module_ptr->cmdline, "[MOD]")) { continue; }
modules_count++; modules_count++;
uint64_t (*module_init)(env_t * env) = uint64_t (*module_init)(env_t *env) = (module_info_t * (*)(env_t * env))
(module_info_t * (*)(env_t * env)) elf_entry(module_ptr->address, module_ptr->size); elf_entry(module_ptr->address, module_ptr->size);
fb_printf("\t->Точка входа: 0x%x\n", module_init); fb_printf("\t->Точка входа: 0x%x\n", module_init);

View File

@ -27,7 +27,9 @@ void _start( ) {
fb_printf("\t\t\t\t *** Базовая Модульная Платформа Операционных Систем " fb_printf("\t\t\t\t *** Базовая Модульная Платформа Операционных Систем "
"версии %u.%u.%u ***\n", "версии %u.%u.%u ***\n",
VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD); VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD);
fb_printf("\t\t\t\t *** Дата сборки: %s %s ***\n", __DATE__, __TIME__);
fb_printf("\t\t\t\t *** Дата сборки: %s %s ***\n", __DATE__, __TIME__);
pit_init( );
fb_printf("Готово!\n");
for (;;) { asm volatile("hlt"); } for (;;) { asm volatile("hlt"); }
} }

View File

@ -45,7 +45,8 @@ uint64_t tool_starts_with(const char *str, const char *prefix) {
} }
// Функция для форматированного вывода // Функция для форматированного вывода
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) {
while (*format_string != '\0') { while (*format_string != '\0') {
if (*format_string == '%') { if (*format_string == '%') {
format_string++; format_string++;

View File

@ -2,12 +2,11 @@
const char name[] = "Привет мир!"; const char name[] = "Привет мир!";
const char message[] = "Привет из модуля!"; const char message[] = "Привет из модуля!";
module_info_t static_info = { module_info_t info = { .name = (char *)&name,
.name = (char *)&name, .message = (char *)&message, .err_code = 2023, .func_count = 1 .message = (char *)&message,
}; .err_code = 2023,
.func_count = 1 };
uint64_t init(env_t *env) { uint64_t init(env_t *env) {
init_env(env);
env->fb_printf("Модуль \"Привет мир!\" инициализирован!\n");
return 0; return 0;
} }

0
modules/music/build.sh Normal file → Executable file
View File

View File

@ -14,7 +14,26 @@ static inline void usleep(uint64_t ticks) {
for (uint64_t i = 0; i < ticks * 100; i++) { asm volatile("pause"); } for (uint64_t i = 0; i < ticks * 100; i++) { asm volatile("pause"); }
} }
static inline void play_sound(unsigned int frequency) {} static inline void play_sound(unsigned int frequency) {
uint32_t div;
uint8_t tmp;
// Set the PIT to the desired frequency
div = 1193180 / frequency;
outb(0x43, 0xb6);
outb(0x42, (uint8_t)(div));
outb(0x42, (uint8_t)(div >> 8));
// And play the sound using the PC speaker
tmp = inb(0x61);
if (tmp != (tmp | 3)) { outb(0x61, tmp | 3); }
}
static void nosound( ) {
uint8_t tmp = inb(0x61) & 0xFC;
outb(0x61, tmp);
}
int init(env_t *env) { int init(env_t *env) {
init_env(env); init_env(env);