Subversion Repositories Kolibri OS

Rev

Rev 1962 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1962 Rev 3539
Line 22... Line 22...
22
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
;*****************************************************************************
25
;*****************************************************************************
Line 26... Line 26...
26
 
26
 
Line 27... Line 27...
27
					×èòàé ìåæäó ñòðîê - òàì íèêîãäà íå áûâàåò îïå÷àòîê.
27
					Читай между строк - там никогда не бывает опечаток.
Line 28... Line 28...
28
 
28
 
Line 29... Line 29...
29
Áóòñåêòîð äëÿ FAT32-òîìà íà íîñèòåëå ñ ðàçìåðîì ñåêòîðà 0x200 = 512 áàéò.
29
Бутсектор для FAT32-тома на носителе с размером сектора 0x200 = 512 байт.
30
 
30
 
31
=====================================================================
31
=====================================================================
32
 
32
 
33
Åñòü äâå âåðñèè â çàâèñèìîñòè îò òîãî, ïîääåðæèâàåò ëè íîñèòåëü LBA,
33
Есть две версии в зависимости от того, поддерживает ли носитель LBA,
34
âûáîð îñóùåñòâëÿåòñÿ óñòàíîâêîé êîíñòàíòû use_lba â ïåðâîé ñòðîêå èñõîäíèêà.
34
выбор осуществляется установкой константы use_lba в первой строке исходника.
35
Òðåáîâàíèÿ äëÿ ðàáîòû:
35
Требования для работы:
36
1) Ñàì áóòñåêòîð, ïåðâàÿ êîïèÿ FAT è âñå èñïîëüçóåìûå ôàéëû
36
1) Сам бутсектор, первая копия FAT и все используемые файлы
37
äîëæíû áûòü ÷èòàáåëüíû. (Åñëè äåëî ïðîèñõîäèò íà íîñèòåëå ñ ðàçáèåíèåì íà
37
должны быть читабельны. (Если дело происходит на носителе с разбиением на
38
ðàçäåëû è çàãðóçî÷íûé êîä â MBR äîñòàòî÷íî óìíûé, òî ÷èòàáåëüíîñòè ðåçåðâíîé
38
разделы и загрузочный код в MBR достаточно умный, то читабельности резервной
Line 39... Line 39...
39
êîïèè áóòñåêòîðà (ñåêòîð íîìåð 6 íà òîìå) äîñòàòî÷íî âìåñòî ÷èòàáåëüíîñòè
39
копии бутсектора (сектор номер 6 на томе) достаточно вместо читабельности
Line 40... Line 40...
40
ñàìîãî áóòñåêòîðà).
40
самого бутсектора).
41
2) Ìèíèìàëüíûé ïðîöåññîð - 80386.
41
2) Минимальный процессор - 80386.
42
3) Â ñèñòåìå äîëæíî áûòü êàê ìèíèìóì 584K ñâîáîäíîé áàçîâîé ïàìÿòè.
42
3) В системе должно быть как минимум 584K свободной базовой памяти.
43
 
43
 
44
=====================================================================
44
=====================================================================
45
 
45
 
46
Äîêóìåíòàöèÿ â òåìó (ññûëêè ïðîâåðÿëèñü íà âàëèäíîñòü 15.05.2008):
46
Документация в тему (ссылки проверялись на валидность 15.05.2008):
47
	îôèöèàëüíàÿ ñïåöèôèêàöèÿ FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
47
	официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
Line 48... Line 48...
48
		â ôîðìàòå PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf
48
		в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf
Line 49... Line 49...
49
		ðóññêèé ïåðåâîä: http://wasm.ru/docs/11/fatgen103-rus.zip
49
		русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip
50
	îôèöèàëüíàÿ ñïåöèôèêàöèÿ ðàñøèðåíèÿ EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf
50
	официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf
51
		òî æå, âåðñèÿ 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf
51
		то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf
52
	îïèñàíèå ôóíêöèé BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html
52
	описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html
53
	îôèöèàëüíàÿ ñïåöèôèêàöèÿ Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf
53
	официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf
54
 
54
 
55
=====================================================================
55
=====================================================================
56
 
56
 
57
Ñõåìà èñïîëüçóåìîé ïàìÿòè:
57
Схема используемой памяти:
58
	...-7C00	ñòåê
58
	...-7C00	стек
59
	7C00-7E00	êîä áóòñåêòîðà
59
	7C00-7E00	код бутсектора
60
	7E00-8200	âñïîìîãàòåëüíûé ôàéë çàãðóç÷èêà (kordldr.f32)
60
	7E00-8200	вспомогательный файл загрузчика (kordldr.f32)
61
	8400-8C00	èíôîðìàöèÿ î êýøå äëÿ òàáëèöû FAT: 100h âõîäîâ ïî 8
61
	8400-8C00	информация о кэше для таблицы FAT: 100h входов по 8
62
			áàéò: 4 áàéòà (äâå ññûëêè - âïåð¸ä è íàçàä) äëÿ
62
			байт: 4 байта (две ссылки - вперёд и назад) для
63
			îðãàíèçàöèè L2-ñïèñêà âñåõ ïðî÷èòàííûõ ñåêòîðîâ â
63
			организации L2-списка всех прочитанных секторов в
64
			ïîðÿäêå âîçðàñòàíèÿ ïîñëåäíåãî âðåìåíè èñïîëüçîâàíèÿ
64
			порядке возрастания последнего времени использования
65
			+ 4 áàéòà äëÿ íîìåðà ñåêòîðà; ïðè ïåðåïîëíåíèè êýøà
65
			+ 4 байта для номера сектора; при переполнении кэша
66
			âûêèäûâàåòñÿ ýëåìåíò èç ãîëîâû ñïèñêà, òî åñòü òîò,
66
			выкидывается элемент из головы списка, то есть тот,
67
			ê êîòîðîìó äîëüøå âñåõ íå áûëî îáðàùåíèé
67
			к которому дольше всех не было обращений
Line 68... Line 68...
68
	60000-80000	êýø äëÿ òàáëèöû FAT (100h ñåêòîðîâ)
68
	60000-80000	кэш для таблицы FAT (100h секторов)
Line 69... Line 69...
69
	80000-90000	òåêóùèé êëàñòåð òåêóùåé ðàññìàòðèâàåìîé ïàïêè
69
	80000-90000	текущий кластер текущей рассматриваемой папки
