МОДУЛЬ Машина; (** AUTHOR "pjm"; ЦЕЛЬ "Загрузка, конфигурирование и машинный интерфейс"; *)

(* Код тела этого модуля должен быть первым в статически связанном загрузочном файле. *)

ИМПОРТНАЯ СИСТЕМА, СЛЕД;

CONST
Версия = "A2 Revision 5296 (10.04.2013)";

MaxCPU* = 8; (** максимальное количество процессоров (до 16) *)

DefaultObjectFileExtension* = ".Gof";

(** биты в переменных характеристиках *)
MTTR* = 12; MMX* = 23; HTT* = 28;

MaxDisks = 2; (* максимальное количество дисков с параметрами BIOS *)

HeapAdr = 100000H;

MaxMemTop = (80000000H);

По умолчаниюDMASize = 20; (* размер области ISA DMA по умолчанию в КБ *)

CONST
StrongChecks = FALSE; (* провести тщательную проверку *)
Stats* = FALSE; (* получение статистики *)
TimeCount = 0 (* 100000 *); (* количество попыток блокировки перед проверкой тайм-аута - 0 для отключения *)

(** стандартные уровни блокировки (по порядку) *) (* также см. Traps.Show *)
TraceOutput* = 0;    (* Вывод трассировки *)
Память* = 1;    (* Управление виртуальной памятью, распределение стека и страниц *)
Кучи* = 2;        (* Распределение памяти и сбор мусора *)
Прерывания* = 3 ;    (* Обработка прерываний. *)
Модули* = 4;    (* Список модулей *)
Объекты* = 5;    (* Готовая очередь *)
Процессоры* = 6; (* Интерпроцессорные прерывания *)
KernelLog* = 7;    (* Атомарный вывод *)
(** самый высокий уровень - все блокировки объектов *)

Преемственность* = 31; (** флаг для BreakAll *)

MaxLocks = 8; (* { <= 32 } *)

LowestLock = 0; HighestLock = MaxLocks-1;

CONST
TraceVerbose = TRUE; (* записывать подробную информацию о трассировке *)

AddressSize = SIZEOF(ADDRESS);
SetSize = MAX (SET) + 1;

(** коды ошибок *)
Ok* = 0;

(* стандартные множители *)
K = 1024; (* 1 Кб = 0400H *)
M = 100000H; (* 1K, 1M *)

(* размеры подкачки *)
PS = 4096;    (* размер страницы в байтах *)
PSlog2 = 12;    (* ASH(1, PSlog2) = PS *)
RS = 4*M;    (* область, покрываемая таблицей страниц в байтах *)
PTEs = RS DIV PS; (* количество записей в таблице страниц/каталоге *)

ReservedPages = 8; (* страницы, зарезервированные в куче страниц (не для обычного использования кучи) *)

NilAdr* = -1;    (** нулевое значение для адресов (не то же самое, что значение NIL указателя) *)

(* свободный макет узла страницы стека страниц *)
NodeSP = 0;
NodeNext = AddressSize;
NodePrev = AddressSize*2;
MinSP = AddressSize*3; MaxSP = PS;

(*
0 сп
AddressSize nextAdr
AddressSize*2 prevAdr
AddressSize*3 первая запись
4092 последняя запись
*)

(* расположение виртуальной памяти. ни одна область не будет пересекать границу 2G, чтобы избежать проблем со знаком SIGNED32. *)
MapAreaAdr = (80000000H); (* динамические отображения: нижняя часть 2G...4G *)
MapAreaSize = 64*M;
IntelAreaAdr = (0FEE00000H); (* зарезервировано Intel для APIC: 4G-18M..4G-18M+4K *)
IntelAreaSize = 00001000H;
StackAreaAdr = MapAreaAdr+MapAreaSize; (* стеки: средняя часть 2G...4G *)
StackAreaSize = IntelAreaAdr-StackAreaAdr;

(* размеры стека *)
KernelStackSize = 2*PS;    (* кратно PS *)
MaxUserStackSize = 512*K; (* кратно PS *)
InitUserStackSize = PS;    (* должен быть PS (или изменить NewStack) *)
UserStackGuardSize = PS; (* кратное PS, оставшееся нераспределенным в нижней части виртуальной области стека *)
MaxUserStacks = StackAreaSize DIV MaxUserStackSize;

(* расположение физической памяти *)
LowAdr = PS;        (* наименьший используемый физический адрес *)
LinkAdr = M;        (* адрес, по которому ссылается ядро, также адрес, по которому начинается куча *)
StaticBlockSize = 32;    (* статический размер блока кучи *)
BlockHeaderSize = 2 * AddressSize;
RecordDescSize = 4 * AddressSize;  (* необходимо адаптировать в случае изменения Heaps.RecordDesc *)

(* индексы gdt *)
TSSOfs = 6;        (* смещение в GDT TSSs *)
StackOfs = TSSOfs + MaxCPU; (* смещение в GDT стеков *)
GDTSize = StackOfs + MaxCPU;

(* селекторы gdt *)
KernelCodeSel = 1*8;    (* селектор 1 в gdt, RPL 0 *)
KernelStackSel = 2*8;    (* селектор 2 в gdt, RPL 0 *)
UserCodeSel = 3*8 + 3;    (* селектор 3 в gdt, RPL 3 *)
DataSel = 4*8;        (* селектор 4 в gdt, RPL 0 *)
UserStackSel = 5*8 + 3;    (* селектор 5 в gdt, RPL 3 *)
KernelTR = TSSOfs*8;    (* селектор в gdt, RPL 0 *)

(* флаги подкачки *)
PageNotPresent = 0;    (*не присутствует на странице*)
KernelPage = 3;        (* супервизор, присутствие, r/w *)
UserPage = 7;        (* пользователь, присутствует, r/w *)

HeapMin = 50;        (* "минимум" размер кучи в процентах от общего объема памяти (используется для расширения кучи в рамках GC ) *)
HeapMax = 95;        (* "максимум" размер кучи в процентах от общего объема памяти (используется для расширения кучи в рамках GC) *)
ExpandRate = 1;        (* всегда расширяйте кучу по крайней мере на этот процент от общего объема памяти *)
Порог = 10;        (* периодический GC инициируется, когда этот процент байтов общего объема памяти "прошел через" NewBlock *)
InitialHeapIncrement = 4096;

HeaderSize = 40H; (* ср. Linker0 *)
EndBlockOfs = 38H; (* ср. Linker0 *)
MemoryBlockOfs = BlockHeaderSize + RecordDescSize + BlockHeaderSize; (* блок памяти (включая заголовок) начинается со смещения HeaderSize *)

CONST
(** предопределенные прерывания 0-31, используются с InstallHandler *)