Kernel code/ru: Difference between revisions
No edit summary |
mNo edit summary |
||
(67 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
Ветка trunk ядра KolibriOS. | Ветка trunk ядра KolibriOS. | ||
Путеводитель-справочник по исходному коду. | Путеводитель-справочник по исходному коду ядра. | ||
==/== | UPD: теперь есть автособираемая doxygen документация: http://builds.kolibrios.org/doxygen/html/index.html | ||
===init.inc=== | |||
== Директория / == | |||
=== Файл init.inc === | |||
:* | Содержит функции, необходимые для инициализации системы. | ||
Инициализация системной таблицы страниц | ---- | ||
: | ==== mem_test ==== | ||
: Проводит тестирование памяти. | |||
Если bios имеет функцию 0xE820, то тестирование не производится и происходит выход из функции. | |||
==== init_mem ==== | |||
: Инициализация системной таблицы страниц | |||
==== init_page_map ==== | |||
: TODO | |||
==== init_BIOS32 ==== | |||
: TODO | |||
==== test_cpu ==== | |||
: Получение информации о процессоре. | |||
==== acpi_locate ==== | |||
: Поиск поиск структуры RSDP (Root System Description Pointer) которая используется в ACPI. | |||
: Функция возвращает указатель на RSDP в регистре eax. | |||
: см. https://wiki.osdev.org/RSDP | |||
==== rsdt_find ==== | |||
: В ecx принимает адрес RSDT, в edx сигнатуру таблицы, которую нужно найти (например ACPI_FADT_SIGN) | |||
: В eax возвращает адрес требуемой таблицы | |||
: см. https://wiki.osdev.org/RSDT | |||
==== check_acpi ==== | |||
: TODO | |||
==== init_hpet ==== | |||
: Инициализация HPET (High Perfomance Event Timer) | |||
---- | |||
=== Файл kernel32.inc === | |||
: Этот файл не содержит реализаций и является по сути заголовочным | |||
: Здесь содержатся инклуды .inc файлов почти всех подсистем ядра | |||
---- | |||
=== Файл proc32.inc === | |||
: Содержит макросы для определения и вызова процедур: | |||
---- | |||
==== stdcall proc ==== | |||
: Directly call STDCALL procedure | |||
==== invoke proc ==== | |||
: Indirectly call STDCALL procedure | |||
==== ccall proc ==== | |||
: Directly call CDECL procedure | |||
==== invoke proc ==== | |||
: Indirectly call CDECL procedure | |||
==== proc ==== | |||
: ... | |||
---- | |||
=== Файл macros.inc === | |||
: Содержит разные полезные макросы, в том числе для работы со связными списками | |||
---- | |||
==== $Revision ==== | |||
: Клиент svn при работе с репозиторием после ключевого слова $Revision: подставляет текущую ревизию файла. | |||
В macros.inc из исходников ядра, подключающемся первым, определён макрос fasm'а $Revision, который вычисляет максимум из всех мест, где он встретился (то есть во всех файлах, прямо или косвенно подключаемым к kernel.asm), каковой максимум и является номером самой свежей ревизии ядра (не драйверов). | |||
В конце kernel.asm он присваивается переменной __REV__, ну а boot/bootstr.inc включает значение __REV__ в начальную выводимую строку. | |||
==== diff16 ==== | |||
: Макрос, который вычисляет разность между вторым и первым аргументом и выводит ее на консоль в 16ичной системе счисления во время ассемблирования fasm'ом | |||
: Первый аргумент - строка с сообщением | |||
: '''Пример:''' | |||
:: diff16 "cur_saved_data (data32.inc) ", 0, $ | |||
:: cur_saved_data rb 4096 | |||
: Во время ассемблирования данного участка кода, fasm выведет "cur_saved_data (data32.inc) 0xЧИСЛО", где 0xЧИСЛО будет адресом cur_saved_data | |||
==== diff10 ==== | |||
: Аналог diff16, только в 10ичной системе. | |||
==== dbgstr ==== | |||
: Вывод строки на доску отладки. | |||
Макросы для работы со связными списками: | |||
==== list_init_head ==== | |||
: Создание списка | |||
==== __list_add ==== | |||
: Добавление в список (внутреннее использование) | |||
==== list_add ==== | |||
: Вставка в начало списка | |||
==== list_add_tail ==== | |||
: Вставка в конец списка | |||
==== list_del ==== | |||
: Удаление из списка | |||
---- | |||
=== Файл struct.inc === | |||
: Содержит макросы для объявления структур и работы с ними | |||
---- | |||
==== struct ==== | |||
: Макрос для объявления структур | |||
---- | |||
=== Файл fdo.inc === | |||
: Formatted Debug Output (FDO) | |||
: Это набор макросов для повышения удобства отладки приложений. | |||
: Работает подобно функции printf(), выводя на доску отладки форматированные сообщения. | |||
: Доступные спецификаторы формата %s, %d, %u, %x (с частичной поддержкой ширины). | |||
: Использовать обычно нужно только DEBUGF, хотя доступны также и DEBUGS, DEBUGD, DEBUGH. | |||
: '''Примеры:''' | |||
:: DEBUGF 1, "%s - %d (%x)", eax, 123, ch | |||
:: DEBUGF 1, "%d.%d.%d.%d", [ip+0]:1, [ip+1]:1, [ip+2]:1, [ip+3]:1 | |||
:: DEBUGF 1, <"function ", __FNAME__, ": %s - %x - %u">, "text here", [var]:5, [esp+16] | |||
:: DEBUGF 1, "[%d][%d][%d][%d][%d]\n", al, ax, ebx, [eax], [eax]:1 | |||
:: DEBUGF 2, "[%u][%u][%u][%u][%u]\n", al, ax, ebx, [eax], [eax]:1 | |||
:: DEBUGF 3, "[%x][%x][%x][%x][%x]\n", al, ax, ebx, [eax], [eax]:1 | |||
:: DEBUGF 4, "[%s][%s][%s][%s][%s][%s][%s]\n", "string":4, eax, eax:5, [ebx]:5, eax:ecx, eax:[ecx], eax:byte[ecx] | |||
: '''Ширина:''' | |||
:: for %s - any number, register, or in-memory variable | |||
:: for %d - 1, 2, 4 (only for in-memory arguments) | |||
:: for %u - 1, 2, 4 (only for in-memory arguments) | |||
:: for %x - 1 .. 8 | |||
---- | |||
=== Файл const.inc === | |||
: Содержит константы и объявления структур. | |||
: Распространенные сокращения: | |||
:: bk - от "back", fd - от "forward". Часто в структурах поля bk и fd означают указатель на предыдущий и следующий элемент соотв-но. | |||
:: также fd может означать "file descriptor" | |||
---- | |||
.... | |||
==== APPOBJ ==== | |||
: Структура заголовка объекта, принадлежащего приложению. Используется как составная часть некоторых других структур. | |||
: Для создания и уничтожения объектов используются следующие функции: | |||
:: - create_kernel_object/destroy_kernel_object (создание/удаления объектов ядра) | |||
:: - create_object/destroy_object (создание/удаление объектов текущего приложения (current_process)) | |||
==== CURSOR ==== | |||
: Структура курсора | |||
: TODO | |||
==== EVENT ==== | |||
: Структура события | |||
==== SMEM ==== | |||
: TODO | |||
==== SMAP ==== | |||
: TODO | |||
==== DLLDESCR ==== | |||
: TODO | |||
==== HDLL ==== | |||
: TODO | |||
==== DQ ==== | |||
: Структура, просто с двумя dd, т.е для хранения восьмибайтовых значений. | |||
==== e820entry ==== | |||
: Структура элемента карты оперативной памяти, получаемой с помощью интерфейса e820. | |||
.... | |||
==== boot_data ==== | |||
: Структура, содержащая данные, полученные при загрузке системы, различная информация о железе, биосе и т.д | |||
==== display_t ==== | |||
: Структура дл яхранения информации о дисплее. | |||
==== DISPMODE ==== | |||
: Структура, хранящая информацию о режиме дисплея: ширина, высота, кол-во байт на пиксель, частота. | |||
==== PCIDEV ==== | |||
: Структура для хранения информации об устройстве на PCI-шине. | |||
.... | |||
---- | |||
=== Файл data32.inc === | |||
: Здесь определены некоторые структуры данных ядра. | |||
: Также содержит строковые константы на различных языках (русский, английский и т.д). | |||
: Также в здесь объявлены некотрые переменные и настройки ядра | |||
: Включает в себя файлы data32sp.inc (испанский) и data32et.inc (эстонский) | |||
---- | |||
==== keymap ==== | |||
: Содежит раскладку клавиатуры (128 байт) | |||
==== keymap_shift==== | |||
: Раскладка клавиатуры при зажатой Shift | |||
==== keymap_alt ==== | |||
: Раскладка клавиатуры при зажатой Alt | |||
... - далее идут объявления констант с именами boot_* | |||
: Это те самые сообщения, которые пишутся белым шрифтом на черном фоне при загрузке KolibriOS | |||
... - далее идут константы, содержащие пути к драйверам, некоторым файлам | |||
==== shmem_list ==== | |||
: TODO | |||
==== dll_list ==== | |||
: TODO | |||
==== pcidev_list ==== | |||
: TODO | |||
... | |||
==== syslang ==== | |||
: Хранит номер языка системы (1 - en, 4 - ru и тд) | |||
==== gdts ==== | |||
Судя из названия метки: gdts = GDT Start | |||
GDT это Global Descriptor Table, глобальная таблица дескрипторов, в которой описываются сегменты памяти | |||
Далее описаны элементы этой таблицы то есть сегменты: | |||
os_code_l, int_data_l и os_data_l, app_code_l, app_data_l, pci_code_32, pci_data_32, apm_code_32, apm_code_16, apm_data_16, graph_data_l, tss0_1, tls_data_l | |||
==== gdte ==== | |||
: После описания всех сегментов стоит это метка. | |||
: Судя из названия: gdte = GDT End | |||
... | |||
==== pg_data ==== | |||
: TODO | |||
... | |||
==== sys_pgmap ==== | |||
: Таблица физических страниц. | |||
: Представляет собой массив битов, который для каждой физической страницы описывает, выделена она или свободна. | |||
... | |||
---- | |||
=== Файл kglobals.inc === | |||
: Содержит макросы для объявления глобальных данных (макросы iglobal ... endg и uglobal ... endg) | |||
:: Рассмотрим файл kglobals.inc. На первый взгляд вовсе не очевидно, что же делают определенные в нем макросы iglobal и uglobal. Их используют при объявления данных в некоторых участках кода ядра. Но зачем же они нужны? Задача этих макросов собрать данные, объявленные с помощью них, в конец компилируемого файла, чтобы добиться уменьшения размера файла (за счет отсутствия лишних выравниваний на границу align 4) и возможно лучшего сжатия, процедурой упаковки ядра. Данные, обозначенные макросом iglobal являются инициализированными и уже заранее содержат нужное значение. Также есть макрос uglobal, который также собирает данные в конец файла, но помещает их за пределами получаемого бинарника - это не инициализированные данные и содержимое их не гарантируется, хотя обычно содержит ноль. Цель макросов iglobal и uglobal — не столько уменьшение размера файла, хотя и это тоже присутствует, сколько ускорение, процессору существенно лучше, когда код и данные разделены. Данные, размещённые в uglobal, сами по себе действительно неинициализированы, но конкретно в случае ядра Колибри при загрузке выполняется код, который область uglobal явным образом обнуляет. | |||
---- | |||
==== iglobal ==== | |||
: use "iglobal" for inserting initialized global data definitions. | |||
==== uglobal ==== | |||
: use 'uglobal' for inserting uninitialized global definitions. | |||
: (even when you define some data values, these variables will be stored as uninitialized data) | |||
---- | |||
=== Файл encoding.inc === | |||
: Содержит макросы для конвертирования и объявления кодировок | |||
---- | |||
=== Файл unpacker.inc === | |||
: Это lzma-распаковщик, содержит одну единственную функцию void unpack(void* packed_data, void* unpacked_data); | |||
:: dword[packed_data + 0] -> символы 'KPCK' | |||
:: dword[packed_data + 4] -> размер unpacked_data | |||
: TODO: т.е как эта функция определяет длину packed_data? | |||
---- | |||
== Директория detect/ == | |||
=== Файл biosdisk.inc === | |||
: Получение информации о жестких дисках с помощью функций bios | |||
---- | |||
=== Файл biosmem.inc === | |||
: Получение memory map с помощую функции bios'а | |||
: memory map это структура, описывающая физическую оперативную память компьютера | |||
---- | |||
=== Файл dev_fd.inc === | |||
: Поиск и занесение в таблицу приводов FDD (Floppy Disk Drive т.е привод гибких дисков т.е дискет) | |||
---- | |||
=== Файл disks.inc === | |||
: В этом заголовочном файле просто 4 инклюда: | |||
:: include 'dev_fd.inc' | |||
:: include 'dev_hdcd.inc' | |||
:: include 'getcache.inc' | |||
:: include 'sear_par.inc' | |||
---- | |||
=== Файл init_ata.inc === | |||
: Инициализация ATA интерфейса, поиск, инициализация и настройка IDE контроллеров | |||
: Сначала идет код поиска IDE контроллера в списке pci устройств и определение его BAR регистров | |||
---- | |||
==== set_pci_command_bus_master ==== | |||
: Установить bus master бит в командный pci регистр | |||
==== Init_IDE_ATA_controller ==== | |||
: Инициализация ide контроллера | |||
==== Init_IDE_ATA_controller_2 ==== | |||
: ... | |||
---- | |||
=== Файл dev_hdcd.inc === | |||
: Поиск hdd и cd дисков, чтение информации о них, функции посылки команд на них | |||
==== FindHDD ==== | |||
: TODO | |||
==== FindHDD_2 ==== | |||
: TODO | |||
==== FindHDD_1 ==== | |||
: TODO | |||
==== сalculate_IDE_device_values_storage ==== | |||
: TODO | |||
==== convert_Sector512_value ==== | |||
: TODO | |||
==== ReadHDD_ID ==== | |||
: Чтение идентификатора жесткого диска | |||
: Входные параметры передаются через глобальные переменные: | |||
:: ChannelNumber - номер канала (1 или 2); | |||
:: DiskNumber - номер диска на канале (0 или 1). | |||
: Идентификационный блок данных считывается в массив Sector512. | |||
==== find_IDE_controller_done ==== | |||
: Инициализирует до трех ide контроллеров | |||
: Настраивает ide кэш | |||
: Ищет разделы на диске | |||
: ... | |||
: Если включен extended_primary_loader, то выполняется код из boot/rdload.inc | |||
---- | |||
=== Файл getcache.inc === | |||
: Настройка IDE кэша | |||
---- | |||
=== Файл sear_par.inc === | |||
: Поиск разделов на дисках | |||
---- | |||
=== Файл rdload.inc === | |||
: Загрузчик ram диска | |||
---- | |||
=== Файл vortex86.inc === | |||
: Обнаружение и получение информации о SoC Vortex86 для компьютеров на базе нее | |||
---- | |||
== Директория core/ == | |||
=== Файл syscall.inc === | |||
: Содержит таблицу системных вызовов и функции для осуществления системных вызовов различными способами. | |||
: TODO: чем отличаются следующие три функции? когда какая применяется? | |||
==== sysenter_entry ==== | |||
: Обработчик системного вызова с использованием технологии Intel SYSENTER/SYSEXIT (AMD CPU support it too) | |||
==== i40 ==== | |||
: Обработчик системного вызова по умолчанию, обычным способом (через прерывание 0x40 и возврат из него). | |||
==== syscall_entry ==== | |||
: Обработчик системного вызова с использованием технологии AMD SYSCALL/SYSRET | |||
==== servetable2 ==== | |||
: Это таблица системных вызовов. | |||
: Хранит адреса функций-обработчиков системных вызовов, начиная с 0ой и заканчивая 80ой. | |||
---- | |||
=== Файл apic.inc === | |||
: Реализована работа с APIC (Advanced Programmable Interrupt Controller) и PIC | |||
: APIC состоит из двух модулей - LAPIC (свой для каждого ядра процессора) и IOAPIC (контроллер на системной плате). | |||
: В начале объявлены глобальные перменные и константы. | |||
: Например переменная irq_mode обозначет текущий режим прерываний. Она принимает значение IRQ_PIC и IRQ_APIC | |||
: TODO: описать предназначение каждой перменной и константы | |||
---- | |||
==== APIC_init ==== | |||
: эта функция отвечает за APIC. | |||
: она инициализирует конроллер IOAPIC и вызывает функцию LAPIC_init | |||
==== LAPIC_init ==== | |||
: инициализация LAPIC | |||
==== IOAPIC_read ==== | |||
: чтение регистра из контроллера IOAPIC. | |||
: номер регистра передается в EAX, значение возвращеется в EAX | |||
==== IOAPIC_write ==== | |||
: запись значения в регистр контроллера IOAPIC | |||
: номер регистра передается в EAX, значение передается в EBX, функция ничего не возвращает | |||
==== PIC_init ==== | |||
: инициализация PIC (Programmable Interrupt Controller, программируетмый контроллер прерываний) | |||
: она выполняет Remap all IRQ to 0x20+ Vectors, IRQ0 to vector 0x20, IRQ1 to vector 0x21... | |||
==== PIT_init ==== | |||
: инициализирует PIT (Programmable Interval Timer, программируемый интервальный таймер) | |||
: устанавливает интервал срабатывания 1/100 секунды | |||
==== unmask_timer ==== | |||
: TODO | |||
==== IRQ_mask_all ==== | |||
: отключить все irq | |||
==== irq_eoi ==== | |||
: послать сигнал EOI (End Of Interrupt, конец прерывания). | |||
: В cl передается номер irq | |||
==== proc enable_irq stdcall, irq_line:dword ==== | |||
==== proc disable_irq stdcall, irq_line:dword ==== | |||
==== pci_irq_fixup ==== | |||
==== get_clock_ns ==== | |||
==== acpi_get_root_ptr ==== | |||
: возращает в eax Root System Description Pointer (есть такая структура данных в ACPI) | |||
---- | |||
=== Файл debug.inc === | |||
: Содержит реализазию системной функции 69 - отладка. (см. http://wiki.kolibrios.org/wiki/SysFn69/) | |||
---- | |||
=== Файл clipboard.inc === | |||
: Содержит реализацию системной функции54 - работа с буфером обмена. (см. http://wiki.kolibrios.org/wiki/SysFn54/) | |||
---- | |||
=== Файл string.inc === | |||
: Реализует следующие функции для работы со строками: | |||
:* size_t strncat(char *s1, const char *s2, size_t n); // Append string s2 to s1. | |||
:* char *strchr(const char *s, int c); // | |||
:* int strncmp(const char *s1, const char *s2, size_t n); // | |||
:* char *strncpy(char *s1, const char *s2, size_t n); // Copy string s2 to s1. | |||
:* proc strrchr stdcall, s:dword, c:dword; Look for the last occurrence a character in a string. | |||
---- | |||
=== Файл conf_lib.inc === | |||
: Загружает настройки ядра из файла /sys/sys.conf | |||
: для чтения ini использует функции libini.obj (?) | |||
---- | |||
==== proc set_kernel_conf ==== | |||
: Читает из sys.conf параметры mouse_speed, mouse_delay, midibase и применяет их | |||
==== proc strtoint ==== | |||
: конвертация строки в dword, сама оределяет hex или dec, по наличию или отсутствию 0x, 0X | |||
==== proc strtoint_dec ==== | |||
==== proc strtoint_hex ==== | |||
==== proc do_inet_adr stdcall,strs ==== | |||
: ковертировать строковую запись ip адреса в dword | |||
---- | |||
=== Файл memory.inc === | |||
==== alloc_page (proc alloc_page) ==== | |||
: функция выделения одной физической страницы. | |||
: функция ищет первую свободную физическую страницу в таблице физических страниц (sys_pgmap ?). | |||
: Найдя страницу, page_start устанавливается на следующую страницу после найденной. | |||
: но есть при следующем выове свободные страницы бцдцт искаться начиная с нее. | |||
: Система хранит массив битов, который для каждой физической страницы описывает, выделена она или свободна, | |||
: а также вспомогательные переменные: | |||
: подсказку [page_start] - нижнюю границу при поиске свободной страницы (указатель внутри битового массива, относительно которого известно, что все предшествующие данные забиты единицами, а соответствующие страницы выделены), | |||
: указатель [page_end] на конец массива, число свободных страниц [pg_data.pages_free]. | |||
: in: ничего | |||
: out: eax = физ. адрес выделенной физической страницы, или eax = 0 если свободной страницы не нашлось. | |||
==== alloc_pages (proc alloc_pages stdcall, count:dword) ==== | |||
: функция выделения нескольких физических страниц, выделяющая связный диапазон, причём кратный 8 страницам | |||
: in: требуемое количество страниц | |||
: out: eax = начальный физ. адрес выделенного диапазона страниц, или eax = 0 если не удалось выделить. | |||
==== map_page (proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword) ==== | |||
: функция отображения указанной физической страницы по указанному линейному адресу | |||
: (стандартное добавление элемента в таблицу страниц; работает и с user-mode пространством). | |||
: способная также размаппить страницу (нулевой элемент таблицы страниц соответствует свободной линейной странице). | |||
: in: | |||
: lin_addr - по какому линейному адресу отобразить страницу | |||
: phis_addr - физ. адрес отображаемой страницы | |||
: flags - какие флаги поставить на страницу (констанды этих слагов есть в data32.inc, например PG_SWR и тд) | |||
: out: ничего | |||
==== map_space ==== | |||
: объявлена, но не реализована, предназначение неясно. | |||
==== free_page (proc free_page) ==== | |||
: функция освобождения ранее выделенной физической страницы | |||
: in: eax = физ. адрес страницы | |||
: out: ничего | |||
==== map_io_mem (proc map_io_mem stdcall, base:dword, size:dword, flags:dword) ==== | |||
: функция, создающая отображение заданного блока физических страниц в адресном пространстве ядра | |||
: Как работает: вызывает alloc_kernel_space (см. core/heap.inc), а потом добавляет в таблицу страниц преобразование указанных физических адресов на только что выделенные линейные. | |||
: in: | |||
: base = начало блока | |||
: size = размер блока | |||
: flags = какие флаги поставить на виртуальные страницы | |||
: out: | |||
: eax = линейный адрес начала блока страниц | |||
==== commit_pages ==== | |||
: аналогичная map_page функция, только для блока непрерывных физических адресов. | |||
: отображает непрерывный блок физических адресов по указанному линейному адресу | |||
: in: | |||
: eax = page base + page flags | |||
: ebx = linear address | |||
: ecx = count | |||
: out: ничего | |||
==== release_pages ==== | |||
: функция, которая принимает линейный адрес и размер блока и одновременно размаппит из линейных адресов и освобождает физические страницы из этого блока. | |||
: in: | |||
: eax = base | |||
: ecx = count | |||
: out: ничего | |||
==== unmap_pages ==== | |||
: функция, обратная commit_pages. Размаппит страницы принадлежащие указанному непрерывному блоку линейных адресов. | |||
==== map_page_table ==== | |||
: TODO | |||
==== alloc_dma24 ==== | |||
: TODO | |||
==== create_trampoline_pgmap ==== | |||
: TODO | |||
==== new_mem_resize ==== | |||
: TODO | |||
==== get_pg_addr ==== | |||
: функция получения физического адреса по указанному линейному | |||
==== page_fault_handler ==== | |||
: TODO: | |||
==== map_mem_ipc ==== | |||
: TODO | |||
==== map_memEx ==== | |||
: TODO | |||
==== safe_map_page ==== | |||
: TODO | |||
==== sys_IPC ==== | |||
: реализация системной функции 60 | |||
==== sys_ipc_send ==== | |||
: реализация подфункции 2 сисфункции 60 | |||
==== sysfn_meminfo ==== | |||
: реализация подфункции 20 системной функции 18. | |||
: кстати, таблица подфункций сисфункции 18 находится в kernel.asm, это метка sys_system_table | |||
: обработчик сисфункции 18 sys_system | |||
==== f68 ==== | |||
: реализует подфункции 11-29 системной функции 68 | |||
==== f68call ==== | |||
: это таблица подфункций 11-29 системной функции 68 | |||
==== load_pe_driver ==== | |||
: эту функцию использует реализация подфункции 21 системной функции 68 | |||
==== create_ring_buffer ==== | |||
: TODO | |||
==== print_mem ==== | |||
: TODO | |||
---- | |||
=== Файл heap.inc === | |||
: в начале объявляется структура MEM_BLOCK и константы MEM_BLOCK_RESERVED, MEM_BLOCK_FREE, MEM_BLOCK_USED, MEM_BLOCK_DONT_FREE | |||
: также объявляется calc_index. | |||
---- | |||
==== md ==== | |||
: TODO | |||
==== init_kernel_heap ==== | |||
: инициализация кучи ядра. | |||
==== get_small_block ==== | |||
: найти первый блок >= требуемого размера. | |||
: аргументы eax = требуемый размер | |||
: возвращаемое значение: edi = указатель на блок; ebx= индекс блока | |||
==== free_mem_block ==== | |||
: TODO | |||
==== alloc_kernel_space ==== | |||
: Выделяет непрерывный диапазон в адресном пространстве ядра. | |||
: НО данная функция в отличие от kernel_alloc, не выделяет физических и виртуальных страниц, а лишь делает выделение в структурах кучи. | |||
: Функция alloc_kernel_space используется в kernel_alloc | |||
==== free_kernel_space ==== | |||
: Освобождает непрерывный диапазон в адресном пространстве ядра. | |||
: НО данная функция в отличие от kernel_free, не освобождает физических и виртуальных страниц, а лишь делает освобождение в структурах кучи. | |||
: Функция free_kernel_space используется в kernel_free | |||
==== kernel_alloc ==== | |||
: Выделить нужное кол-во байт в куче ядра. | |||
==== kernel_free ==== | |||
: Освободить ранее выделенную память в куче ядра. | |||
Далее функции пользовательской кучи | |||
==== init_heap ==== | |||
: TODO | |||
==== user_alloc ==== | |||
: TODO | |||
==== user_alloc_at ==== | |||
: TODO | |||
==== user_free ==== | |||
: TODO | |||
==== user_unmap ==== | |||
: TODO | |||
==== user_normalize ==== | |||
: TODO | |||
==== user_realloc ==== | |||
: TODO | |||
Далее функции shared memory | |||
==== destroy_smap ==== | |||
: TODO | |||
==== shmem_open ==== | |||
: TODO | |||
==== shmem_close ==== | |||
: TODO | |||
Далее функции user land ring buffers | |||
==== user_ring ==== | |||
: TODO | |||
---- | |||
=== Файл sys32.inc === | |||
: Функции управления задачами | |||
---- | |||
==== build_interrupt_table ==== | |||
: TODO | |||
==== page_fault_exc ==== | |||
: TODO | |||
==== show_error_parameters ==== | |||
: TODO | |||
==== lock_application_table ==== | |||
: TODO | |||
==== unlock_application_table ==== | |||
: TODO | |||
==== sys_resize_app_memory ==== | |||
: Реализация единственной подфункции 1 системной функции 64 | |||
==== terminate ==== | |||
: Завершение процесса, когда системный поток получает управление (главный цикл системы), одним из его действий является проход по списку процессов, поиск потоков в завершающемся состоянии и убийство таких процессов. Все нижеследующие действия происходят в контексте системного потока. | |||
: Захватывает доступ на запись к таблицам потоков (lock_application_table) | |||
: проходит по списку объектов ядра и вызывает деструкторы | |||
: если этот поток - последний в своём процессе, уничтожает адресное пространство | |||
: освобождает разные системные ресурсы, которые мог выделить этот поток и которых нет в списке объектов ядра (список горячих клавиш, список кнопок, определённых потоком) | |||
: если поток отлаживается, посылает извещение отладчику | |||
: освобождает память под kernel-mode стек и область сохранения FPU/SSE | |||
: освобождает карту ввода/вывода (если она была изменена - есть стандартная карта ввода/вывода, которая создаётся при загрузке и разделяется между всеми потоками) | |||
: если окно потока было на вершине оконного стека, активирует следующее окно | |||
: если поток рухнул (или был прибит) в процессе работы с жёстким диском, освобождает мьютекс занятости жёсткого диска; то же самое для CD и дискеты | |||
: освобождает выделенные потоком IRQ и порты | |||
: если текущий прибиваемый процесс - отладчик, помечает как завершающиеся все отлаживаемые им процессы | |||
: перерисовывает экран | |||
: Освобождает доступ на запись к таблицам потоков (unlock_application_table) | |||
==== destroy_thread ==== | |||
: TODO | |||
==== protect_from_terminate ==== | |||
: TODO | |||
==== unprotect_from_terminate ==== | |||
: TODO | |||
==== request_terminate ==== | |||
: TODO | |||
=== Файл sched.inc === | |||
: Планировщик задач | |||
==== irq0 ==== | |||
: обработчик прерывания интервального таймера (irq 0) | |||
: Увеличивает текущее время (число сотых долей секунды, прошедших с загрузки системы, может быть получено в приложении функцией 26.9, много где используется внутри ядра) | |||
: Вызывает процедуру обработки текущей ноты для писка, описанного в предыдущем абзаце; | |||
: Каждую 100-ю итерацию (каждую секунду) обнуляет счётчик "тактов в предыдущую секунду" (поле в структуре потока) у всех потоков; | |||
: Служит планировщиком, переключаясь на следующую задачу; алгоритм выбора описан в предыдущем посте, а при переключении увеличивается счётчик тактов у текущего потока (от которого управление уходит) и заполняются системные структуры - kernel-mode стек, карта разрешения ввода/вывода, page table (cr3), отладочные регистры drN (если нужно) и устанавливает бит TS в cr0. (Регистры CPU хранятся в системном стеке, так что popa после переключения стека автоматически восстановит регистры задачи, которая стала текущей.) Последнее действие нужно для "ленивой выгрузки" контекста FPU/MMX/SSE: если этот контекст переключать сразу, это займёт какое-то время, при том, что новая задача, возможно, вообще не использует ничего, кроме CPU; поэтому эти регистры остаются на своих местах, но устанавливается флаг TaskSwitch, в результате чего при следующем обращении к регистрам (именно обращении! когда нужно действительно переключать весь контекст) процессор возбудит исключение, обработчик которого молча сохранит регистры ушедшего потока, загрузит регистры нового потока и перезапустит инструкцию, сделав вид, что ничего не случилось. | |||
==== change_task ==== | |||
: данная функция с помощью find_next_task находит следующий таск на котрый нужно переключиться. | |||
: и переключается на него с помощью вызова do_change_task | |||
==== update_counters ==== | |||
: TODO | |||
==== updatecputimes ==== | |||
: Вычисляет TASKDATA.cpu_usage для всех тасков. | |||
==== do_change_task ==== | |||
: функция переключения контекста на заданный таск. | |||
: параметры передаются так: | |||
: ebx = address of the APPDATA for incoming task (new): warning: | |||
: [CURRENT_TASK] and [TASK_BASE] must be changed before (e.g. in find_next_task) | |||
: [current_slot] is the outcoming (old), and set here to a new value (ebx) | |||
==== scheduler_add_thread ==== | |||
: Add the given thread to the given priority list for the scheduler. | |||
: in: edx = адрес структуры потока APPDATA | |||
: ecx = приоритет | |||
==== scheduler_remove_thread ==== | |||
: Remove the given thread from the corresponding priority list for the scheduler. | |||
: in: edx = адрес структуры APPDATA потока | |||
==== find_next_task ==== | |||
: Найти новый таск для передачи ему управления | |||
: принимает аргументы: | |||
:: bl = SCHEDULE_ANY_PRIORITY: | |||
:: учитывать таски со всеми приоритетами | |||
:: bl = SCHEDULE_HIGHER_PRIORITY: | |||
:: учитывать только таски с приоритетом больше приоритета текущего таска | |||
:: продолжаем исполнять текущий таск, если не найдется готовых тасков с приоритетом меньшим чем у текущего | |||
: возвращаемое значение: | |||
:: ebx = address of the APPDATA for the selected task (slot-base) | |||
:: edi = address of the TASKDATA for the selected task | |||
:: ZF = 1 if the task is the same | |||
: Предупреждение: | |||
:: [CURRENT_TASK] = bh , [TASK_BASE] = edi -- as result | |||
:: [current_slot] is not set to new value (ebx)!!! | |||
:: scratched: eax,ecx | |||
==== pick_task ==== | |||
: TODO | |||
: Внимание: данная функция сейчас находится в блоке if 0 ... end if т.е закомментирована. | |||
==== shed ==== | |||
: TODO | |||
: Внимание: данная функция сейчас находится в блоке if 0 ... end if т.е закомментирована. | |||
==== enqueue ==== | |||
: TODO | |||
: Внимание: данная функция сейчас находится в блоке if 0 ... end if т.е закомментирована. | |||
---- | |||
=== Файл taskman.inc === | |||
==== fs_execute ==== | |||
: Создание процесса. принимает на вход имя бинарного файла для загрузки, параметры командной строки для нового процесса и флаги, сейчас только то, запускается процесс как отлаживаемый или как обычный. (edx = flags; ecx -> cmdline; ebx -> absolute file path; eax = string length ) | |||
: Загружает бинарник (целиком в память ядра; если он упакован kpack'ом, то распаковывается в памяти); | |||
: Проверяет заголовок исполняемого файла, вычисляются нужные параметры (есть две версии заголовка, мало отличающиеся); | |||
: Захватывает доступ на запись к таблицам потоков (lock_application_table) | |||
: Находит пустой слот для нового потока; если такого нет (255 потоков уже запущены) - выход с ошибкой; | |||
: Заполняет имя процесса; | |||
: Создаёт новое адресное пространство (это отдельная история); | |||
: Вызывает функцию set_app_params, заполняющую остальные поля структуры потока (подробнее - ниже); | |||
: Освобождает доступ на запись к таблицам потоков (unlock_application_table) | |||
==== test_app_header ==== | |||
: TODO | |||
==== alloc_thread_slot ==== | |||
: TODO | |||
==== create_process ==== | |||
: TODO | |||
==== destroy_page_table ==== | |||
: TODO | |||
==== destroy_process ==== | |||
: TODO | |||
==== pid_to_slot ==== | |||
: Поиск номера слота таска по его PID. | |||
: Принимает PID в eax, возращает номер слота в eax, или 0 если таска с таким PID не существует. | |||
==== check_region ==== | |||
: TODO | |||
==== read_process_memory ==== | |||
: TODO | |||
==== write_process_memory ==== | |||
: TODO | |||
==== new_sys_threads ==== | |||
: Создание нового потока. Принимает на вход entry point нового процесса и указатель на user-mode стек. | |||
: Захватывает доступ на запись к таблицам потоков (lock_application_table) | |||
: Находит пустой слот для нового потока; если такого нет - выход с ошибкой; | |||
: Копирует имя процесса и информацию об адресном пространстве вызывающего потока в структуру для нового; | |||
: Вызывает set_app_params | |||
: Освобождает доступ на запись к таблицам потоков (unlock_application_table) | |||
==== map_process_image ==== | |||
: TODO | |||
==== common_app_entry ==== | |||
: TODO | |||
==== set_app_params ==== | |||
: Выделяет в адресном пространстве ядра буфер под стек ядра и область для сохранения состояния FPU и SSE; | |||
: Инициализирует разные параметры потока значениями по умолчанию; | |||
: Копирует командную строку и путь к приложению в адресное пространство процесса по адресам, записанным в заголовке бинарника (или не копирует, если эти значения в заголовке нулевые, что означает, что программа в них не нуждается); | |||
: Выделяет очередной идентификатор (каждый следующий TID равен предыдущему + 1); | |||
: инициализирует user-mode контекст, значения eip и esp берутся из параметров вызова для sys_new_threads и из заголовка для fs_execute; | |||
: Если новый процесс загружается как отлаживаемый, то помечает его состояние как замороженное, иначе - как работающее (начиная с этого места на новый поток возможны переключения задач). | |||
==== get_stack_base ==== | |||
: TODO | |||
---- | |||
== Директория acpi/ == | |||
TODO | TODO | ||
== Директория blkdev/ == | |||
TODO | TODO | ||
== Директория boot/ == | |||
TODO | |||
== Директория bootloader/ == | |||
TODO | |||
== Директория bus/ == | |||
TODO | |||
== Директория fs/ == | |||
TODO | |||
== Директория gui/ == | |||
TODO | |||
== Директория hid/ == | |||
TODO | |||
== Директория network/ == | |||
TODO | |||
== Директория posix/ == | |||
TODO | |||
== Директория sec_loader/ == | |||
TODO | TODO | ||
== | == Директория sound/ == | ||
TODO | |||
== Директория video/ == | |||
TODO |
Latest revision as of 16:03, 6 February 2023
Ветка trunk ядра KolibriOS. Путеводитель-справочник по исходному коду ядра.
UPD: теперь есть автособираемая doxygen документация: http://builds.kolibrios.org/doxygen/html/index.html
Директория /
Файл init.inc
Содержит функции, необходимые для инициализации системы.
mem_test
- Проводит тестирование памяти.
Если bios имеет функцию 0xE820, то тестирование не производится и происходит выход из функции.
init_mem
- Инициализация системной таблицы страниц
init_page_map
- TODO
init_BIOS32
- TODO
test_cpu
- Получение информации о процессоре.
acpi_locate
- Поиск поиск структуры RSDP (Root System Description Pointer) которая используется в ACPI.
- Функция возвращает указатель на RSDP в регистре eax.
rsdt_find
- В ecx принимает адрес RSDT, в edx сигнатуру таблицы, которую нужно найти (например ACPI_FADT_SIGN)
- В eax возвращает адрес требуемой таблицы
check_acpi
- TODO
init_hpet
- Инициализация HPET (High Perfomance Event Timer)
Файл kernel32.inc
- Этот файл не содержит реализаций и является по сути заголовочным
- Здесь содержатся инклуды .inc файлов почти всех подсистем ядра
Файл proc32.inc
- Содержит макросы для определения и вызова процедур:
stdcall proc
- Directly call STDCALL procedure
invoke proc
- Indirectly call STDCALL procedure
ccall proc
- Directly call CDECL procedure
invoke proc
- Indirectly call CDECL procedure
proc
- ...
Файл macros.inc
- Содержит разные полезные макросы, в том числе для работы со связными списками
$Revision
- Клиент svn при работе с репозиторием после ключевого слова $Revision: подставляет текущую ревизию файла.
В macros.inc из исходников ядра, подключающемся первым, определён макрос fasm'а $Revision, который вычисляет максимум из всех мест, где он встретился (то есть во всех файлах, прямо или косвенно подключаемым к kernel.asm), каковой максимум и является номером самой свежей ревизии ядра (не драйверов).
В конце kernel.asm он присваивается переменной __REV__, ну а boot/bootstr.inc включает значение __REV__ в начальную выводимую строку.
diff16
- Макрос, который вычисляет разность между вторым и первым аргументом и выводит ее на консоль в 16ичной системе счисления во время ассемблирования fasm'ом
- Первый аргумент - строка с сообщением
- Пример:
- diff16 "cur_saved_data (data32.inc) ", 0, $
- cur_saved_data rb 4096
- Во время ассемблирования данного участка кода, fasm выведет "cur_saved_data (data32.inc) 0xЧИСЛО", где 0xЧИСЛО будет адресом cur_saved_data
diff10
- Аналог diff16, только в 10ичной системе.
dbgstr
- Вывод строки на доску отладки.
Макросы для работы со связными списками:
list_init_head
- Создание списка
__list_add
- Добавление в список (внутреннее использование)
list_add
- Вставка в начало списка
list_add_tail
- Вставка в конец списка
list_del
- Удаление из списка
Файл struct.inc
- Содержит макросы для объявления структур и работы с ними
struct
- Макрос для объявления структур
Файл fdo.inc
- Formatted Debug Output (FDO)
- Это набор макросов для повышения удобства отладки приложений.
- Работает подобно функции printf(), выводя на доску отладки форматированные сообщения.
- Доступные спецификаторы формата %s, %d, %u, %x (с частичной поддержкой ширины).
- Использовать обычно нужно только DEBUGF, хотя доступны также и DEBUGS, DEBUGD, DEBUGH.
- Примеры:
- DEBUGF 1, "%s - %d (%x)", eax, 123, ch
- DEBUGF 1, "%d.%d.%d.%d", [ip+0]:1, [ip+1]:1, [ip+2]:1, [ip+3]:1
- DEBUGF 1, <"function ", __FNAME__, ": %s - %x - %u">, "text here", [var]:5, [esp+16]
- DEBUGF 1, "[%d][%d][%d][%d][%d]\n", al, ax, ebx, [eax], [eax]:1
- DEBUGF 2, "[%u][%u][%u][%u][%u]\n", al, ax, ebx, [eax], [eax]:1
- DEBUGF 3, "[%x][%x][%x][%x][%x]\n", al, ax, ebx, [eax], [eax]:1
- DEBUGF 4, "[%s][%s][%s][%s][%s][%s][%s]\n", "string":4, eax, eax:5, [ebx]:5, eax:ecx, eax:[ecx], eax:byte[ecx]
- Ширина:
- for %s - any number, register, or in-memory variable
- for %d - 1, 2, 4 (only for in-memory arguments)
- for %u - 1, 2, 4 (only for in-memory arguments)
- for %x - 1 .. 8
Файл const.inc
- Содержит константы и объявления структур.
- Распространенные сокращения:
- bk - от "back", fd - от "forward". Часто в структурах поля bk и fd означают указатель на предыдущий и следующий элемент соотв-но.
- также fd может означать "file descriptor"
....
APPOBJ
- Структура заголовка объекта, принадлежащего приложению. Используется как составная часть некоторых других структур.
- Для создания и уничтожения объектов используются следующие функции:
- - create_kernel_object/destroy_kernel_object (создание/удаления объектов ядра)
- - create_object/destroy_object (создание/удаление объектов текущего приложения (current_process))
CURSOR
- Структура курсора
- TODO
EVENT
- Структура события
SMEM
- TODO
SMAP
- TODO
DLLDESCR
- TODO
HDLL
- TODO
DQ
- Структура, просто с двумя dd, т.е для хранения восьмибайтовых значений.
e820entry
- Структура элемента карты оперативной памяти, получаемой с помощью интерфейса e820.
....
boot_data
- Структура, содержащая данные, полученные при загрузке системы, различная информация о железе, биосе и т.д
display_t
- Структура дл яхранения информации о дисплее.
DISPMODE
- Структура, хранящая информацию о режиме дисплея: ширина, высота, кол-во байт на пиксель, частота.
PCIDEV
- Структура для хранения информации об устройстве на PCI-шине.
....
Файл data32.inc
- Здесь определены некоторые структуры данных ядра.
- Также содержит строковые константы на различных языках (русский, английский и т.д).
- Также в здесь объявлены некотрые переменные и настройки ядра
- Включает в себя файлы data32sp.inc (испанский) и data32et.inc (эстонский)
keymap
- Содежит раскладку клавиатуры (128 байт)
keymap_shift
- Раскладка клавиатуры при зажатой Shift
keymap_alt
- Раскладка клавиатуры при зажатой Alt
... - далее идут объявления констант с именами boot_*
- Это те самые сообщения, которые пишутся белым шрифтом на черном фоне при загрузке KolibriOS
... - далее идут константы, содержащие пути к драйверам, некоторым файлам
shmem_list
- TODO
dll_list
- TODO
pcidev_list
- TODO
...
syslang
- Хранит номер языка системы (1 - en, 4 - ru и тд)
gdts
Судя из названия метки: gdts = GDT Start
GDT это Global Descriptor Table, глобальная таблица дескрипторов, в которой описываются сегменты памяти
Далее описаны элементы этой таблицы то есть сегменты:
os_code_l, int_data_l и os_data_l, app_code_l, app_data_l, pci_code_32, pci_data_32, apm_code_32, apm_code_16, apm_data_16, graph_data_l, tss0_1, tls_data_l
gdte
- После описания всех сегментов стоит это метка.
- Судя из названия: gdte = GDT End
...
pg_data
- TODO
...
sys_pgmap
- Таблица физических страниц.
- Представляет собой массив битов, который для каждой физической страницы описывает, выделена она или свободна.
...
Файл kglobals.inc
- Содержит макросы для объявления глобальных данных (макросы iglobal ... endg и uglobal ... endg)
- Рассмотрим файл kglobals.inc. На первый взгляд вовсе не очевидно, что же делают определенные в нем макросы iglobal и uglobal. Их используют при объявления данных в некоторых участках кода ядра. Но зачем же они нужны? Задача этих макросов собрать данные, объявленные с помощью них, в конец компилируемого файла, чтобы добиться уменьшения размера файла (за счет отсутствия лишних выравниваний на границу align 4) и возможно лучшего сжатия, процедурой упаковки ядра. Данные, обозначенные макросом iglobal являются инициализированными и уже заранее содержат нужное значение. Также есть макрос uglobal, который также собирает данные в конец файла, но помещает их за пределами получаемого бинарника - это не инициализированные данные и содержимое их не гарантируется, хотя обычно содержит ноль. Цель макросов iglobal и uglobal — не столько уменьшение размера файла, хотя и это тоже присутствует, сколько ускорение, процессору существенно лучше, когда код и данные разделены. Данные, размещённые в uglobal, сами по себе действительно неинициализированы, но конкретно в случае ядра Колибри при загрузке выполняется код, который область uglobal явным образом обнуляет.
iglobal
- use "iglobal" for inserting initialized global data definitions.
uglobal
- use 'uglobal' for inserting uninitialized global definitions.
- (even when you define some data values, these variables will be stored as uninitialized data)
Файл encoding.inc
- Содержит макросы для конвертирования и объявления кодировок
Файл unpacker.inc
- Это lzma-распаковщик, содержит одну единственную функцию void unpack(void* packed_data, void* unpacked_data);
- dword[packed_data + 0] -> символы 'KPCK'
- dword[packed_data + 4] -> размер unpacked_data
- TODO: т.е как эта функция определяет длину packed_data?
Директория detect/
Файл biosdisk.inc
- Получение информации о жестких дисках с помощью функций bios
Файл biosmem.inc
- Получение memory map с помощую функции bios'а
- memory map это структура, описывающая физическую оперативную память компьютера
Файл dev_fd.inc
- Поиск и занесение в таблицу приводов FDD (Floppy Disk Drive т.е привод гибких дисков т.е дискет)
Файл disks.inc
- В этом заголовочном файле просто 4 инклюда:
- include 'dev_fd.inc'
- include 'dev_hdcd.inc'
- include 'getcache.inc'
- include 'sear_par.inc'
Файл init_ata.inc
- Инициализация ATA интерфейса, поиск, инициализация и настройка IDE контроллеров
- Сначала идет код поиска IDE контроллера в списке pci устройств и определение его BAR регистров
set_pci_command_bus_master
- Установить bus master бит в командный pci регистр
Init_IDE_ATA_controller
- Инициализация ide контроллера
Init_IDE_ATA_controller_2
- ...
Файл dev_hdcd.inc
- Поиск hdd и cd дисков, чтение информации о них, функции посылки команд на них
FindHDD
- TODO
FindHDD_2
- TODO
FindHDD_1
- TODO
сalculate_IDE_device_values_storage
- TODO
convert_Sector512_value
- TODO
ReadHDD_ID
- Чтение идентификатора жесткого диска
- Входные параметры передаются через глобальные переменные:
- ChannelNumber - номер канала (1 или 2);
- DiskNumber - номер диска на канале (0 или 1).
- Идентификационный блок данных считывается в массив Sector512.
find_IDE_controller_done
- Инициализирует до трех ide контроллеров
- Настраивает ide кэш
- Ищет разделы на диске
- ...
- Если включен extended_primary_loader, то выполняется код из boot/rdload.inc
Файл getcache.inc
- Настройка IDE кэша
Файл sear_par.inc
- Поиск разделов на дисках
Файл rdload.inc
- Загрузчик ram диска
Файл vortex86.inc
- Обнаружение и получение информации о SoC Vortex86 для компьютеров на базе нее
Директория core/
Файл syscall.inc
- Содержит таблицу системных вызовов и функции для осуществления системных вызовов различными способами.
- TODO: чем отличаются следующие три функции? когда какая применяется?
sysenter_entry
- Обработчик системного вызова с использованием технологии Intel SYSENTER/SYSEXIT (AMD CPU support it too)
i40
- Обработчик системного вызова по умолчанию, обычным способом (через прерывание 0x40 и возврат из него).
syscall_entry
- Обработчик системного вызова с использованием технологии AMD SYSCALL/SYSRET
servetable2
- Это таблица системных вызовов.
- Хранит адреса функций-обработчиков системных вызовов, начиная с 0ой и заканчивая 80ой.
Файл apic.inc
- Реализована работа с APIC (Advanced Programmable Interrupt Controller) и PIC
- APIC состоит из двух модулей - LAPIC (свой для каждого ядра процессора) и IOAPIC (контроллер на системной плате).
- В начале объявлены глобальные перменные и константы.
- Например переменная irq_mode обозначет текущий режим прерываний. Она принимает значение IRQ_PIC и IRQ_APIC
- TODO: описать предназначение каждой перменной и константы
APIC_init
- эта функция отвечает за APIC.
- она инициализирует конроллер IOAPIC и вызывает функцию LAPIC_init
LAPIC_init
- инициализация LAPIC
IOAPIC_read
- чтение регистра из контроллера IOAPIC.
- номер регистра передается в EAX, значение возвращеется в EAX
IOAPIC_write
- запись значения в регистр контроллера IOAPIC
- номер регистра передается в EAX, значение передается в EBX, функция ничего не возвращает
PIC_init
- инициализация PIC (Programmable Interrupt Controller, программируетмый контроллер прерываний)
- она выполняет Remap all IRQ to 0x20+ Vectors, IRQ0 to vector 0x20, IRQ1 to vector 0x21...
PIT_init
- инициализирует PIT (Programmable Interval Timer, программируемый интервальный таймер)
- устанавливает интервал срабатывания 1/100 секунды
unmask_timer
- TODO
IRQ_mask_all
- отключить все irq
irq_eoi
- послать сигнал EOI (End Of Interrupt, конец прерывания).
- В cl передается номер irq
proc enable_irq stdcall, irq_line:dword
proc disable_irq stdcall, irq_line:dword
pci_irq_fixup
get_clock_ns
acpi_get_root_ptr
- возращает в eax Root System Description Pointer (есть такая структура данных в ACPI)
Файл debug.inc
- Содержит реализазию системной функции 69 - отладка. (см. http://wiki.kolibrios.org/wiki/SysFn69/)
Файл clipboard.inc
- Содержит реализацию системной функции54 - работа с буфером обмена. (см. http://wiki.kolibrios.org/wiki/SysFn54/)
Файл string.inc
- Реализует следующие функции для работы со строками:
- size_t strncat(char *s1, const char *s2, size_t n); // Append string s2 to s1.
- char *strchr(const char *s, int c); //
- int strncmp(const char *s1, const char *s2, size_t n); //
- char *strncpy(char *s1, const char *s2, size_t n); // Copy string s2 to s1.
- proc strrchr stdcall, s:dword, c:dword; Look for the last occurrence a character in a string.
Файл conf_lib.inc
- Загружает настройки ядра из файла /sys/sys.conf
- для чтения ini использует функции libini.obj (?)
proc set_kernel_conf
- Читает из sys.conf параметры mouse_speed, mouse_delay, midibase и применяет их
proc strtoint
- конвертация строки в dword, сама оределяет hex или dec, по наличию или отсутствию 0x, 0X
proc strtoint_dec
proc strtoint_hex
proc do_inet_adr stdcall,strs
- ковертировать строковую запись ip адреса в dword
Файл memory.inc
alloc_page (proc alloc_page)
- функция выделения одной физической страницы.
- функция ищет первую свободную физическую страницу в таблице физических страниц (sys_pgmap ?).
- Найдя страницу, page_start устанавливается на следующую страницу после найденной.
- но есть при следующем выове свободные страницы бцдцт искаться начиная с нее.
- Система хранит массив битов, который для каждой физической страницы описывает, выделена она или свободна,
- а также вспомогательные переменные:
- подсказку [page_start] - нижнюю границу при поиске свободной страницы (указатель внутри битового массива, относительно которого известно, что все предшествующие данные забиты единицами, а соответствующие страницы выделены),
- указатель [page_end] на конец массива, число свободных страниц [pg_data.pages_free].
- in: ничего
- out: eax = физ. адрес выделенной физической страницы, или eax = 0 если свободной страницы не нашлось.
alloc_pages (proc alloc_pages stdcall, count:dword)
- функция выделения нескольких физических страниц, выделяющая связный диапазон, причём кратный 8 страницам
- in: требуемое количество страниц
- out: eax = начальный физ. адрес выделенного диапазона страниц, или eax = 0 если не удалось выделить.
map_page (proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword)
- функция отображения указанной физической страницы по указанному линейному адресу
- (стандартное добавление элемента в таблицу страниц; работает и с user-mode пространством).
- способная также размаппить страницу (нулевой элемент таблицы страниц соответствует свободной линейной странице).
- in:
- lin_addr - по какому линейному адресу отобразить страницу
- phis_addr - физ. адрес отображаемой страницы
- flags - какие флаги поставить на страницу (констанды этих слагов есть в data32.inc, например PG_SWR и тд)
- out: ничего
map_space
- объявлена, но не реализована, предназначение неясно.
free_page (proc free_page)
- функция освобождения ранее выделенной физической страницы
- in: eax = физ. адрес страницы
- out: ничего
map_io_mem (proc map_io_mem stdcall, base:dword, size:dword, flags:dword)
- функция, создающая отображение заданного блока физических страниц в адресном пространстве ядра
- Как работает: вызывает alloc_kernel_space (см. core/heap.inc), а потом добавляет в таблицу страниц преобразование указанных физических адресов на только что выделенные линейные.
- in:
- base = начало блока
- size = размер блока
- flags = какие флаги поставить на виртуальные страницы
- out:
- eax = линейный адрес начала блока страниц
commit_pages
- аналогичная map_page функция, только для блока непрерывных физических адресов.
- отображает непрерывный блок физических адресов по указанному линейному адресу
- in:
- eax = page base + page flags
- ebx = linear address
- ecx = count
- out: ничего
release_pages
- функция, которая принимает линейный адрес и размер блока и одновременно размаппит из линейных адресов и освобождает физические страницы из этого блока.
- in:
- eax = base
- ecx = count
- out: ничего
unmap_pages
- функция, обратная commit_pages. Размаппит страницы принадлежащие указанному непрерывному блоку линейных адресов.
map_page_table
- TODO
alloc_dma24
- TODO
create_trampoline_pgmap
- TODO
new_mem_resize
- TODO
get_pg_addr
- функция получения физического адреса по указанному линейному
page_fault_handler
- TODO:
map_mem_ipc
- TODO
map_memEx
- TODO
safe_map_page
- TODO
sys_IPC
- реализация системной функции 60
sys_ipc_send
- реализация подфункции 2 сисфункции 60
sysfn_meminfo
- реализация подфункции 20 системной функции 18.
- кстати, таблица подфункций сисфункции 18 находится в kernel.asm, это метка sys_system_table
- обработчик сисфункции 18 sys_system
f68
- реализует подфункции 11-29 системной функции 68
f68call
- это таблица подфункций 11-29 системной функции 68
load_pe_driver
- эту функцию использует реализация подфункции 21 системной функции 68
create_ring_buffer
- TODO
print_mem
- TODO
Файл heap.inc
- в начале объявляется структура MEM_BLOCK и константы MEM_BLOCK_RESERVED, MEM_BLOCK_FREE, MEM_BLOCK_USED, MEM_BLOCK_DONT_FREE
- также объявляется calc_index.
md
- TODO
init_kernel_heap
- инициализация кучи ядра.
get_small_block
- найти первый блок >= требуемого размера.
- аргументы eax = требуемый размер
- возвращаемое значение: edi = указатель на блок; ebx= индекс блока
free_mem_block
- TODO
alloc_kernel_space
- Выделяет непрерывный диапазон в адресном пространстве ядра.
- НО данная функция в отличие от kernel_alloc, не выделяет физических и виртуальных страниц, а лишь делает выделение в структурах кучи.
- Функция alloc_kernel_space используется в kernel_alloc
free_kernel_space
- Освобождает непрерывный диапазон в адресном пространстве ядра.
- НО данная функция в отличие от kernel_free, не освобождает физических и виртуальных страниц, а лишь делает освобождение в структурах кучи.
- Функция free_kernel_space используется в kernel_free
kernel_alloc
- Выделить нужное кол-во байт в куче ядра.
kernel_free
- Освободить ранее выделенную память в куче ядра.
Далее функции пользовательской кучи
init_heap
- TODO
user_alloc
- TODO
user_alloc_at
- TODO
user_free
- TODO
user_unmap
- TODO
user_normalize
- TODO
user_realloc
- TODO
Далее функции shared memory
destroy_smap
- TODO
shmem_open
- TODO
shmem_close
- TODO
Далее функции user land ring buffers
user_ring
- TODO
Файл sys32.inc
- Функции управления задачами
build_interrupt_table
- TODO
page_fault_exc
- TODO
show_error_parameters
- TODO
lock_application_table
- TODO
unlock_application_table
- TODO
sys_resize_app_memory
- Реализация единственной подфункции 1 системной функции 64
terminate
- Завершение процесса, когда системный поток получает управление (главный цикл системы), одним из его действий является проход по списку процессов, поиск потоков в завершающемся состоянии и убийство таких процессов. Все нижеследующие действия происходят в контексте системного потока.
- Захватывает доступ на запись к таблицам потоков (lock_application_table)
- проходит по списку объектов ядра и вызывает деструкторы
- если этот поток - последний в своём процессе, уничтожает адресное пространство
- освобождает разные системные ресурсы, которые мог выделить этот поток и которых нет в списке объектов ядра (список горячих клавиш, список кнопок, определённых потоком)
- если поток отлаживается, посылает извещение отладчику
- освобождает память под kernel-mode стек и область сохранения FPU/SSE
- освобождает карту ввода/вывода (если она была изменена - есть стандартная карта ввода/вывода, которая создаётся при загрузке и разделяется между всеми потоками)
- если окно потока было на вершине оконного стека, активирует следующее окно
- если поток рухнул (или был прибит) в процессе работы с жёстким диском, освобождает мьютекс занятости жёсткого диска; то же самое для CD и дискеты
- освобождает выделенные потоком IRQ и порты
- если текущий прибиваемый процесс - отладчик, помечает как завершающиеся все отлаживаемые им процессы
- перерисовывает экран
- Освобождает доступ на запись к таблицам потоков (unlock_application_table)
destroy_thread
- TODO
protect_from_terminate
- TODO
unprotect_from_terminate
- TODO
request_terminate
- TODO
Файл sched.inc
- Планировщик задач
irq0
- обработчик прерывания интервального таймера (irq 0)
- Увеличивает текущее время (число сотых долей секунды, прошедших с загрузки системы, может быть получено в приложении функцией 26.9, много где используется внутри ядра)
- Вызывает процедуру обработки текущей ноты для писка, описанного в предыдущем абзаце;
- Каждую 100-ю итерацию (каждую секунду) обнуляет счётчик "тактов в предыдущую секунду" (поле в структуре потока) у всех потоков;
- Служит планировщиком, переключаясь на следующую задачу; алгоритм выбора описан в предыдущем посте, а при переключении увеличивается счётчик тактов у текущего потока (от которого управление уходит) и заполняются системные структуры - kernel-mode стек, карта разрешения ввода/вывода, page table (cr3), отладочные регистры drN (если нужно) и устанавливает бит TS в cr0. (Регистры CPU хранятся в системном стеке, так что popa после переключения стека автоматически восстановит регистры задачи, которая стала текущей.) Последнее действие нужно для "ленивой выгрузки" контекста FPU/MMX/SSE: если этот контекст переключать сразу, это займёт какое-то время, при том, что новая задача, возможно, вообще не использует ничего, кроме CPU; поэтому эти регистры остаются на своих местах, но устанавливается флаг TaskSwitch, в результате чего при следующем обращении к регистрам (именно обращении! когда нужно действительно переключать весь контекст) процессор возбудит исключение, обработчик которого молча сохранит регистры ушедшего потока, загрузит регистры нового потока и перезапустит инструкцию, сделав вид, что ничего не случилось.
change_task
- данная функция с помощью find_next_task находит следующий таск на котрый нужно переключиться.
- и переключается на него с помощью вызова do_change_task
update_counters
- TODO
updatecputimes
- Вычисляет TASKDATA.cpu_usage для всех тасков.
do_change_task
- функция переключения контекста на заданный таск.
- параметры передаются так:
- ebx = address of the APPDATA for incoming task (new): warning:
- [CURRENT_TASK] and [TASK_BASE] must be changed before (e.g. in find_next_task)
- [current_slot] is the outcoming (old), and set here to a new value (ebx)
scheduler_add_thread
- Add the given thread to the given priority list for the scheduler.
- in: edx = адрес структуры потока APPDATA
- ecx = приоритет
scheduler_remove_thread
- Remove the given thread from the corresponding priority list for the scheduler.
- in: edx = адрес структуры APPDATA потока
find_next_task
- Найти новый таск для передачи ему управления
- принимает аргументы:
- bl = SCHEDULE_ANY_PRIORITY:
- учитывать таски со всеми приоритетами
- bl = SCHEDULE_HIGHER_PRIORITY:
- учитывать только таски с приоритетом больше приоритета текущего таска
- продолжаем исполнять текущий таск, если не найдется готовых тасков с приоритетом меньшим чем у текущего
- возвращаемое значение:
- ebx = address of the APPDATA for the selected task (slot-base)
- edi = address of the TASKDATA for the selected task
- ZF = 1 if the task is the same
- Предупреждение:
- [CURRENT_TASK] = bh , [TASK_BASE] = edi -- as result
- [current_slot] is not set to new value (ebx)!!!
- scratched: eax,ecx
pick_task
- TODO
- Внимание: данная функция сейчас находится в блоке if 0 ... end if т.е закомментирована.
shed
- TODO
- Внимание: данная функция сейчас находится в блоке if 0 ... end if т.е закомментирована.
enqueue
- TODO
- Внимание: данная функция сейчас находится в блоке if 0 ... end if т.е закомментирована.
Файл taskman.inc
fs_execute
- Создание процесса. принимает на вход имя бинарного файла для загрузки, параметры командной строки для нового процесса и флаги, сейчас только то, запускается процесс как отлаживаемый или как обычный. (edx = flags; ecx -> cmdline; ebx -> absolute file path; eax = string length )
- Загружает бинарник (целиком в память ядра; если он упакован kpack'ом, то распаковывается в памяти);
- Проверяет заголовок исполняемого файла, вычисляются нужные параметры (есть две версии заголовка, мало отличающиеся);
- Захватывает доступ на запись к таблицам потоков (lock_application_table)
- Находит пустой слот для нового потока; если такого нет (255 потоков уже запущены) - выход с ошибкой;
- Заполняет имя процесса;
- Создаёт новое адресное пространство (это отдельная история);
- Вызывает функцию set_app_params, заполняющую остальные поля структуры потока (подробнее - ниже);
- Освобождает доступ на запись к таблицам потоков (unlock_application_table)
test_app_header
- TODO
alloc_thread_slot
- TODO
create_process
- TODO
destroy_page_table
- TODO
destroy_process
- TODO
pid_to_slot
- Поиск номера слота таска по его PID.
- Принимает PID в eax, возращает номер слота в eax, или 0 если таска с таким PID не существует.
check_region
- TODO
read_process_memory
- TODO
write_process_memory
- TODO
new_sys_threads
- Создание нового потока. Принимает на вход entry point нового процесса и указатель на user-mode стек.
- Захватывает доступ на запись к таблицам потоков (lock_application_table)
- Находит пустой слот для нового потока; если такого нет - выход с ошибкой;
- Копирует имя процесса и информацию об адресном пространстве вызывающего потока в структуру для нового;
- Вызывает set_app_params
- Освобождает доступ на запись к таблицам потоков (unlock_application_table)
map_process_image
- TODO
common_app_entry
- TODO
set_app_params
- Выделяет в адресном пространстве ядра буфер под стек ядра и область для сохранения состояния FPU и SSE;
- Инициализирует разные параметры потока значениями по умолчанию;
- Копирует командную строку и путь к приложению в адресное пространство процесса по адресам, записанным в заголовке бинарника (или не копирует, если эти значения в заголовке нулевые, что означает, что программа в них не нуждается);
- Выделяет очередной идентификатор (каждый следующий TID равен предыдущему + 1);
- инициализирует user-mode контекст, значения eip и esp берутся из параметров вызова для sys_new_threads и из заголовка для fs_execute;
- Если новый процесс загружается как отлаживаемый, то помечает его состояние как замороженное, иначе - как работающее (начиная с этого места на новый поток возможны переключения задач).
get_stack_base
- TODO
Директория acpi/
TODO
Директория blkdev/
TODO
Директория boot/
TODO
Директория bootloader/
TODO
Директория bus/
TODO
Директория fs/
TODO
Директория gui/
TODO
Директория hid/
TODO
Директория network/
TODO
Директория posix/
TODO
Директория sec_loader/
TODO
Директория sound/
TODO
Директория video/
TODO