70
	90000-...	êýø äëÿ ñîäåðæèìîãî ïàïîê (êàæäîé ïàïêå îòâîäèòñÿ
70
	90000-...	кэш для содержимого папок (каждой папке отводится
71
			2000h áàéò = 100h âõîäîâ, îäíîâðåìåííî â êýøå
71
			2000h байт = 100h входов, одновременно в кэше
72
			ìîæåò íàõîäèòüñÿ íå áîëåå 8 ïàïîê;
72
			может находиться не более 8 папок;
73
			òî÷íûé ðàçìåð îïðåäåëÿåòñÿ ðàçìåðîì äîñòóïíîé
73
			точный размер определяется размером доступной
74
			ôèçè÷åñêîé ïàìÿòè - êàê ïðàâèëî, íåïîñðåäñòâåííî
74
			физической памяти - как правило, непосредственно
75
			ïåðåä A0000 ðàçìåùàåòñÿ EBDA, Extended BIOS Data Area)
75
			перед A0000 размещается EBDA, Extended BIOS Data Area)
76
 
76
 
77
=====================================================================
77
=====================================================================
78
 
78
 
79
Îñíîâíîé ïðîöåññ çàãðóçêè.
79
Основной процесс загрузки.
80
Òî÷êà âõîäà (start): ïîëó÷àåò óïðàâëåíèå îò BIOS ïðè çàãðóçêå, ïðè ýòîì
80
Точка входа (start): получает управление от BIOS при загрузке, при этом
81
	dl ñîäåðæèò èäåíòèôèêàòîð äèñêà, ñ êîòîðîãî èä¸ò çàãðóçêà
81
	dl содержит идентификатор диска, с которого идёт загрузка
82
1. Íàñòðàèâàåò ñòåê ss:sp = 0:7C00 (ñòåê ðàñïîëàãàåòñÿ íåïîñðåäñòâåííî ïåðåä
82
1. Настраивает стек ss:sp = 0:7C00 (стек располагается непосредственно перед
83
	êîäîì), ñåãìåíò äàííûõ ds = 0, è óñòàíàâëèâàåò ss:bp íà íà÷àëî
83
	кодом), сегмент данных ds = 0, и устанавливает ss:bp на начало
84
	áóòñåêòîðà (â äàëüíåéøåì äàííûå áóäóò àäðåñîâàòüñÿ ÷åðåç [bp+N] -
84
	бутсектора (в дальнейшем данные будут адресоваться через [bp+N] -
85
	ýòî îñâîáîæäàåò ds è ýêîíîìèò íà ðàçìåðå êîäà). Ñîõðàíÿåò â ñòåêå
85
	это освобождает ds и экономит на размере кода). Сохраняет в стеке
86
	èäåíòèôèêàòîð çàãðóçî÷íîãî äèñêà äëÿ ïîñëåäóþùåãî îáðàùåíèÿ
86
	идентификатор загрузочного диска для последующего обращения
87
	÷åðåç byte [bp-2].
87
	через byte [bp-2].
88
2. LBA-âåðñèÿ: ïðîâåðÿåò, ïîääåðæèâàåò ëè íîñèòåëü LBA, âûçîâîì ôóíêöèè 41h
88
2. LBA-версия: проверяет, поддерживает ли носитель LBA, вызовом функции 41h
89
	ïðåðûâàíèÿ 13h. Åñëè íåò, ïåðåõîäèò íà êîä îáðàáîòêè îøèáîê ñ
89
	прерывания 13h. Если нет, переходит на код обработки ошибок с
90
	ñîîáùåíèåì îá îòñóòñòâèè LBA.
90
	сообщением об отсутствии LBA.
91
CHS-âåðñèÿ: îïðåäåëÿåò ãåîìåòðèþ íîñèòåëÿ âûçîâîì ôóíêöèè 8 ïðåðûâàíèÿ 13h è
91
CHS-версия: определяет геометрию носителя вызовом функции 8 прерывания 13h и
92
	çàïèñûâàåò ïîëó÷åííûå äàííûå ïîâåðõ BPB. Åñëè âûçîâ çàâåðøèëñÿ îøèáêîé,
92
	записывает полученные данные поверх BPB. Если вызов завершился ошибкой,
93
	ïðåäïîëàãàåò óæå ñóùåñòâóþùèå äàííûå êîððåêòíûìè.
93
	предполагает уже существующие данные корректными.
94
3. Âû÷èñëÿåò íà÷àëî äàííûõ FAT-òîìà, ñîõðàíÿåò åãî â ñòåê äëÿ ïîñëåäóþùåãî
94
3. Вычисляет начало данных FAT-тома, сохраняет его в стек для последующего
95
	îáðàùåíèÿ ÷åðåç dword [bp-10].  ïðîöåññå âû÷èñëåíèÿ óçíà¸ò íà÷àëî
95
	обращения через dword [bp-10]. В процессе вычисления узнаёт начало
96
	ïåðâîé FAT, ñîõðàíÿåò è åãî â ñòåê äëÿ ïîñëåäóþùåãî îáðàùåíèÿ ÷åðåç
96
	первой FAT, сохраняет и его в стек для последующего обращения через
97
	dword [bp-6].
97
	dword [bp-6].
98
4. (Çàêàí÷èâàÿ òåìó ïàðàìåòðîâ â ñòåêå) Ïîìåùàåò â ñòåê dword-çíà÷åíèå -1
98
4. (Заканчивая тему параметров в стеке) Помещает в стек dword-значение -1
99
	äëÿ ïîñëåäóþùåãî îáðàùåíèÿ ÷åðåç dword [bp-14] - èíèöèàëèçàöèÿ
99
	для последующего обращения через dword [bp-14] - инициализация
100
	ïåðåìåííîé, ñîäåðæàùåé òåêóùèé ñåêòîð, íàõîäÿùèéñÿ â êýøå FAT
100
	переменной, содержащей текущий сектор, находящийся в кэше FAT
101
	(-1 íå ÿâëÿåòñÿ âàëèäíûì çíà÷åíèåì äëÿ íîìåðà ñåêòîðà FAT).
101
	(-1 не является валидным значением для номера сектора FAT).
102
5. Èùåò â êîðíåâîé ïàïêå ýëåìåíò kordldr.f32. Åñëè íå íàõîäèò - ïåðåõîäèò íà
102
5. Ищет в корневой папке элемент kordldr.f32. Если не находит - переходит на
103
	êîä îáðàáîòêè îøèáîê ñ ñîîáùåíèåì î íåíàéäåííîì çàãðóç÷èêå.
103
	код обработки ошибок с сообщением о ненайденном загрузчике.
104
	Çàìå÷àíèå: íà ýòîì ýòàïå çàãðóçêè èñêàòü ìîæíî òîëüêî â êîðíåâîé
104
	Замечание: на этом этапе загрузки искать можно только в корневой
105
	ïàïêå è òîëüêî èìåíà, çàäàííûå â ôîðìàòå ôàéëîâîé ñèñòåìå FAT
105
	папке и только имена, заданные в формате файловой системе FAT
