Kernel code/ru

From KolibriOS wiki
Jump to navigation Jump to search

Ветка trunk ядра KolibriOS. Путеводитель-справочник по исходному коду.

Директория /

Файл 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

Содержит константы и объявления структур.

....

APPOBJ

Структура объекта, принадлежащего приложению
Для создания и уничтожения объектов используются следующие функции:
- create_kernel_object/destroy_kernel_object (создание/удаления объектов ядра)
- create_object/destroy_object (создание/удаление объектов текущего приложения (current_process))

....


Файл 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

TODO

i40

TODO

syscall_entry

TODO

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

выделяет непрерывный диапазон в адресном пространстве ядра

free_kernel_space

освобождает непрерывный диапазон в адресном пространстве ядра

kernel_alloc

TODO

kernel_free

TODO

Далее функции пользовательской кучи

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

TODO

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

TODO

scheduler_remove_thread

TODO

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

shed

TODO

enqueue

TODO

Файл 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