diff --git a/4 СЕМ/ОПЕРАЦИОННЫЕ СИСТЕМЫ/2 ЛАБА/bootsect.asm b/4 СЕМ/ОПЕРАЦИОННЫЕ СИСТЕМЫ/2 ЛАБА/bootsect.asm new file mode 100644 index 0000000..33365ab --- /dev/null +++ b/4 СЕМ/ОПЕРАЦИОННЫЕ СИСТЕМЫ/2 ЛАБА/bootsect.asm @@ -0,0 +1,159 @@ +.intel_syntax noprefix + +.code16 +.global _start +_start: + xor ax, ax # Clear AX + mov ds, ax # Set DS to 0 + mov es, ax # Set ES to 0 + mov ss, ax # Set SS to 0 + mov sp, 0x7C00 # Set stack pointer + + mov ax, 0x1000 # Load the address where the disk is located + mov es, ax # Set ES to point to this location + mov bx, 0 # BX = 0 + mov ah, 2 # Read sectors function + mov dl, 1 # Drive number (1 = first floppy) + mov dh, 0 # Head number + mov cl, 1 # Starting sector (1) + mov ch, 0 # Cylinder number + mov al, 88 # Number of sectors to read + int 0x13 # BIOS interrupt to read sectors + + mov ax, 0x0003 + int 0x10 + +LOAD: + xor cx, cx + xor dx, dx + mov eax, 0xe801 + int 0x15 + mov [0x3400], cx # Количество Кб до 16 Мб + mov [0x3420], dx # Количество страниц размером 64 Кб + +LOADING_OS_PRINT: + mov ah, 0x0e + mov al, 'L' + int 0x10 + mov al, 'o' + int 0x10 + mov al, 'a' + int 0x10 + mov al, 'd' + int 0x10 + mov al, 'i' + int 0x10 + mov al, 'n' + int 0x10 + mov al, 'g' + int 0x10 + mov al, ' ' + int 0x10 + mov al, 'O' + int 0x10 + mov al, 'S' + int 0x10 + mov al, '.' + int 0x10 + mov al, '.' + int 0x10 + mov al, '.' + int 0x10 + mov al, ' ' + int 0x10 + mov al, 'P' + int 0x10 + mov al, 'r' + int 0x10 + mov al, 'e' + int 0x10 + mov al, 's' + int 0x10 + mov al, 's' + int 0x10 + mov al, ' ' + int 0x10 + mov al, 's' + int 0x10 + mov al, 'p' + int 0x10 + mov al, 'a' + int 0x10 + mov al, 'c' + int 0x10 + mov al, 'e' + int 0x10 + mov al, ' ' + int 0x10 + mov al, 't' + int 0x10 + mov al, 'o' + int 0x10 + mov al, ' ' + int 0x10 + mov al, 'c' + int 0x10 + mov al, 'o' + int 0x10 + mov al, 'n' + int 0x10 + mov al, 't' + int 0x10 + mov al, 'i' + int 0x10 + mov al, 'n' + int 0x10 + mov al, 'u' + int 0x10 + mov al, 'e' + int 0x10 + mov al, '!' + int 0x10 + +input: + mov ah, 0 + int 0x16 + cmp al, 0x20 + jne input + mov ax, 0x03 + int 0x10 + +COMPLETE: + mov ax, 0x3 # Read character from keyboard + int 0x10 # BIOS interrupt for video services + + lgdt gdt_info # Load GDT + cli # Clear interrupts + in al, 0x70 # Read from port 0x70 + or al, 0x80 # Set bit 7 + out 0x70, al # Write back to port 0x70 + + mov eax, cr0 # Read control register 0 + or al, 1 # Set PE bit to enter protected mode + mov cr0, eax # Write back to CR0 + + jmp 0x8:protected_mode # Jump to protected mode + +.code32 +protected_mode: + mov ax, 0x10 # Load data segment selector + mov es, ax # Set ES + mov ds, ax # Set DS + mov ss, ax # Set SS + + call 0x10000 # Call code at new segment + +inf_loop: + jmp inf_loop # Infinite loop + +gdt: + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00 + .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00 +gdt_info: + .word gdt_info - gdt + .word gdt, 0 + +# Reserve space to ensure we have a valid boot sector +.zero (512 - ($ - _start) - 2) +.byte 0x55, 0xAA diff --git a/4 СЕМ/ОПЕРАЦИОННЫЕ СИСТЕМЫ/2 ЛАБА/kernel.cpp b/4 СЕМ/ОПЕРАЦИОННЫЕ СИСТЕМЫ/2 ЛАБА/kernel.cpp new file mode 100644 index 0000000..6f92cb5 --- /dev/null +++ b/4 СЕМ/ОПЕРАЦИОННЫЕ СИСТЕМЫ/2 ЛАБА/kernel.cpp @@ -0,0 +1,831 @@ +/* +as --32 -o bootsect.o bootsect.asm +ld -Ttext 0x7c00 --oformat binary -m elf_i386 -o bootsect.bin bootsect.o +g++ -ffreestanding -m32 -o kernel.o -c kernel.cpp +ld --oformat binary -Ttext 0x10000 -o kernel.bin --entry=kmain -m elf_i386 kernel.o +qemu -fda bootsect.bin -fdb kernel.bin +*/ + +__asm("jmp kmain"); + +#define NWORD 456 +#define CLR 0x02 +#define VIDEO_BUF_PTR (0xb8000) +#define IDT_TYPE_INTR (0x0E) +#define IDT_TYPE_TRAP (0x0F) +#define PIC1_PORT (0x20) +#define CURSOR_PORT (0x3D4) +#define VIDEO_WIDTH (80) +#define GDT_CS (0x8) + +char avb_letter[27] = { 0 }; +int avb_letter_cnt[26] = { 0 }; +int rand = 0x12000; +const char* empty_str = " "; +int str_num = 0; +int offset = 0; +unsigned int ticks = 0; +char time_os_loaded[15] = { 0 }; +unsigned short mem_h = 0; +unsigned short mem_l = 0; + +char strlen(const char *str) +{ + const char *s; + + for (s = str; *s; ++s) + ; + return (s - str); +} + +char strncmp(char *s1, char* s2, int len) +{ + int i = 0; + while (*s1 && *s2 && i < len) + { + if (*s1 != *s2) + { + return (*s1 - *s2); + } + s1++; + s2++; + i++; + } + if (i == len) + { + s1--; + s2--; + } + return (*s1 - *s2); +} + +unsigned int kbd_scan[44] = { + 0x1e, 0x30, 0x2e, 0x20, 0x12, 0x21, 0x22, 0x23, 0x17, 0x24, 0x25, 0x26, 0x32, 0x31, 0x18, 0x19, 0x10, 0x13, 0x1f, 0x14, 0x16, 0x2f, 0x11, 0x2d, 0x15, 0x2c, 0x39, 0x0d, 0x0c, 0x35, 0x1c, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0e, 0x2a, 0xAA }; +char alphabet[32] = "abcdefghijklmnopqrstuvwxyz +-/*"; +bool is_shift_pressed = false; + +char command[41] = { 0 }; + +//OBRABOTKA PRERIVANIY KLAVIATURY +////////////////////////////////////////////////////////////////// +static inline unsigned char inb(unsigned short port) +{ + unsigned char data; + asm volatile ("inb %w1, %b0": "=a" (data) : "Nd" (port)); + return data; +} + +static inline void outb(unsigned short port, unsigned char data) +{ + asm volatile ("outb %b0, %w1" : : "a" (data), "Nd" (port)); +} + +////////////////////////////////////////////////////////////////// + + +static inline void outw(unsigned short port, unsigned short data) +{ + asm volatile ("outw %w0, %w1" : : "a" (data), "Nd" (port)); +} + + +void get_cpu_vendor_id(char *vendor_id) { + unsigned int eax, ebx, ecx, edx; + // Выполняем инструкцию CPUID с EAX = 0 для получения Vendor ID + eax = 0; + asm volatile ( + "cpuid" + : "=b"(ebx), "=d"(edx), "=c"(ecx), "=a"(eax) // Выходные операнды + : "a"(eax) // Входной операнд, EAX = 0 + ); + + // Копируем Vendor ID в строку + *((unsigned int *)&vendor_id[0]) = ebx; + *((unsigned int *)&vendor_id[4]) = edx; + *((unsigned int *)&vendor_id[8]) = ecx; + // Добавляем нуль-терминатор + vendor_id[12] = '\0'; +} + +//MOVE CURSORE TO POSITION +/////////////////////////////////////////////////////////////////////// +void cursor_moveto(unsigned int strnum, unsigned int pos) +{ + unsigned short new_pos = (strnum * VIDEO_WIDTH) + pos; + outb(CURSOR_PORT, 0x0F); + outb(CURSOR_PORT + 1, (unsigned char)(new_pos & 0xFF)); + outb(CURSOR_PORT, 0x0E); + outb(CURSOR_PORT + 1, (unsigned char)((new_pos >> 8) & 0xFF)); + +} + +//////////////////////////////////////////////////////////////////////// + +// Функция для получения времени +unsigned char get_time(unsigned char reg) { + + outb(0x70, reg); // Записываем интересующий регистр в порт 0x70 + return inb(0x71); // Читаем текущее значение из порта 0x71 + +} + + +void curtime(char* buffer, unsigned int buffer_size) { + unsigned char seconds = get_time(0); // Читаем секунды + unsigned char minutes = get_time(2); // Читаем минуты + unsigned char hours = get_time(4); // Читаем часы + // Преобразуем BCD в десятичный формат + seconds = (seconds & 0x0F) + ((seconds >> 4) * 10); + minutes = (minutes & 0x0F) + ((minutes >> 4) * 10); + hours = ((hours & 0x0F) + ((hours >> 4) * 10) + 3) % 24; + // Формируем строку времени + char* ptr = buffer; + // Чаcы + *ptr++ = (hours / 10) + '0'; + *ptr++ = (hours % 10) + '0'; + *ptr++ = ':'; + // Минуты + *ptr++ = (minutes / 10) + '0'; + *ptr++ = (minutes % 10) + '0'; + *ptr++ = ':'; + // Секунды + *ptr++ = (seconds / 10) + '0'; + *ptr++ = (seconds % 10) + '0'; + // Завершаем строку + *ptr++ = '\0'; +} + + +// +void clear() { + + unsigned char* video_buf = (unsigned char*)VIDEO_BUF_PTR; + // Очищаем весь видеобуфер + for (unsigned int i = 0; i < 80 * 25; i++) { + video_buf[i * 2] = (unsigned char)' '; // Установка пробела + } + + // Сбрасываем курсор на начало + str_num = 0; + offset = 0; + cursor_moveto(str_num, offset); +} + + +void get_str(char* ptr, int strnum) +{ + unsigned char* video_buf = (unsigned char*)VIDEO_BUF_PTR; + video_buf += 80 * 2 * strnum; + + for (int i = 0; i < 40; i++, video_buf += 2) + { + ptr[i] = *video_buf; + } +} + +void print_str(const char* ptr, unsigned int strnum); + +void skip() +{ + if (str_num != 25) + return; + char temp[41] = { 0 }; + for (int i = 0; i < 24; i++) + { + get_str(temp, i + 1); + print_str(temp, i); + } + print_str(empty_str, 24); + str_num = 24; +} + +void print_str(const char* ptr, unsigned int strnum) +{ + unsigned char* video_buf = (unsigned char*)VIDEO_BUF_PTR; + video_buf += 80 * 2 * strnum; + + while (*ptr) + { + + video_buf[0] = (unsigned char)*ptr; + video_buf[1] = CLR; + video_buf += 2; + ptr++; + } + + str_num++; offset = 0; + skip(); + cursor_moveto(str_num, offset); +} + +void print_char(char chr) +{ + unsigned char* video_buf = (unsigned char*)VIDEO_BUF_PTR; + video_buf += 80 * 2 * str_num + offset * 2; + + video_buf[0] = (unsigned char)chr; + video_buf[1] = CLR; + + offset++; + cursor_moveto(str_num, offset); +} +//SHUTDOWN +//////////////////////////////////////////// +void +shutdown_power_off (void) +{ + const char s[] = "Shutdown"; + const char *p; + + str_num++; + offset = 0; + skip(); + print_str("Powering off...", str_num); + outw (0xB004, 0x2000); + outw (0x604, 0x2000); + + for (p = s; *p != '\0'; p++) + outb (0x8900, *p); + + asm("cli"); + asm("hlt"); +} +/////////////////////////////////////////////// + +struct idt_entry +{ + unsigned short base_lo; + unsigned short segm_sel; + unsigned char always0; + unsigned char flags; + unsigned short base_hi; +} __attribute__((packed)); + + +struct idt_ptr +{ + unsigned short limit; + unsigned int base; +} __attribute__((packed)); + + +//////////////////////////////////////////////////// + + +// Функция для преобразования ticks в строку + +void uint_to_string(unsigned int num, char* str_ticks) +{ + if (num == 0) { + str_ticks[0] = '0'; + str_ticks[1] = '\0'; // Завершаем строку + return; + } + + char buffer[9 + 1]; // +1 для завершающего нуля + int i = 0; + + // Заполнение буфера цифрами в обратном порядке + while (num > 0) { + buffer[i++] = '0' + (num % 10); // Получаем последнюю цифру + num /= 10; // Убираем последнюю цифру + } + + // Обратный порядок в строке + for (int j = 0; j < i; j++) { + str_ticks[j] = buffer[i - 1 - j]; + } + str_ticks[i] = '\0'; // Завершаем строку +} +/////////////////////////////////////////////////// + +void parseTime(char* timeStr, int* hours, int* minutes, int* seconds) { + *hours = (timeStr[0] - '0') * 10 + (timeStr[1] - '0'); + *minutes = (timeStr[3] - '0') * 10 + (timeStr[4] - '0'); + *seconds = (timeStr[6] - '0') * 10 + (timeStr[7] - '0'); +} + +void formatUptime(int totalSeconds, char* buffer) { + int hours = totalSeconds / 3600; + int minutes = (totalSeconds % 3600) / 60; + int seconds = totalSeconds % 60; + + char* ptr = buffer; + + // Форматируем часы + if (hours > 0) { + // Преобразуем часы в строку + if (hours >= 10) { + *ptr++ = (hours / 10) + '0'; + *ptr++ = (hours % 10) + '0'; + } + else { + *ptr++ = hours + '0'; + } + + *ptr++ = ' '; // Пробел после часов + + // Добавляем "hour" или "hours" + if (hours == 1) { + *ptr++ = 'h'; + *ptr++ = 'o'; + *ptr++ = 'u'; + *ptr++ = 'r'; + } + else { + *ptr++ = 'h'; + *ptr++ = 'o'; + *ptr++ = 'u'; + *ptr++ = 'r'; + *ptr++ = 's'; + } + + // Проверяем, нужны ли запятые + if (minutes > 0 || seconds > 0) { + *ptr++ = ','; + *ptr++ = ' '; + } + } + + // Форматируем минуты + if (minutes > 0) { + // Преобразуем минуты в строку + if (minutes >= 10) { + *ptr++ = (minutes / 10) + '0'; + *ptr++ = (minutes % 10) + '0'; + } + else { + *ptr++ = minutes + '0'; + } + + *ptr++ = ' '; // Пробел после минут + + // Добавляем "minute" или "minutes" + if (minutes == 1) { + *ptr++ = 'm'; + *ptr++ = 'i'; + *ptr++ = 'n'; + *ptr++ = 'u'; + *ptr++ = 't'; + *ptr++ = 'e'; + } + else { + *ptr++ = 'm'; + *ptr++ = 'i'; + *ptr++ = 'n'; + *ptr++ = 'u'; + *ptr++ = 't'; + *ptr++ = 'e'; + *ptr++ = 's'; + } + + // Проверяем, нужны ли запятые + if (seconds > 0) { + *ptr++ = ','; + *ptr++ = ' '; + } + } + + // Форматируем секунды + if (seconds >= 10) { + *ptr++ = (seconds / 10) + '0'; + *ptr++ = (seconds % 10) + '0'; + } + else { + *ptr++ = seconds + '0'; + } + + *ptr++ = ' '; // Пробел после секунд + + // Добавляем "second" или "seconds" + if (seconds == 1) { + *ptr++ = 's'; + *ptr++ = 'e'; + *ptr++ = 'c'; + *ptr++ = 'o'; + *ptr++ = 'n'; + *ptr++ = 'd'; + } + else { + *ptr++ = 's'; + *ptr++ = 'e'; + *ptr++ = 'c'; + *ptr++ = 'o'; + *ptr++ = 'n'; + *ptr++ = 'd'; + *ptr++ = 's'; + } + + *ptr = '\0'; // Завершаем строку +} + + +int calculateUptime(char* bootTime, char* currentTime, char* uptimeStr) { + int bootHours, bootMinutes, bootSeconds; + int currentHours, currentMinutes, currentSeconds; + + parseTime(bootTime, &bootHours, &bootMinutes, &bootSeconds); + parseTime(currentTime, ¤tHours, ¤tMinutes, ¤tSeconds); + + // Преобразуем всё в секунды + int bootTotalSeconds = bootHours * 3600 + bootMinutes * 60 + bootSeconds; + int currentTotalSeconds = currentHours * 3600 + currentMinutes * 60 + currentSeconds; + + // Вычисляем общее время работы системы + int uptimeTotalSeconds = currentTotalSeconds - bootTotalSeconds; + + // Если текущее время меньше времени включения (например, переход через полночь) + if (uptimeTotalSeconds < 0) { + uptimeTotalSeconds += 24 * 3600; // Добавляем 24 часа в секундах + } + + formatUptime(uptimeTotalSeconds, uptimeStr); + return uptimeTotalSeconds; +} + +/////////////////////////////////////////////////// + +void meminfo_command() +{ + unsigned int size = mem_h * 64 + mem_l; + char buffer[20]; + uint_to_string(size, buffer); + print_str(buffer, str_num); + print_str("Kilobytes", str_num); +} + + +//VYPOLNENIYE COMMAND +//////////////////////////////////////////////////// +void cmd_exec() { + int command_switch = 0; + + if ('\0' == strncmp(command, "info", 4)) + { + command_switch = 1; + } + else if ('\0' == strncmp(command, "help", 4)) + { + command_switch = 2; + } + else if ('\0' == strncmp(command, "clear ", 5)) + { + command_switch = 3; + } + else if ('\0' == strncmp(command, "curtime", 7)) + { + command_switch = 4; + } + else if ('\0' == strncmp(command, "shutdown", 8)) + { + command_switch = 5; + } + else if ('\0' == strncmp(command, "cpuid", 5)) + { + command_switch = 6; + } + else if ('\0' == strncmp(command, "ticks", 5)) + { + command_switch = 7; + } + else if ('\0' == strncmp(command, "loadtime", 8)) + { + command_switch = 8; + } + else if ('\0' == strncmp(command, "uptime", 6)) + { + command_switch = 9; + } + else if ('\0' == strncmp(command, "meminfo", 7)) + { + command_switch = 10; + } + else + { + command_switch = 0; + } + + switch (command_switch) { + case 1: + { + print_str("Made by ...", str_num); + print_str("...", str_num); + print_str("with: GNU Assembler, GCC, Intel syntax", str_num); + break; + } + case 2: + { + print_str("+ info - System information", str_num); + print_str("+ help - List of supported commands", str_num); + print_str("+ clear - Clear command history", str_num); + print_str("+ ticks - ticks number since the start", str_num); + print_str("+ loadtime - The time the OS was booted", str_num); + print_str("+ curtime - Current time", str_num); + print_str("+ uptime - Uptime in a readable format", str_num); + print_str("+ meminfo - Inf about available memory", str_num); + print_str("+ cpuid - Specifies the processor model", str_num); + print_str("+ shutdown - Computer shutdown", str_num); + break; + } + case 3: + { + clear(); + break; + } + case 4: + { + char time_str[50]; // Буфер для строки времени + curtime(time_str, sizeof(time_str)); + print_str(time_str, str_num); + break; + } + case 5: + { + shutdown_power_off(); + break; + } + case 6: + { + char vendor_id[13]; + get_cpu_vendor_id(vendor_id); + print_str(vendor_id, str_num); + break; + } + case 7: + { + char str_ticks[10]; + uint_to_string(ticks, str_ticks); + print_str(str_ticks, str_num); + break; + } + case 8: + { + print_str(time_os_loaded, str_num); + break; + } + case 9: + { + char currentTime[50]; // Буфер для строки времени + curtime(currentTime, sizeof(currentTime)); + char uptimeStr[100]; // Буфер для строки uptime + calculateUptime(time_os_loaded, currentTime, uptimeStr); + print_str(uptimeStr, str_num); + break; + } + case 10: + { + meminfo_command(); + break; + } + default: + { + print_str("wrong input", str_num); + break; + } + } +} +//////////////////////////////////////////////////////////////////// + + +//NAZHATIE KLAVISH +//////////////////////////////////////////////////////////////////// + +void on_key(unsigned int scan_code) +{ + int i; + for (i = 0; i < 43; i++) + { + if (scan_code == kbd_scan[i]) + break; + } + if (i == 43) + return; + if (i >= 0 && i <= 25) + { + if (is_shift_pressed == true) + { + command[offset] = alphabet[i] - (char)0x20; + print_char(alphabet[i] - (char)0x20); + } + else + { + command[offset] = alphabet[i]; + print_char(alphabet[i]); + } + } + else if (i >= 26 && i <= 29) + { + command[offset] = alphabet[i]; + print_char(alphabet[i]); + } + + else if (i == 30) + { + str_num++; + skip(); + offset = 0; + cursor_moveto(str_num, offset); + cmd_exec(); + for (int i = 0; i < 41; i++) + command[i] = '\0'; + str_num++; + skip(); + offset = 0; + cursor_moveto(str_num, offset); + } + + else if (i >= 31 && i <= 40) + { + if (is_shift_pressed) + { + command[offset] = '*'; + print_char('*'); + } + else + { + char num = (char)((kbd_scan[i] - 1) % 10 + '0'); + command[offset] = num - '0'; + print_char(num); + } + } + else + { + if (offset == 0) + return; + offset--; + command[offset] = '\0'; + print_char(' '); + offset--; + cursor_moveto(str_num, offset); + } +} +////////////////////////////////////////////////////////////////////// + + + +//SCHITIVANIE POSTUPAYSHEGO SIMVOLA +////////////////////////////////////////////////////////// +void process_shift(unsigned int scan_code) +{ + if (scan_code == kbd_scan[42]) + { + is_shift_pressed = true; + } + else if (scan_code == kbd_scan[43]) + { + is_shift_pressed = false; + } + else if (scan_code < 128 || scan_code == 0x135) + { + on_key(scan_code); + } +} +void keyb_process_keys() +{ + if (inb(0x64) & 0x01) + { + unsigned int scan_code; + scan_code = (unsigned int)inb(0x60) & 0x1FF; + + if (offset == 40 && scan_code != kbd_scan[30]) + { + return; + } + + process_shift(scan_code); + } +} + + + +//////////////////////////////////////////////////////////////////// + + +//OBRABOTCHIK PRERIVANIY +//////////////////////////////////////////////////////////////////// +void keyb_handler() +{ + asm("pusha"); + keyb_process_keys(); + outb(PIC1_PORT, 0x20); + asm("popa; leave; iret"); +} +///////////////////////////////////////////////////////////////////// + + +// Обработчик тиков + +///////////////////////////////////////////////////////////////////// + +void timer_handler() +{ + asm("pusha"); + ticks++; // Инкрементируем счетчик тиков + outb(PIC1_PORT, 0x20); // Посылаем сигнал завершения прерывания + asm("popa; leave; iret"); +} + +///////////////////////////////////////////////////////////////////// + +//PROCEDURA OBRABOTCHIK PRERIVANIY +///////////////////////////////////////////////////////////////////// + +struct idt_entry g_idt[256]; +struct idt_ptr g_idtp; +void default_interrupt_handler() +{ + asm("pusha"); + asm("popa; leave; iret"); +} + +typedef void(*interrupt_handler)(); +void interrupt_reg_handler(int num, unsigned short segm_sel, unsigned short + flags, interrupt_handler hndlr) +{ + unsigned int hndlr_addr = (unsigned int)hndlr; + + g_idt[num].base_lo = (unsigned short)(hndlr_addr & 0xFFFF); + g_idt[num].segm_sel = segm_sel; + g_idt[num].always0 = 0; + g_idt[num].flags = flags; + g_idt[num].base_hi = (unsigned short)(hndlr_addr >> 16); +} + +void keyb_init() +{ + interrupt_reg_handler(0x09, GDT_CS, 0x80 | IDT_TYPE_INTR, keyb_handler); + outb(PIC1_PORT + 1, 0xFF ^ 0x02); + +} + +void timer_init() +{ + // Регистрация обработчика прерывания + interrupt_reg_handler(8, GDT_CS, 0x80 | IDT_TYPE_INTR, timer_handler); + // segm_sel=0x8, P=1, DPL=0, Type=Intr + + // Разрешение только прерываний клавиатуры от контроллера 8259 + outb(PIC1_PORT + 1, 0xFF ^ 0x01); // 0xFF - все прерывания, 0x02 - бит IRQ1 (клавиатура) + // Разрешены будут только прерывания, чьи биты установлены в 0 +} + + +void interrupt_init() +{ + int i; + int idt_count = sizeof(g_idt) / sizeof(g_idt[0]); + + for (i = 0; i < idt_count; i++) + interrupt_reg_handler(i, GDT_CS, 0x80 | IDT_TYPE_INTR, + default_interrupt_handler); +} + +void interrupt_start() +{ + int idt_count = sizeof(g_idt) / sizeof(g_idt[0]); + + g_idtp.base = (unsigned int)(&g_idt[0]); + g_idtp.limit = (sizeof(struct idt_entry) * idt_count) - 1; + + asm("lidt %0" : : "m" (g_idtp)); +} + +void interrupt_enable() +{ + asm("sti"); +} + +void interrupt_disable() +{ + asm("cli"); +} + +extern "C" int kmain() +{ + interrupt_init(); + timer_init(); + interrupt_disable(); + keyb_init(); + interrupt_start(); + interrupt_enable(); + cursor_moveto(str_num, offset); + + curtime(time_os_loaded, sizeof(time_os_loaded)); + + char m1, m2; + m1 = (*(char*)(0x3400)); + m2 = (*(char*)(0x3420)); + mem_l = (unsigned short)m1; + mem_h = (unsigned short)m2; + + const char* hello = ".:: WELCOME TO INFO_OS ::."; + print_str(hello , str_num); + while (1) + { + outb(PIC1_PORT + 1, 0xFF ^ 0x02); + outb(PIC1_PORT + 1, 0xFF ^ 0x01); + asm("hlt"); + } + + return 0; +}