106
	(8+3 - 8 áàéò íà èìÿ, 3 áàéòà íà ðàñøèðåíèå, âñå áóêâû äîëæíû
106
	(8+3 - 8 байт на имя, 3 байта на расширение, все буквы должны
107
	áûòü çàãëàâíûìè, ïðè íåîáõîäèìîñòè èìÿ è ðàñøèðåíèå äîïîëíÿþòñÿ
107
	быть заглавными, при необходимости имя и расширение дополняются
108
	ïðîáåëàìè, ðàçäåëÿþùåé òî÷êè íåò, çàâåðøàþùåãî íóëÿ íåò).
108
	пробелами, разделяющей точки нет, завершающего нуля нет).
109
6. Çàãðóæàåò ïåðâûé êëàñòåð ôàéëà kordldr.f32 ïî àäðåñó 0:7E00 è ïåðåäà¸ò
109
6. Загружает первый кластер файла kordldr.f32 по адресу 0:7E00 и передаёт
110
	åìó óïðàâëåíèå. Ïðè ýòîì â ðåãèñòðå eax îêàçûâàåòñÿ àáñîëþòíûé
110
	ему управление. При этом в регистре eax оказывается абсолютный
Line 111... Line 111...
111
	íîìåð ïåðâîãî ñåêòîðà kordldr.f32, à â cx - ÷èñëî ñ÷èòàííûõ ñåêòîðîâ
111
	номер первого сектора kordldr.f32, а в cx - число считанных секторов
112
	(ðàâíîå ðàçìåðó êëàñòåðà).
112
	(равное размеру кластера).
113
 
113
 
114
Âñïîìîãàòåëüíûå ïðîöåäóðû áóòñåêòîðà.
114
Вспомогательные процедуры бутсектора.
115
Êîä îáðàáîòêè îøèáîê (err):
115
Код обработки ошибок (err):
116
1. Âûâîäèò ñòðîêó ñ ñîîáùåíèåì îá îøèáêå.
116
1. Выводит строку с сообщением об ошибке.
117
2. Âûâîäèò ñòðîêó "Press any key...".
117
2. Выводит строку "Press any key...".
118
3. Æä¸ò íàæàòèÿ any key.
118
3. Ждёт нажатия any key.
119
4. Âûçûâàåò int 18h, äàâàÿ øàíñ BIOSó ïîïûòàòüñÿ çàãðóçèòüñÿ îòêóäà-íèáóäü åù¸.
119
4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё.
120
5. Äëÿ ïîäñòðàõîâêè çàöèêëèâàåòñÿ.
120
5. Для подстраховки зацикливается.
Line 121... Line 121...
121
 
121
 
122
Ïðîöåäóðà ÷òåíèÿ êëàñòåðà (read_cluster):
122
Процедура чтения кластера (read_cluster):
123
íà âõîäå äîëæíî áûòü óñòàíîâëåíî:
123
на входе должно быть установлено:
124
	ss:bp = 0:7C00
124
	ss:bp = 0:7C00
125
	es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå
125
	es:bx = указатель на начало буфера, куда будут прочитаны данные
126
	eax = íîìåð êëàñòåðà
126
	eax = номер кластера
127
íà âûõîäå: ecx = ÷èñëî ïðî÷èòàííûõ ñåêòîðîâ (ðàçìåð êëàñòåðà),
127
на выходе: ecx = число прочитанных секторов (размер кластера),
128
	es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå,
128
	es:bx указывает на конец буфера, в который были прочитаны данные,
129
	eax è ñòàðøèå ñëîâà äðóãèõ 32-áèòíûõ ðåãèñòðîâ ðàçðóøàþòñÿ
129
	eax и старшие слова других 32-битных регистров разрушаются
130
Çàãðóæàåò â ecx ðàçìåð êëàñòåðà, ïåðåêîäèðóåò íîìåð êëàñòåðà â íîìåð ñåêòîðà
130
Загружает в ecx размер кластера, перекодирует номер кластера в номер сектора
131
è ïåðåõîäèò ê ñëåäóþùåé ïðîöåäóðå.
131
и переходит к следующей процедуре.
132
 
132
 
133
Ïðîöåäóðà ÷òåíèÿ ñåêòîðîâ (read_sectors32 è read_sectors2):
133
Процедура чтения секторов (read_sectors32 и read_sectors2):
134
íà âõîäå äîëæíî áûòü óñòàíîâëåíî:
134
на входе должно быть установлено:
135
	ss:bp = 0:7C00
135
	ss:bp = 0:7C00
136
	es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå
136
	es:bx = указатель на начало буфера, куда будут прочитаны данные
137
	eax = ñòàðòîâûé ñåêòîð (îòíîñèòåëüíî íà÷àëà ëîãè÷åñêîãî äèñêà
137
	eax = стартовый сектор (относительно начала логического диска
138
		äëÿ read_sectors32, îòíîñèòåëüíî íà÷àëà äàííûõ
138
		для read_sectors32, относительно начала данных
139
		äëÿ read_sectors2)
139
		для read_sectors2)
140
	cx = ÷èñëî ñåêòîðîâ (äîëæíî áûòü áîëüøå íóëÿ)
140
	cx = число секторов (должно быть больше нуля)
141
íà âûõîäå: es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå
141
на выходе: es:bx указывает на конец буфера, в который были прочитаны данные
142
	ñòàðøèå ñëîâà 32-áèòíûõ ðåãèñòðîâ ìîãóò ðàçðóøèòüñÿ
142
	старшие слова 32-битных регистров могут разрушиться
143
0. Åñëè âûçûâàåòñÿ read_sectors2, îíà ïåðåâîäèò óêàçàííûé åé íîìåð ñåêòîðà
143
0. Если вызывается read_sectors2, она переводит указанный ей номер сектора
144
	â íîìåð îòíîñèòåëüíî íà÷àëà ëîãè÷åñêîãî äèñêà, ïðèáàâëÿÿ íîìåð ñåêòîðà
144
	в номер относительно начала логического диска, прибавляя номер сектора
145
	íà÷àëà äàííûõ, õðàíÿùèéñÿ â ñòåêå êàê [bp-10].
145
	начала данных, хранящийся в стеке как [bp-10].
146
1. Ïåðåâîäèò ñòàðòîâûé ñåêòîð (îòñ÷èòûâàåìûé îò íà÷àëà òîìà) â ñåêòîð íà
146
1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на
147
	óñòðîéñòâå, ïðèáàâëÿÿ çíà÷åíèå ñîîòâåòñòâóþùåãî ïîëÿ èç BPB.
147
	устройстве, прибавляя значение соответствующего поля из BPB.
148
2.  öèêëå (øàãè 3-6) ÷èòàåò ñåêòîðû, ñëåäèò çà òåì, ÷òîáû íà êàæäîé èòåðàöèè
148
2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации
149
	CHS-âåðñèÿ: âñå ÷èòàåìûå ñåêòîðû áûëè íà îäíîé äîðîæêå.
149
	CHS-версия: все читаемые секторы были на одной дорожке.
150
	LBA-âåðñèÿ: ÷èñëî ÷èòàåìûõ ñåêòîðîâ íå ïðåâîñõîäèëî 7Fh (òðåáîâàíèå
150
	LBA-версия: число читаемых секторов не превосходило 7Fh (требование
151
	ñïåöèôèêàöèè EDD BIOS).
151
	спецификации EDD BIOS).
152
CHS-âåðñèÿ:
152
CHS-версия:
153
3. Ïåðåâîäèò àáñîëþòíûé íîìåð ñåêòîðà â CHS-ñèñòåìó: ñåêòîð ðàññ÷èòûâàåòñÿ êàê
153
3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как
154
	åäèíèöà ïëþñ îñòàòîê îò äåëåíèÿ àáñîëþòíîãî íîìåðà íà ÷èñëî ñåêòîðîâ
154
	единица плюс остаток от деления абсолютного номера на число секторов
155
	íà äîðîæêå; äîðîæêà ðàññ÷èòûâàåòñÿ êàê îñòàòîê îò äåëåíèÿ ÷àñòíîãî,
155
	на дорожке; дорожка рассчитывается как остаток от деления частного,
156
	ïîëó÷åííîãî íà ïðåäûäóùåì øàãå, íà ÷èñëî äîðîæåê, à öèëèíäð - êàê
156
	полученного на предыдущем шаге, на число дорожек, а цилиндр - как
157
	÷àñòíîå îò ýòîãî æå äåëåíèÿ. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå,
157
	частное от этого же деления. Если число секторов для чтения больше,
158
	÷åì ÷èñëî ñåêòîðîâ äî êîíöà äîðîæêè, óìåíüøàåò ÷èñëî ñåêòîðîâ äëÿ
158
	чем число секторов до конца дорожки, уменьшает число секторов для
159
	÷òåíèÿ.
159
	чтения.
160
4. Ôîðìèðóåò äàííûå äëÿ âûçîâà int 13h (ah=2 - ÷òåíèå, al=÷èñëî ñåêòîðîâ,
160
4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов,
161
	dh=ãîëîâêà, (ìëàäøèå 6 áèò cl)=ñåêòîð,
161
	dh=головка, (младшие 6 бит cl)=сектор,
162
	(ñòàðøèå 2 áèòà cl è âåñü ch)=äîðîæêà, dl=äèñê, es:bx->áóôåð).
162
	(старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер).
163
5. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, âûïîëíÿåò ñáðîñ äèñêà
163
5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска
164
	è ïîâòîðÿåò ïîïûòêó ÷òåíèÿ, âñåãî äåëàåòñÿ íå áîëåå òð¸õ ïîïûòîê
164
	и повторяет попытку чтения, всего делается не более трёх попыток
165
	(íåñêîëüêî ïîïûòîê íóæíî â ñëó÷àå äèñêåòû äëÿ ãàðàíòèè òîãî, ÷òî
165
	(несколько попыток нужно в случае дискеты для гарантии того, что
166
	ìîòîð ðàñêðóòèëñÿ). Åñëè âñå òðè ðàçà ïðîèñõîäèò îøèáêà ÷òåíèÿ,
166
	мотор раскрутился). Если все три раза происходит ошибка чтения,
167
	ïåðåõîäèò íà êîä îáðàáîòêè îøèáîê ñ ñîîáùåíèåì "Read error".
167
	переходит на код обработки ошибок с сообщением "Read error".
168
6.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ
168
6. В соответствии с числом прочитанных на текущей итерации секторов
169
	êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà
169
	корректирует текущий сектор, число оставшихся секторов и указатель на
170
	áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò
170
	буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает
171
	ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 3.
171
	работу, иначе возвращается на шаг 3.
172
LBA-âåðñèÿ:
172
LBA-версия:
173
3. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå 7Fh, óìåíüøàåò åãî (äëÿ òåêóùåé
173
3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей
Line 174... Line 174...
174
	èòåðàöèè) äî 7Fh.
174
	итерации) до 7Fh.
175
4. Ôîðìèðóåò â ñòåêå ïàêåò äëÿ int 13h (êëàä¸ò âñå íóæíûå äàííûå êîìàíäàìè
175
4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами
176
	push, ïðè÷¸ì â îáðàòíîì ïîðÿäêå: ñòåê - ñòðóêòóðà LIFO, è äàííûå â
176
	push, причём в обратном порядке: стек - структура LIFO, и данные в
177
	ñòåêå õðàíÿòñÿ â îáðàòíîì ïîðÿäêå ïî îòíîøåíèþ ê òîìó, êàê èõ òóäà
177
	стеке хранятся в обратном порядке по отношению к тому, как их туда
178
	êëàëè).
178
	клали).
179
5. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, ïåðåõîäèò íà êîä îáðàáîòêè
179
5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки
180
	îøèáîê ñ ñîîáùåíèåì "Read error". Î÷èùàåò ñòåê îò ïàêåòà,
180
	ошибок с сообщением "Read error". Очищает стек от пакета,
181
	ñôîðìèðîâàííîãî íà ïðåäûäóùåì øàãå.
181
	сформированного на предыдущем шаге.
182
6.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ
182
6. В соответствии с числом прочитанных на текущей итерации секторов
183
	êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà
183
	корректирует текущий сектор, число оставшихся секторов и указатель на
184
	áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò
184
	буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает
185
	ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 3.
185
	работу, иначе возвращается на шаг 3.
186
 
186
 
187
Ïðîöåäóðà ïîèñêà ýëåìåíòà â ïàïêå (lookup_in_dir):
187
Процедура поиска элемента в папке (lookup_in_dir):
188
íà âõîäå äîëæíî áûòü óñòàíîâëåíî:
188
на входе должно быть установлено:
189
	ss:bp = 0:7C00
189
	ss:bp = 0:7C00
190
	ds:si = óêàçàòåëü íà èìÿ ôàéëà â ôîðìàòå FAT (ñì. âûøå)
190
	ds:si = указатель на имя файла в формате FAT (см. выше)
191
	eax = íà÷àëüíûé êëàñòåð ïàïêè
191
	eax = начальный кластер папки
192
	bx = 0
192
	bx = 0
193
íà âûõîäå: ôëàã CF îïðåäåëÿåò, óäàëîñü ëè íàéòè ôàéë; åñëè óäàëîñü, òî
193
на выходе: флаг CF определяет, удалось ли найти файл; если удалось, то
194
	CF ñáðîøåí è es:di óêàçûâàåò íà ýëåìåíò ïàïêè
194
	CF сброшен и es:di указывает на элемент папки
195
 öèêëå ñ÷èòûâàåò êëàñòåðû ïàïêè è èùåò çàïðîøåííûé ýëåìåíò â ïðî÷èòàííûõ
195
В цикле считывает кластеры папки и ищет запрошенный элемент в прочитанных
Line 196... Line 196...
196
äàííûõ. Äëÿ ÷òåíèÿ êëàñòåðà èñïîëüçóåò óæå îïèñàííóþ ïðîöåäóðó read_clusters,
196
данных. Для чтения кластера использует уже описанную процедуру read_clusters,
Line 197... Line 197...
197
äëÿ ïðîäâèæåíèÿ ïî öåïî÷êå êëàñòåðîâ - îïèñàííóþ äàëåå ïðîöåäóðó
197
для продвижения по цепочке кластеров - описанную далее процедуру
198
get_next_clusters. Äàííûå ÷èòàþòñÿ â îáëàñòü ïàìÿòè, íà÷èíàþùóþñÿ ñ àäðåñà
198
get_next_clusters. Данные читаются в область памяти, начинающуюся с адреса
199
8000:0000, ïðè ýòîì ïåðâûå 2000h áàéò èç äàííûõ ïàïêè (ìîæåò áûòü, ìåíüøå,
199
8000:0000, при этом первые 2000h байт из данных папки (может быть, меньше,
200
åñëè ÷òåíèå ïðåðâ¸òñÿ ðàíüøå) íå ïåðåêðûâàþòñÿ ïîñëåäóþùèìè ÷òåíèÿìè
200
если чтение прервётся раньше) не перекрываются последующими чтениями
201
(ýòî áóäåò èñïîëüçîâàíî ïîçäíåå, â ñèñòåìå êýøèðîâàíèÿ èç kordldr.f32).
201
(это будет использовано позднее, в системе кэширования из kordldr.f32).
202
Âûõîä îñóùåñòâëÿåòñÿ â ëþáîì èç ñëåäóþùèõ ñëó÷àåâ: íàéäåí çàïðîøåííûé ýëåìåíò;
202
Выход осуществляется в любом из следующих случаев: найден запрошенный элемент;
203
êîí÷èëèñü ýëåìåíòû â ïàïêå (ïåðâûé áàéò î÷åðåäíîãî ýëåìåíòà íóëåâîé);
203
кончились элементы в папке (первый байт очередного элемента нулевой);
204
êîí÷èëèñü äàííûå ïàïêè â ñîîòâåòñòâèè ñ öåïî÷êîé êëàñòåðîâ èç FAT.
204
кончились данные папки в соответствии с цепочкой кластеров из FAT.
205
 
205
 
206
Ïðîöåäóðà âûâîäà íà ýêðàí ASCIIZ-ñòðîêè (out_string):
206
Процедура вывода на экран ASCIIZ-строки (out_string):
207
íà âõîäå: ds:si -> ñòðîêà
207
на входе: ds:si -> строка
208
 öèêëå, ïîêà íå äîñòèãíóò çàâåðøàþùèé íîëü, âûçûâàåò ôóíêöèþ int 10h/ah=0Eh.
208
В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh.
209
 
209
 
210
=====================================================================
210
=====================================================================
211
 
211
 
212
Ðàáîòà âñïîìîãàòåëüíîãî çàãðóç÷èêà kordldr.f32:
212
Работа вспомогательного загрузчика kordldr.f32:
213
1. Îïðåäåëÿåò, áûë ëè îí çàãðóæåí CHS- èëè LBA-âåðñèåé áóòñåêòîðà.
213
1. Определяет, был ли он загружен CHS- или LBA-версией бутсектора.
214
	Â çàâèñèìîñòè îò ýòîãî óñòàíàâëèâàåò ñìåùåíèÿ èñïîëüçóåìûõ ïðîöåäóð
214
	В зависимости от этого устанавливает смещения используемых процедур
215
	áóòñåêòîðà. Êðèòåðèé ïðîâåðêè: â CHS-âåðñèè ïî àäðåñó err íàõîäèòñÿ
215
	бутсектора. Критерий проверки: в CHS-версии по адресу err находится
216
	áàéò 0xE8 (ìàøèííàÿ êîìàíäà call), â LBA-âåðñèè ïî òîìó æå àäðåñó
216
	байт 0xE8 (машинная команда call), в LBA-версии по тому же адресу
217
	íàõîäèòñÿ áàéò 0x14, à àäðåñ ïðîöåäóðû err äðóãîé.
217
	находится байт 0x14, а адрес процедуры err другой.
218
2. Óçíà¸ò ðàçìåð ñâîáîäíîé áàçîâîé ïàìÿòè (ò.å. ñâîáîäíîãî íåïðåðûâíîãî êóñêà
218
2. Узнаёт размер свободной базовой памяти (т.е. свободного непрерывного куска
219
	àäðåñîâ ïàìÿòè, íà÷èíàþùåãîñÿ ñ 0) âûçîâîì int 12h.  ñîîòâåòñòâèè ñ
219
	адресов памяти, начинающегося с 0) вызовом int 12h. В соответствии с
220
	íèì âû÷èñëÿåò ÷èñëî ýëåìåíòîâ â êýøå ïàïîê. Õîòÿ áû äëÿ îäíîãî ýëåìåíòà
220
	ним вычисляет число элементов в кэше папок. Хотя бы для одного элемента
221
	ìåñòî äîëæíî áûòü, îòñþäà îãðàíè÷åíèå â 592 Kb (94000h áàéò).
221
	место должно быть, отсюда ограничение в 592 Kb (94000h байт).
222
	Çàìå÷àíèå: ýòîò ðàçìåð íå ìîæåò ïðåâîñõîäèòü 0A0000h áàéò è
222
	Замечание: этот размер не может превосходить 0A0000h байт и
223
	íà ïðàêòèêå îêàçûâàåòñÿ íåìíîãî (íà 1-2 êèëîáàéòà) ìåíüøèì èç-çà
223
	на практике оказывается немного (на 1-2 килобайта) меньшим из-за
224
	íàëè÷èÿ	äîïîëíèòåëüíîé îáëàñòè äàííûõ BIOS "ââåðõó" áàçîâîé ïàìÿòè.
224
	наличия	дополнительной области данных BIOS "вверху" базовой памяти.
225
3. Èíèöèàëèçèðóåò êýøèðîâàíèå ïàïîê. Áóòñåêòîð óæå çàãðóçèë êàêóþ-òî ÷àñòü
225
3. Инициализирует кэширование папок. Бутсектор уже загрузил какую-то часть
226
	äàííûõ êîðíåâîé ïàïêè; êîïèðóåò çàãðóæåííûå äàííûå â êýø è çàïîìèíàåò,
226
	данных корневой папки; копирует загруженные данные в кэш и запоминает,
227
	÷òî â êýøå åñòü êîðíåâàÿ ïàïêà.
227
	что в кэше есть корневая папка.
228
4. Èíèöèàëèçèðóåò êýøèðîâàíèå FAT. Áóòñåêòîð èìååò äåëî ñ FAT â òîì è òîëüêî
228
4. Инициализирует кэширование FAT. Бутсектор имеет дело с FAT в том и только
229
	òîì ñëó÷àå, êîãäà åìó ïðèõîäèòñÿ çàãðóæàòü äàííûå êîðíåâîé ïàïêè,
229
	том случае, когда ему приходится загружать данные корневой папки,
230
	íå ïîìåñòèâøèåñÿ â îäèí êëàñòåð.  ýòîì ñëó÷àå â ïàìÿòè ïðèñóòñòâóåò
230
	не поместившиеся в один кластер. В этом случае в памяти присутствует
231
	îäèí ñåêòîð FAT (åñëè áûëî íåñêîëüêî îáðàùåíèé - ïîñëåäíèé èç
231
	один сектор FAT (если было несколько обращений - последний из
232
	èñïîëüçîâàííûõ).
232
	использованных).
233
5. Åñëè êëàñòåð ðàâåí ñåêòîðó, òî áóòñåêòîð çàãðóçèë òîëüêî ÷àñòü ôàéëà
233
5. Если кластер равен сектору, то бутсектор загрузил только часть файла
234
	kordldr.f32, è çàãðóç÷èê ïîäãðóæàåò âòîðóþ ñâîþ ÷àñòü, èñïîëüçóÿ
234
	kordldr.f32, и загрузчик подгружает вторую свою часть, используя
235
	çíà÷åíèÿ ðåãèñòðîâ íà âõîäå â kordldr.f32.
235
	значения регистров на входе в kordldr.f32.
236
6. Çàãðóæàåò âòîðè÷íûé çàãðóç÷èê kord/loader ïî àäðåñó 1000:0000. Åñëè ôàéë íå
236
6. Загружает вторичный загрузчик kord/loader по адресу 1000:0000. Если файл не
237
	íàéäåí,	èëè îêàçàëñÿ ïàïêîé, èëè îêàçàëñÿ ñëèøêîì áîëüøèì, òî ïåðåõîäèò
237
	найден,	или оказался папкой, или оказался слишком большим, то переходит
238
	íà êîä îáðàáîòêè îøèáîê èç áóòñåêòîðà ñ ñîîáùåíèåì
238
	на код обработки ошибок из бутсектора с сообщением
239
	"Fatal error: cannot load the secondary loader".
239
	"Fatal error: cannot load the secondary loader".
240
	Çàìå÷àíèå: íà ýòîì ýòàïå èìÿ ôàéëà óæå ìîæíî óêàçûâàòü âìåñòå ñ ïóò¸ì
240
	Замечание: на этом этапе имя файла уже можно указывать вместе с путём
241
	è â ôîðìàòå ASCIIZ, õîòÿ ïîääåðæêè äëèííûõ èì¸í è íåàíãëèéñêèõ ñèìâîëîâ
241
	и в формате ASCIIZ, хотя поддержки длинных имён и неанглийских символов
242
	ïî-ïðåæíåìó íåò.
242
	по-прежнему нет.
243
7. Èçìåíÿåò êîä îáðàáîòêè îøèáîê áóòñåêòîðà íà ïåðåõîä íà ìåòêó hooked_err.
243
7. Изменяет код обработки ошибок бутсектора на переход на метку hooked_err.
244
	Ýòî íóæíî, ÷òîáû ïîñëåäóþùèå îáðàùåíèÿ ê êîäó áóòñåêòîðà â ñëó÷àå
244
	Это нужно, чтобы последующие обращения к коду бутсектора в случае
245
	îøèáîê ÷òåíèÿ íå âûâîäèë ñîîòâåòñòâóþùåå ñîîáùåíèå ñ ïîñëåäóþùåé
245
	ошибок чтения не выводил соответствующее сообщение с последующей
246
	ïåðåçàãðóçêîé, à ðàïîðòîâàë îá îøèáêå ÷òåíèÿ, êîòîðóþ ìîãëî áû
246
	перезагрузкой, а рапортовал об ошибке чтения, которую могло бы
247
	êàê-íèáóäü îáðàáîòàòü ÿäðî.
247
	как-нибудь обработать ядро.
248
8. Åñëè çàãðóçî÷íûé äèñê èìååò èäåíòèôèêàòîð ìåíüøå 0x80,
248
8. Если загрузочный диск имеет идентификатор меньше 0x80,
249
	òî óñòàíàâëèâàåò al='f' ("floppy"), ah=èäåíòèôèêàòîð äèñêà,
249
	то устанавливает al='f' ("floppy"), ah=идентификатор диска,
250
	èíà÷å al='h' ("hard"), ah=èäåíòèôèêàòîð äèñêà-0x80 (íîìåð äèñêà).
250
	иначе al='h' ("hard"), ah=идентификатор диска-0x80 (номер диска).
251
	(Ãîâîðèòå, äèñêåòîê ñ FAT32 íå áûâàåò?  ÷¸ì-òî Âû ïðàâû... íî
251
	(Говорите, дискеток с FAT32 не бывает? В чём-то Вы правы... но
252
	óâåðåíû ëè Âû, ÷òî íåò çàãðóçî÷íûõ óñòðîéñòâ, ïîäîáíûõ äèñêåòàì,
252
	уверены ли Вы, что нет загрузочных устройств, подобных дискетам,
253
	íî áîëüøåãî ðàçìåðà, è äëÿ êîòîðûõ BIOS-èäåíòèôèêàòîð ìåíüøå 0x80?)
253
	но большего размера, и для которых BIOS-идентификатор меньше 0x80?)
254
	Óñòàíàâëèâàåò bx='32' (òèï ôàéëîâîé ñèñòåìû - FAT32).
254
	Устанавливает bx='32' (тип файловой системы - FAT32).
255
	Óñòàíàâëèâàåò si=ñìåùåíèå ôóíêöèè îáðàòíîãî âûçîâà. Ïîñêîëüêó â ýòîò
255
	Устанавливает si=смещение функции обратного вызова. Поскольку в этот
256
	ìîìåíò ds=0, òî ds:si îáðàçóþò ïîëíûé àäðåñ.
256
	момент ds=0, то ds:si образуют полный адрес.
257
9. Ïåðåäà¸ò óïðàâëåíèå ïî àäðåñó 1000:0000.
257
9. Передаёт управление по адресу 1000:0000.
258
 
258
 
259
Ôóíêöèÿ îáðàòíîãî âûçîâà äëÿ âòîðè÷íîãî çàãðóç÷èêà:
259
Функция обратного вызова для вторичного загрузчика:
260
	ïðåäîñòàâëÿåò âîçìîæíîñòü ÷òåíèÿ ôàéëà.
260
	предоставляет возможность чтения файла.
261
Âõîä è âûõîä îïèñàíû â ñïåöèôèêàöèè íà çàãðóç÷èê.
261
Вход и выход описаны в спецификации на загрузчик.
262
1. Ñîõðàíÿåò ñòåê âûçûâàþùåãî êîäà è óñòàíàâëèâàåò ñâîé ñòåê:
262
1. Сохраняет стек вызывающего кода и устанавливает свой стек:
263
	ss:sp = 0:(7C00-10), bp=7C00: ïàðà ss:bp ïðè ðàáîòå ñ îñòàëüíûì
263
	ss:sp = 0:(7C00-10), bp=7C00: пара ss:bp при работе с остальным
264
	êîäîì äîëæíà óêàçûâàòü íà 0:7C00, à -10 áåð¸òñÿ îò òîãî, ÷òî
264
	кодом должна указывать на 0:7C00, а -10 берётся от того, что
265
	èíèöèàëèçèðóþùèé êîä áóòñåêòîðà óæå ïîìåñòèë â ñòåê 10 áàéò ïàðàìåòðîâ,
265
	инициализирующий код бутсектора уже поместил в стек 10 байт параметров,
266
	è îíè äîëæíû ñîõðàíÿòüñÿ â íåèçìåííîñòè. (Çíà÷åíèå [ebp-14],
266
	и они должны сохраняться в неизменности. (Значение [ebp-14],
267
	"òåêóùèé ñåêòîð, íàõîäÿùèéñÿ â êýøå FAT", íå èñïîëüçóåòñÿ ïîñëå
267
	"текущий сектор, находящийся в кэше FAT", не используется после
268
	èíèöèàëèçàöèè êýøèðîâàíèÿ â kordldr.f32.)
268
	инициализации кэширования в kordldr.f32.)
269
2. Ðàçáèðàåò ïåðåäàííûå ïàðàìåòðû è âûçûâàåò íóæíóþ èç âñïîìîãàòåëüíûõ
269
2. Разбирает переданные параметры и вызывает нужную из вспомогательных
270
	ïðîöåäóð (çàãðóçêè ôàéëà ëèáî ïðîäîëæåíèÿ çàãðóçêè ôàéëà).
270
	процедур (загрузки файла либо продолжения загрузки файла).
271
3. Âîññòàíàâëèâàåò ñòåê âûçûâàþùåãî êîäà è âîçâðàùàåò óïðàâëåíèå.
271
3. Восстанавливает стек вызывающего кода и возвращает управление.
272
 
272
 
273
Âñïîìîãàòåëüíûå ïðîöåäóðû kordldr.f32.
273
Вспомогательные процедуры kordldr.f32.
274
Ïðîöåäóðà ïîëó÷åíèÿ ñëåäóþùåãî êëàñòåðà â FAT (get_next_cluster):
274
Процедура получения следующего кластера в FAT (get_next_cluster):
275
1. Âû÷èñëÿåò íîìåð ñåêòîðà â FAT, â êîòîðîì íàõîäèòñÿ çàïðîøåííûé ýëåìåíò.
275
1. Вычисляет номер сектора в FAT, в котором находится запрошенный элемент.
276
	(Â ñåêòîðå 0x200 áàéò, êàæäûé âõîä çàíèìàåò 4 áàéòà.)
276
	(В секторе 0x200 байт, каждый вход занимает 4 байта.)
277
2. Ïðîâåðÿåò, åñòü ëè ñåêòîð â êýøå. Åñëè åñòü, ïðîïóñêàåò øàãè 3 è 4.
277
2. Проверяет, есть ли сектор в кэше. Если есть, пропускает шаги 3 и 4.
278
3. Åñëè íåò, òî â êýø íóæíî âñòàâèòü íîâûé ýëåìåíò. Åñëè êýø åù¸ íå çàïîëíåí,
278
3. Если нет, то в кэш нужно вставить новый элемент. Если кэш ещё не заполнен,
279
	âûäåëÿåò î÷åðåäíîé ýëåìåíò â êîíöå êýøà. Åñëè çàïîëíåí, óäàëÿåò
279
	выделяет очередной элемент в конце кэша. Если заполнен, удаляет
280
	ñàìûé ñòàðûé ýëåìåíò (òîò, ê êîòîðîìó äîëüøå âñåãî íå áûëî îáðàùåíèé);
280
	самый старый элемент (тот, к которому дольше всего не было обращений);
281
	äëÿ òîãî, ÷òîáû îòñëåæèâàòü ïîðÿäîê ýëåìåíòîâ ïî âðåìåíè ïîñëåäíåãî
281
	для того, чтобы отслеживать порядок элементов по времени последнего
282
	îáðàùåíèÿ, âñå (âûäåëåííûå) ýëåìåíòû êýøà ñâÿçàíû â äâóñâÿçíûé ñïèñîê,
282
	обращения, все (выделенные) элементы кэша связаны в двусвязный список,
283
	â êîòîðîì ïåðâûì ýëåìåíòîì ÿâëÿåòñÿ ñàìûé ñòàðûé, à ññûëêè âïåð¸ä
283
	в котором первым элементом является самый старый, а ссылки вперёд
284
	óêàçûâàþò íà ñëåäóþùèé ïî âðåìåíè ïîñëåäíåãî îáðàùåíèÿ.
284
	указывают на следующий по времени последнего обращения.
285
4. ×èòàåò ñîîòâåòñòâóþùèé ñåêòîð FAT ñ äèñêà.
285
4. Читает соответствующий сектор FAT с диска.
286
5. Êîððåêòèðóåò ñïèñîê: òåêóùèé îáðàáàòûâàåìûé ýëåìåíò óäàëÿåòñÿ ñ òîé ïîçèöèè,
286
5. Корректирует список: текущий обрабатываемый элемент удаляется с той позиции,
287
	ãäå îí íàõîäèòñÿ, è äîáàâëÿåòñÿ â êîíåö. ( ñëó÷àå ñî ñâåæåäîáàâëåííûìè
287
	где он находится, и добавляется в конец. (В случае со свежедобавленными
288
	â êýø ýëåìåíòàìè óäàëåíèÿ íå äåëàåòñÿ, ïîñêîëüêó èõ â ñïèñêå åù¸ íåò.)
288
	в кэш элементами удаления не делается, поскольку их в списке ещё нет.)
289
6. Ñ÷èòûâàåò íóæíûé âõîä â FAT, ñáðàñûâàÿ ñòàðøèå 4 áèòà.
289
6. Считывает нужный вход в FAT, сбрасывая старшие 4 бита.
290
7. Ñðàâíèâàåò ïðî÷èòàííîå çíà÷åíèå ñ ïðåäåëîì: åñëè îíî ñòðîãî ìåíüøå
290
7. Сравнивает прочитанное значение с пределом: если оно строго меньше
291
	0x0FFFFFF7, òî îíî çàäà¸ò íîìåð ñëåäóþùåãî êëàñòåðà â öåïî÷êå;
291
	0x0FFFFFF7, то оно задаёт номер следующего кластера в цепочке;
292
	â ïðîòèâíîì ñëó÷àå öåïî÷êà çàêîí÷èëàñü.
292
	в противном случае цепочка закончилась.
293
 
293
 
294
Ïðîöåäóðà çàãðóçêè ôàéëà (load_file):
294
Процедура загрузки файла (load_file):
295
1. Òåêóùàÿ ðàññìàòðèâàåìàÿ ïàïêà - êîðíåâàÿ. Â öèêëå âûïîëíÿåò øàãè 2-4.
295
1. Текущая рассматриваемая папка - корневая. В цикле выполняет шаги 2-4.
296
2. Êîíâåðòèðóåò èìÿ òåêóùåãî ðàññìàòðèâàåìîãî êîìïîíåíòà èìåíè (êîìïîíåíòû
296
2. Конвертирует имя текущего рассматриваемого компонента имени (компоненты
297
	ðàçäåëÿþòñÿ ñèìâîëîì '/') â FAT-ôîðìàò 8+3. Åñëè ýòî íåâîçìîæíî
297
	разделяются символом '/') в FAT-формат 8+3. Если это невозможно
298
	(áîëüøå 8 ñèìâîëîâ â èìåíè, áîëüøå 3 ñèìâîëîâ â ðàñøèðåíèè èëè
298
	(больше 8 символов в имени, больше 3 символов в расширении или
299
	áîëüøå îäíîé òî÷êè), âîçâðàùàåòñÿ ñ îøèáêîé.
299
	больше одной точки), возвращается с ошибкой.
300
3. Èùåò ýëåìåíò ñ òàêèì èìåíåì â òåêóùåé ðàññìàòðèâàåìîé ïàïêå. 
300
3. Ищет элемент с таким именем в текущей рассматриваемой папке. 
301
	à) Ïðîâåðÿåò, åñòü ëè òàêàÿ ïàïêà â êýøå ïàïîê. (Èäåíòèôèêàöèÿ ïàïîê
301
	а) Проверяет, есть ли такая папка в кэше папок. (Идентификация папок
302
	îñóùåñòâëÿåòñÿ ïî íîìåðó íà÷àëüíîãî êëàñòåðà.) Åñëè òàêîé ïàïêè åù¸
302
	осуществляется по номеру начального кластера.) Если такой папки ещё
303
	íåò, äîáàâëÿåò å¸ â êýø; åñëè òîò ïåðåïîëíÿåòñÿ, âûêèäûâàåò ïàïêó,
303
	нет, добавляет её в кэш; если тот переполняется, выкидывает папку,
304
	ê êîòîðîé äîëüøå âñåãî íå áûëî îáðàùåíèé. (Äëÿ êàæäîãî ýëåìåíòà êýøà
304
	к которой дольше всего не было обращений. (Для каждого элемента кэша
305
	õðàíèòñÿ ìåòêà îò 0 äî (ðàçìåð êýøà)-1, îïðåäåëÿþùàÿ åãî íîìåð ïðè
305
	хранится метка от 0 до (размер кэша)-1, определяющая его номер при
306
	ñîðòèðîâêå ïî äàâíîñòè ïîñëåäíåãî îáðàùåíèÿ. Ïðè îáðàùåíèè ê êàêîìó-òî
306
	сортировке по давности последнего обращения. При обращении к какому-то
307
	ýëåìåíòó åãî ìåòêà ñòàíîâèòñÿ íóëåâîé, à òå ìåòêè, êîòîðûå ìåíüøå
307
	элементу его метка становится нулевой, а те метки, которые меньше
308
	ñòàðîãî çíà÷åíèÿ, óâåëè÷èâàþòñÿ íà åäèíèöó.)
308
	старого значения, увеличиваются на единицу.)
309
	á) Ïðîñìàòðèâàåò â ïîèñêàõ çàïðîøåííîãî èìåíè âñå ýëåìåíòû èç êýøà,
309
	б) Просматривает в поисках запрошенного имени все элементы из кэша,
310
	èñïîëüçóÿ ïðîöåäóðó èç áóòñåêòîðà. Åñëè îáíàðóæèâàåò èñêîìûé ýëåìåíò,
310
	используя процедуру из бутсектора. Если обнаруживает искомый элемент,
311
	ïåðåõîäèò ê øàãó 4. Åñëè îáíàðóæèâàåò êîíåö ïàïêè, âîçâðàùàåòñÿ èç
311
	переходит к шагу 4. Если обнаруживает конец папки, возвращается из
312
	ïðîöåäóðû ñ îøèáêîé.
312
	процедуры с ошибкой.
313
	â)  öèêëå ñ÷èòûâàåò ïàïêó ïîñåêòîðíî. Ïðè ýòîì ïðîïóñêàåò íà÷àëüíûå
313
	в) В цикле считывает папку посекторно. При этом пропускает начальные
314
	ñåêòîðû, êîòîðûå óæå íàõîäÿòñÿ â êýøå è óæå áûëè ïðîñìîòðåíû. Êàæäûé
314
	секторы, которые уже находятся в кэше и уже были просмотрены. Каждый
315
	ïðî÷èòàííûé ñåêòîð êîïèðóåò â êýø, åñëè òàì åù¸ îñòà¸òñÿ ìåñòî,
315
	прочитанный сектор копирует в кэш, если там ещё остаётся место,
316
	è ïðîñìàòðèâàåò â í¸ì âñå ýëåìåíòû. Ðàáîòàåò, ïîêà íå ñëó÷èòñÿ îäíî èç
316
	и просматривает в нём все элементы. Работает, пока не случится одно из
317
	òð¸õ ñîáûòèé: íàéäåí èñêîìûé ýëåìåíò; êîí÷èëèñü êëàñòåðû (ñóäÿ ïî
317
	трёх событий: найден искомый элемент; кончились кластеры (судя по
318
	öåïî÷êå êëàñòåðîâ â FAT); î÷åðåäíîé ýëåìåíò ïàïêè ñèãíàëèçèðóåò î êîíöå
318
	цепочке кластеров в FAT); очередной элемент папки сигнализирует о конце