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
 
27
					Âñòðå÷àþòñÿ âèðóñ è FAT.
27
					Встречаются вирус и FAT.
28
					- Ïðèâåò, òû êòî?
28
					- Привет, ты кто?
29
					- ß? Âèðóñ.
29
					- Я? Вирус.
Line 30... Line 30...
30
					- A ÿ AFT, òî åñòü TAF, òî åñòü FTA, ÷åðò, ñîâñåì çàïóòàëñÿ... 
30
					- A я AFT, то есть TAF, то есть FTA, черт, совсем запутался... 
Line 31... Line 31...
31
 
31
 
Line 32... Line 32...
32
Áóòñåêòîð äëÿ FAT12/FAT16-òîìà íà íîñèòåëå ñ ðàçìåðîì ñåêòîðà 0x200 = 512 áàéò.
32
Бутсектор для FAT12/FAT16-тома на носителе с размером сектора 0x200 = 512 байт.
33
 
33
 
34
=====================================================================
34
=====================================================================
35
 
35
 
36
Åñòü äâå âåðñèè â çàâèñèìîñòè îò òîãî, ïîääåðæèâàåò ëè íîñèòåëü LBA,
36
Есть две версии в зависимости от того, поддерживает ли носитель LBA,
37
âûáîð îñóùåñòâëÿåòñÿ óñòàíîâêîé êîíñòàíòû use_lba â ïåðâîé ñòðîêå èñõîäíèêà.
37
выбор осуществляется установкой константы use_lba в первой строке исходника.
38
Òðåáîâàíèÿ äëÿ ðàáîòû:
38
Требования для работы:
Line 39... Line 39...
39
1) Ñàì áóòñåêòîð, ïåðâàÿ êîïèÿ FAT è âñå èñïîëüçóåìûå ôàéëû
39
1) Сам бутсектор, первая копия FAT и все используемые файлы
Line 40... Line 40...
40
äîëæíû áûòü ÷èòàáåëüíû.
40
должны быть читабельны.
41
2) Ìèíèìàëüíûé ïðîöåññîð - 80186.
41
2) Минимальный процессор - 80186.
42
3) Â ñèñòåìå äîëæíî áûòü êàê ìèíèìóì 592K ñâîáîäíîé áàçîâîé ïàìÿòè.
42
3) В системе должно быть как минимум 592K свободной базовой памяти.
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
Ìàêñèìàëüíîå êîëè÷åñòâî êëàñòåðîâ íà FAT12-òîìå - 0xFF4 = 4084; êàæäûé êëàñòåð
57
Максимальное количество кластеров на FAT12-томе - 0xFF4 = 4084; каждый кластер
58
çàíèìàåò 12 áèò â òàáëèöå FAT, òàê ÷òî îáùèé ðàçìåð íå ïðåâîñõîäèò
58
занимает 12 бит в таблице FAT, так что общий размер не превосходит
59
0x17EE = 6126 áàéò. Âñÿ òàáëèöà ïîìåùàåòñÿ â ïàìÿòè.
59
0x17EE = 6126 байт. Вся таблица помещается в памяти.
60
Ìàêñèìàëüíîå êîëè÷åñòâî êëàñòåðîâ íà FAT16-òîìå - 0xFFF4 = 65524; êàæäûé
60
Максимальное количество кластеров на FAT16-томе - 0xFFF4 = 65524; каждый
61
êëàñòåð çàíèìàåò 16 áèò â òàáëèöå FAT, òàê ÷òî îáùèé ðàçìåð íå ïðåâîñõîäèò
61
кластер занимает 16 бит в таблице FAT, так что общий размер не превосходит
62
0x1FFE8 = 131048 áàéò. Âñÿ òàáëèöà òàêæå ïîìåùàåòñÿ â ïàìÿòè, îäíàêî â
62
0x1FFE8 = 131048 байт. Вся таблица также помещается в памяти, однако в
63
ýòîì ñëó÷àå íåñêîëüêî íåöåëåñîîáðàçíî ñ÷èòûâàòü âñþ òàáëèöó, ïîñêîëüêó
63
этом случае несколько нецелесообразно считывать всю таблицу, поскольку
64
íà ïðàêòèêå íóæíà òîëüêî íåáîëüøàÿ å¸ ÷àñòü. Ïîýòîìó ìåñòî â ïàìÿòè
64
на практике нужна только небольшая её часть. Поэтому место в памяти
65
ðåçåðâèðóåòñÿ, íî äàííûå ñ÷èòûâàþòñÿ òîëüêî â ìîìåíò, êîãäà ê íèì
65
резервируется, но данные считываются только в момент, когда к ним
66
äåéñòâèòåëüíî èä¸ò îáðàùåíèå.
66
действительно идёт обращение.
67
 
67
 
68
Ñõåìà èñïîëüçóåìîé ïàìÿòè:
68
Схема используемой памяти:
69
	...-7C00	ñòåê
69
	...-7C00	стек
70
	7C00-7E00	êîä áóòñåêòîðà
70
	7C00-7E00	код бутсектора
71
	7E00-8200	âñïîìîãàòåëüíûé ôàéë çàãðóç÷èêà (kordldr.f1x)
71
	7E00-8200	вспомогательный файл загрузчика (kordldr.f1x)
72
	8200-8300	ñïèñîê çàãðóæåííûõ ñåêòîðîâ òàáëèöû FAT16
72
	8200-8300	список загруженных секторов таблицы FAT16
73
			(1 = ñîîòâåòñòâóþùèé ñåêòîð çàãðóæåí)
73
			(1 = соответствующий сектор загружен)
74
	60000-80000	çàãðóæåííàÿ òàáëèöà FAT12 / ìåñòî äëÿ òàáëèöû FAT16
74
	60000-80000	загруженная таблица FAT12 / место для таблицы FAT16
Line 75... Line 75...
75
	80000-90000	òåêóùèé êëàñòåð òåêóùåé ðàññìàòðèâàåìîé ïàïêè
75
	80000-90000	текущий кластер текущей рассматриваемой папки
Line 76... Line 76...
76
	90000-92000	êýø äëÿ êîðíåâîé ïàïêè
76
	90000-92000	кэш для корневой папки
77
	92000-...	êýø äëÿ íåêîðíåâûõ ïàïîê (êàæäîé ïàïêå îòâîäèòñÿ
77
	92000-...	кэш для некорневых папок (каждой папке отводится
78
			2000h áàéò = 100h âõîäîâ, îäíîâðåìåííî â êýøå
78
			2000h байт = 100h входов, одновременно в кэше
79
			ìîæåò íàõîäèòüñÿ íå áîëåå 7 ïàïîê;
79
			может находиться не более 7 папок;
80
			òî÷íûé ðàçìåð îïðåäåëÿåòñÿ ðàçìåðîì äîñòóïíîé
80
			точный размер определяется размером доступной
81
			ôèçè÷åñêîé ïàìÿòè - êàê ïðàâèëî, íåïîñðåäñòâåííî
81
			физической памяти - как правило, непосредственно
82
			ïåðåä A0000 ðàçìåùàåòñÿ EBDA, Extended BIOS Data Area)
82
			перед A0000 размещается EBDA, Extended BIOS Data Area)
83
 
83
 
84
=====================================================================
84
=====================================================================
85
 
85
 
86
Îñíîâíîé ïðîöåññ çàãðóçêè.
86
Основной процесс загрузки.
87
Òî÷êà âõîäà (start): ïîëó÷àåò óïðàâëåíèå îò BIOS ïðè çàãðóçêå, ïðè ýòîì
87
Точка входа (start): получает управление от BIOS при загрузке, при этом
88
	dl ñîäåðæèò èäåíòèôèêàòîð äèñêà, ñ êîòîðîãî èä¸ò çàãðóçêà
88
	dl содержит идентификатор диска, с которого идёт загрузка
89
1. Íàñòðàèâàåò ñòåê ss:sp = 0:7C00 (ñòåê ðàñïîëàãàåòñÿ íåïîñðåäñòâåííî ïåðåä
89
1. Настраивает стек ss:sp = 0:7C00 (стек располагается непосредственно перед
90
	êîäîì), ñåãìåíò äàííûõ ds = 0, è óñòàíàâëèâàåò ss:bp íà íà÷àëî
90
	кодом), сегмент данных ds = 0, и устанавливает ss:bp на начало
91
	áóòñåêòîðà (â äàëüíåéøåì äàííûå áóäóò àäðåñîâàòüñÿ ÷åðåç [bp+N] -
91
	бутсектора (в дальнейшем данные будут адресоваться через [bp+N] -
92
	ýòî îñâîáîæäàåò ds è ýêîíîìèò íà ðàçìåðå êîäà).
92
	это освобождает ds и экономит на размере кода).
93
2. LBA-âåðñèÿ: ïðîâåðÿåò, ïîääåðæèâàåò ëè íîñèòåëü LBA, âûçîâîì ôóíêöèè 41h
93
2. LBA-версия: проверяет, поддерживает ли носитель LBA, вызовом функции 41h
94
	ïðåðûâàíèÿ 13h. Åñëè íåò, ïåðåõîäèò íà êîä îáðàáîòêè îøèáîê ñ
94
	прерывания 13h. Если нет, переходит на код обработки ошибок с
95
	ñîîáùåíèåì îá îòñóòñòâèè LBA.
95
	сообщением об отсутствии LBA.
96
CHS-âåðñèÿ: îïðåäåëÿåò ãåîìåòðèþ íîñèòåëÿ âûçîâîì ôóíêöèè 8 ïðåðûâàíèÿ 13h è
96
CHS-версия: определяет геометрию носителя вызовом функции 8 прерывания 13h и
97
	çàïèñûâàåò ïîëó÷åííûå äàííûå ïîâåðõ BPB. Åñëè âûçîâ çàâåðøèëñÿ îøèáêîé,
97
	записывает полученные данные поверх BPB. Если вызов завершился ошибкой,
98
	ïðåäïîëàãàåò óæå ñóùåñòâóþùèå äàííûå êîððåêòíûìè.
98
	предполагает уже существующие данные корректными.
99
3. Âû÷èñëÿåò íåêîòîðûå ïàðàìåòðû FAT-òîìà: íà÷àëüíûé ñåêòîð êîðíåâîé ïàïêè
99
3. Вычисляет некоторые параметры FAT-тома: начальный сектор корневой папки
100
	è íà÷àëüíûé ñåêòîð äàííûõ. Êëàä¸ò èõ â ñòåê; âïîñëåäñòâèè îíè
100
	и начальный сектор данных. Кладёт их в стек; впоследствии они
101
	âñåãäà áóäóò ëåæàòü â ñòåêå è àäðåñîâàòüñÿ ÷åðåç bp.
101
	всегда будут лежать в стеке и адресоваться через bp.
102
4. Ñ÷èòûâàåò íà÷àëî êîðíåâîé ïàïêè ïî àäðåñó 9000:0000. ×èñëî ñ÷èòûâàåìûõ
102
4. Считывает начало корневой папки по адресу 9000:0000. Число считываемых
103
	ñåêòîðîâ - ìèíèìóì èç ðàçìåðà êîðíåâîé ïàïêè, óêàçàííîãî â BPB, è 16
103
	секторов - минимум из размера корневой папки, указанного в BPB, и 16
104
	(ðàçìåð êýøà äëÿ êîðíåâîé ïàïêè - 2000h áàéò = 16 ñåêòîðîâ).
104
	(размер кэша для корневой папки - 2000h байт = 16 секторов).
105
5. Èùåò â êîðíåâîé ïàïêå ýëåìåíò kordldr.f1x. Åñëè íå íàõîäèò, èëè åñëè
105
5. Ищет в корневой папке элемент kordldr.f1x. Если не находит, или если
106
	îí îêàçûâàåòñÿ ïàïêîé, èëè åñëè ôàéë èìååò íóëåâóþ äëèíó -
106
	он оказывается папкой, или если файл имеет нулевую длину -
107
	ïåðåõîäèò íà êîä îáðàáîòêè îøèáîê ñ ñîîáùåíèåì î
107
	переходит на код обработки ошибок с сообщением о
108
	íåíàéäåííîì çàãðóç÷èêå.
108
	ненайденном загрузчике.
109
	Çàìå÷àíèå: íà ýòîì ýòàïå çàãðóçêè èñêàòü ìîæíî òîëüêî â êîðíåâîé
109
	Замечание: на этом этапе загрузки искать можно только в корневой
110
	ïàïêå è òîëüêî èìåíà, çàäàííûå â ôîðìàòå ôàéëîâîé ñèñòåìå FAT
110
	папке и только имена, заданные в формате файловой системе FAT
111
	(8+3 - 8 áàéò íà èìÿ, 3 áàéòà íà ðàñøèðåíèå, âñå áóêâû äîëæíû
111
	(8+3 - 8 байт на имя, 3 байта на расширение, все буквы должны
112
	áûòü çàãëàâíûìè, ïðè íåîáõîäèìîñòè èìÿ è ðàñøèðåíèå äîïîëíÿþòñÿ
112
	быть заглавными, при необходимости имя и расширение дополняются
113
	ïðîáåëàìè, ðàçäåëÿþùåé òî÷êè íåò, çàâåðøàþùåãî íóëÿ íåò).
113
	пробелами, разделяющей точки нет, завершающего нуля нет).
114
6. Çàãðóæàåò ïåðâûé êëàñòåð ôàéëà kordldr.f1x ïî àäðåñó 0:7E00 è ïåðåäà¸ò
114
6. Загружает первый кластер файла kordldr.f1x по адресу 0:7E00 и передаёт
115
	åìó óïðàâëåíèå. Ïðè ýòîì â ðåãèñòðàõ dx:ax îêàçûâàåòñÿ àáñîëþòíûé
115
	ему управление. При этом в регистрах dx:ax оказывается абсолютный
Line 116... Line 116...
116
	íîìåð ïåðâîãî ñåêòîðà kordldr.f1x, à â cx - ÷èñëî ñ÷èòàííûõ ñåêòîðîâ
116
	номер первого сектора kordldr.f1x, а в cx - число считанных секторов
117
	(ðàâíîå ðàçìåðó êëàñòåðà).
117
	(равное размеру кластера).
118
 
118
 
119
Âñïîìîãàòåëüíûå ïðîöåäóðû áóòñåêòîðà.
119
Вспомогательные процедуры бутсектора.
120
Êîä îáðàáîòêè îøèáîê (err):
120
Код обработки ошибок (err):
121
1. Âûâîäèò ñòðîêó ñ ñîîáùåíèåì îá îøèáêå.
121
1. Выводит строку с сообщением об ошибке.
122
2. Âûâîäèò ñòðîêó "Press any key...".
122
2. Выводит строку "Press any key...".
123
3. Æä¸ò íàæàòèÿ any key.
123
3. Ждёт нажатия any key.
124
4. Âûçûâàåò int 18h, äàâàÿ øàíñ BIOSó ïîïûòàòüñÿ çàãðóçèòüñÿ îòêóäà-íèáóäü åù¸.
124
4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё.
125
5. Äëÿ ïîäñòðàõîâêè çàöèêëèâàåòñÿ.
125
5. Для подстраховки зацикливается.
126
 
126
 
127
Ïðîöåäóðà ÷òåíèÿ ñåêòîðîâ (read_sectors è read_sectors2):
127
Процедура чтения секторов (read_sectors и read_sectors2):
128
íà âõîäå äîëæíî áûòü óñòàíîâëåíî:
128
на входе должно быть установлено:
129
	ss:bp = 0:7C00
129
	ss:bp = 0:7C00
130
	es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå
130
	es:bx = указатель на начало буфера, куда будут прочитаны данные
131
	dx:ax = ñòàðòîâûé ñåêòîð (îòíîñèòåëüíî íà÷àëà ëîãè÷åñêîãî äèñêà
131
	dx:ax = стартовый сектор (относительно начала логического диска
132
		äëÿ read_sectors, îòíîñèòåëüíî íà÷àëà äàííûõ äëÿ read_sectors2)
132
		для read_sectors, относительно начала данных для read_sectors2)
133
	cx = ÷èñëî ñåêòîðîâ (äîëæíî áûòü áîëüøå íóëÿ)
133
	cx = число секторов (должно быть больше нуля)
134
íà âûõîäå: es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå
134
на выходе: es:bx указывает на конец буфера, в который были прочитаны данные
135
0. Åñëè âûçûâàåòñÿ read_sectors2, îíà ïåðåâîäèò óêàçàííûé åé íîìåð ñåêòîðà
135
0. Если вызывается read_sectors2, она переводит указанный ей номер сектора
136
	â íîìåð îòíîñèòåëüíî íà÷àëà ëîãè÷åñêîãî äèñêà, ïðèáàâëÿÿ íîìåð ñåêòîðà
136
	в номер относительно начала логического диска, прибавляя номер сектора
137
	íà÷àëà äàííûõ, õðàíÿùèéñÿ â ñòåêå êàê [bp-8].
137
	начала данных, хранящийся в стеке как [bp-8].
138
1. Ïåðåâîäèò ñòàðòîâûé ñåêòîð (îòñ÷èòûâàåìûé îò íà÷àëà òîìà) â ñåêòîð íà
138
1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на
139
	óñòðîéñòâå, ïðèáàâëÿÿ çíà÷åíèå ñîîòâåòñòâóþùåãî ïîëÿ èç BPB.
139
	устройстве, прибавляя значение соответствующего поля из BPB.
140
2.  öèêëå (øàãè 3-6) ÷èòàåò ñåêòîðû, ñëåäèò çà òåì, ÷òîáû íà êàæäîé èòåðàöèè
140
2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации
141
	CHS-âåðñèÿ: âñå ÷èòàåìûå ñåêòîðû áûëè íà îäíîé äîðîæêå.
141
	CHS-версия: все читаемые секторы были на одной дорожке.
142
	LBA-âåðñèÿ: ÷èñëî ÷èòàåìûõ ñåêòîðîâ íå ïðåâîñõîäèëî 7Fh (òðåáîâàíèå
142
	LBA-версия: число читаемых секторов не превосходило 7Fh (требование
143
	ñïåöèôèêàöèè EDD BIOS).
143
	спецификации EDD BIOS).
144
CHS-âåðñèÿ:
144
CHS-версия:
145
3. Ïåðåâîäèò àáñîëþòíûé íîìåð ñåêòîðà â CHS-ñèñòåìó: ñåêòîð ðàññ÷èòûâàåòñÿ êàê
145
3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как
146
	åäèíèöà ïëþñ îñòàòîê îò äåëåíèÿ àáñîëþòíîãî íîìåðà íà ÷èñëî ñåêòîðîâ
146
	единица плюс остаток от деления абсолютного номера на число секторов
147
	íà äîðîæêå; äîðîæêà ðàññ÷èòûâàåòñÿ êàê îñòàòîê îò äåëåíèÿ ÷àñòíîãî,
147
	на дорожке; дорожка рассчитывается как остаток от деления частного,
148
	ïîëó÷åííîãî íà ïðåäûäóùåì øàãå, íà ÷èñëî äîðîæåê, à öèëèíäð - êàê
148
	полученного на предыдущем шаге, на число дорожек, а цилиндр - как
149
	÷àñòíîå îò ýòîãî æå äåëåíèÿ. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå,
149
	частное от этого же деления. Если число секторов для чтения больше,
150
	÷åì ÷èñëî ñåêòîðîâ äî êîíöà äîðîæêè, óìåíüøàåò ÷èñëî ñåêòîðîâ äëÿ
150
	чем число секторов до конца дорожки, уменьшает число секторов для
151
	÷òåíèÿ.
151
	чтения.
152
4. Ôîðìèðóåò äàííûå äëÿ âûçîâà int 13h (ah=2 - ÷òåíèå, al=÷èñëî ñåêòîðîâ,
152
4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов,
153
	dh=ãîëîâêà, (ìëàäøèå 6 áèò cl)=ñåêòîð,
153
	dh=головка, (младшие 6 бит cl)=сектор,
154
	(ñòàðøèå 2 áèòà cl è âåñü ch)=äîðîæêà, dl=äèñê, es:bx->áóôåð).
154
	(старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер).
155
5. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, âûïîëíÿåò ñáðîñ äèñêà
155
5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска
156
	è ïîâòîðÿåò ïîïûòêó ÷òåíèÿ, âñåãî äåëàåòñÿ íå áîëåå òð¸õ ïîïûòîê
156
	и повторяет попытку чтения, всего делается не более трёх попыток
157
	(íåñêîëüêî ïîïûòîê íóæíî â ñëó÷àå äèñêåòû äëÿ ãàðàíòèè òîãî, ÷òî
157
	(несколько попыток нужно в случае дискеты для гарантии того, что
158
	ìîòîð ðàñêðóòèëñÿ). Åñëè âñå òðè ðàçà ïðîèñõîäèò îøèáêà ÷òåíèÿ,
158
	мотор раскрутился). Если все три раза происходит ошибка чтения,
159
	ïåðåõîäèò íà êîä îáðàáîòêè îøèáîê ñ ñîîáùåíèåì "Read error".
159
	переходит на код обработки ошибок с сообщением "Read error".
160
6.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ
160
6. В соответствии с числом прочитанных на текущей итерации секторов
161
	êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà
161
	корректирует текущий сектор, число оставшихся секторов и указатель на
162
	áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò
162
	буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает
163
	ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 3.
163
	работу, иначе возвращается на шаг 3.
164
LBA-âåðñèÿ:
164
LBA-версия:
165
3. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå 7Fh, óìåíüøàåò åãî (äëÿ òåêóùåé
165
3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей
166
	èòåðàöèè) äî 7Fh.
166
	итерации) до 7Fh.
Line 167... Line 167...
167
4. Ôîðìèðóåò â ñòåêå ïàêåò äëÿ int 13h (êëàä¸ò âñå íóæíûå äàííûå êîìàíäàìè
167
4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами
168
	push, ïðè÷¸ì â îáðàòíîì ïîðÿäêå: ñòåê - ñòðóêòóðà LIFO, è äàííûå â
168
	push, причём в обратном порядке: стек - структура LIFO, и данные в
169
	ñòåêå õðàíÿòñÿ â îáðàòíîì ïîðÿäêå ïî îòíîøåíèþ ê òîìó, êàê èõ òóäà
169
	стеке хранятся в обратном порядке по отношению к тому, как их туда
170
	êëàëè).
170
	клали).
171
5. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, ïåðåõîäèò íà êîä îáðàáîòêè
171
5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки
172
	îøèáîê ñ ñîîáùåíèåì "Read error". Î÷èùàåò ñòåê îò ïàêåòà,
172
	ошибок с сообщением "Read error". Очищает стек от пакета,
173
	ñôîðìèðîâàííîãî íà ïðåäûäóùåì øàãå.
173
	сформированного на предыдущем шаге.
174
6.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ
174
6. В соответствии с числом прочитанных на текущей итерации секторов
175
	êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà
175
	корректирует текущий сектор, число оставшихся секторов и указатель на
176
	áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò
176
	буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает
177
	ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 3.
177
	работу, иначе возвращается на шаг 3.
178
 
178
 
179
Ïðîöåäóðà ïîèñêà ýëåìåíòà ïî èìåíè â óæå ïðî÷èòàííûõ äàííûõ ïàïêè
179
Процедура поиска элемента по имени в уже прочитанных данных папки
180
	(scan_for_filename):
180
	(scan_for_filename):
181
íà âõîäå äîëæíî áûòü óñòàíîâëåíî:
181
на входе должно быть установлено:
Line 182... Line 182...
182
	ds:si = óêàçàòåëü íà èìÿ ôàéëà â ôîðìàòå FAT (11 áàéò, 8 íà èìÿ,
182
	ds:si = указатель на имя файла в формате FAT (11 байт, 8 на имя,
183
		3 íà ðàñøèðåíèå, âñå áóêâû çàãëàâíûå, åñëè èìÿ/ðàñøèðåíèå
183
		3 на расширение, все буквы заглавные, если имя/расширение
184
		êîðî÷å, îíî äîïîëíÿåòñÿ äî ìàêñèìóìà ïðîáåëàìè)
184
		короче, оно дополняется до максимума пробелами)
185
	es = ñåãìåíò äàííûõ ïàïêè
185
	es = сегмент данных папки
186
	cx = ÷èñëî ýëåìåíòîâ â ïðî÷èòàííûõ äàííûõ
186
	cx = число элементов в прочитанных данных
187
íà âûõîäå: ZF îïðåäåëÿåò, íóæíî ëè ïðîäîëæàòü ðàçáîð äàííûõ ïàïêè
187
на выходе: ZF определяет, нужно ли продолжать разбор данных папки
188
	(ZF=1, åñëè ëèáî íàéäåí çàïðîøåííûé ýëåìåíò, ëèáî äîñòèãíóò
188
	(ZF=1, если либо найден запрошенный элемент, либо достигнут
189
	êîíåö ïàïêè); CF îïðåäåëÿåò, óäàëîñü ëè íàéòè ýëåìåíò ñ èñêîìûì èìåíåì
189
	конец папки); CF определяет, удалось ли найти элемент с искомым именем
190
	(CF=1, åñëè íå óäàëîñü); åñëè óäàëîñü, òî es:di óêàçûâàåò íà íåãî.
190
	(CF=1, если не удалось); если удалось, то es:di указывает на него.
191
scan_for_filename ñ÷èòàåò, ÷òî äàííûå ïàïêè ðàçìåùàþòñÿ íà÷èíàÿ ñ es:0.
191
scan_for_filename считает, что данные папки размещаются начиная с es:0.
192
Ïåðâîé êîìàíäîé ïðîöåäóðà îáíóëÿåò di. Çàòåì ïðîñòî â öèêëå ïî ýëåìåíòàì ïàïêè
192
Первой командой процедура обнуляет di. Затем просто в цикле по элементам папки
193
ïðîâåðÿåò èìåíà.
193
проверяет имена.
194
 
194
 
195
Ïðîöåäóðà ïîèñêà ýëåìåíòà â êîðíåâîé ïàïêå (lookup_in_root_dir):
195
Процедура поиска элемента в корневой папке (lookup_in_root_dir):
196
íà âõîäå äîëæíî áûòü óñòàíîâëåíî:
196
на входе должно быть установлено:
197
	ss:bp = 0:7C00
197
	ss:bp = 0:7C00
198
	ds:si = óêàçàòåëü íà èìÿ ôàéëà â ôîðìàòå FAT (ñì. âûøå)
198
	ds:si = указатель на имя файла в формате FAT (см. выше)
199
íà âûõîäå: ôëàã CF îïðåäåëÿåò, óäàëîñü ëè íàéòè ôàéë; åñëè óäàëîñü, òî
199
на выходе: флаг CF определяет, удалось ли найти файл; если удалось, то
200
	CF ñáðîøåí è es:di óêàçûâàåò íà ýëåìåíò ïàïêè
200
	CF сброшен и es:di указывает на элемент папки
201
Íà÷èíàåò ñ ïðîñìîòðà êýøèðîâàííîé (íà÷àëüíîé) ÷àñòè êîðíåâîé ïàïêè.  öèêëå
201
Начинает с просмотра кэшированной (начальной) части корневой папки. В цикле
Line 202... Line 202...
202
	ñêàíèðóåò ýëåìåíòû; åñëè ïî ðåçóëüòàòàì ñêàíèðîâàíèÿ îáíàðóæèâàåò,
202
	сканирует элементы; если по результатам сканирования обнаруживает,
Line 203... Line 203...
203
	÷òî íóæíî ÷èòàòü ïàïêó äàëüøå, òî ñ÷èòûâàåò íå áîëåå 0x10000 = 64K
203
	что нужно читать папку дальше, то считывает не более 0x10000 = 64K
204
	áàéò (îãðàíè÷åíèå ââåäåíî ïî äâóì ïðè÷èíàì: âî-ïåðâûõ, ÷òîáû çàâåäîìî
204
	байт (ограничение введено по двум причинам: во-первых, чтобы заведомо
205
	íå âûëåçòè çà ïðåäåëû èñïîëüçóåìîé ïàìÿòè, âî-âòîðûõ, ñêàíèðîâàíèå
205
	не вылезти за пределы используемой памяти, во-вторых, сканирование
206
	ïðåäïîëàãàåò, ÷òî âñå îáðàáàòûâàåìûå ýëåìåíòû ðàñïîëàãàþòñÿ â îäíîì
206
	предполагает, что все обрабатываемые элементы располагаются в одном
207
	ñåãìåíòå) è ïðîäîëæàåò öèêë.
207
	сегменте) и продолжает цикл.
208
Ñêàíèðîâàíèå ïðåêðàùàåòñÿ â òð¸õ ñëó÷àÿõ: îáíàðóæåí èñêîìûé ýëåìåíò;
208
Сканирование прекращается в трёх случаях: обнаружен искомый элемент;
209
	êîí÷èëèñü ýëåìåíòû â ïàïêå (ñóäÿ ïî ÷èñëó ýëåìåíòîâ, óêàçàííîìó â BPB);
209
	кончились элементы в папке (судя по числу элементов, указанному в BPB);
210
	î÷åðåäíîé ýëåìåíò ïàïêè ñèãíàëèçèðóåò î êîíöå (ïåðâûé áàéò íóëåâîé).
210
	очередной элемент папки сигнализирует о конце (первый байт нулевой).
211
 
211
 
212
Ïðîöåäóðà âûâîäà íà ýêðàí ASCIIZ-ñòðîêè (out_string):
212
Процедура вывода на экран ASCIIZ-строки (out_string):
213
íà âõîäå: ds:si -> ñòðîêà
213
на входе: ds:si -> строка
214
 öèêëå, ïîêà íå äîñòèãíóò çàâåðøàþùèé íîëü, âûçûâàåò ôóíêöèþ int 10h/ah=0Eh.
214
В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh.
215
 
215
 
216
=====================================================================
216
=====================================================================
217
 
217
 
218
Ðàáîòà âñïîìîãàòåëüíîãî çàãðóç÷èêà kordldr.f1x:
218
Работа вспомогательного загрузчика kordldr.f1x:
219
1. Îïðåäåëÿåò, áûë ëè îí çàãðóæåí CHS- èëè LBA-âåðñèåé áóòñåêòîðà.
219
1. Определяет, был ли он загружен CHS- или LBA-версией бутсектора.
220
	Â çàâèñèìîñòè îò ýòîãî óñòàíàâëèâàåò ñìåùåíèÿ èñïîëüçóåìûõ ïðîöåäóð
220
	В зависимости от этого устанавливает смещения используемых процедур
221
	áóòñåêòîðà. Êðèòåðèé ïðîâåðêè: scan_for_filename äîëæíà íà÷èíàòüñÿ
221
	бутсектора. Критерий проверки: scan_for_filename должна начинаться
222
	ñ èíñòðóêöèè 'xor di,di' ñ êîäîì 31 FF (âîîáùå-òî ýòà èíñòðóêöèÿ ìîæåò
222
	с инструкции 'xor di,di' с кодом 31 FF (вообще-то эта инструкция может
223
	ñ ðàâíûì óñïåõîì àññåìáëèðîâàòüñÿ è êàê 33 FF, íî fasm ãåíåðèðóåò
223
	с равным успехом ассемблироваться и как 33 FF, но fasm генерирует
224
	èìåííî òàêóþ ôîðìó).
224
	именно такую форму).
225
2. Óçíà¸ò ðàçìåð ñâîáîäíîé áàçîâîé ïàìÿòè (ò.å. ñâîáîäíîãî íåïðåðûâíîãî êóñêà
225
2. Узнаёт размер свободной базовой памяти (т.е. свободного непрерывного куска
226
	àäðåñîâ ïàìÿòè, íà÷èíàþùåãîñÿ ñ 0) âûçîâîì int 12h.  ñîîòâåòñòâèè ñ
226
	адресов памяти, начинающегося с 0) вызовом int 12h. В соответствии с
227
	íèì âû÷èñëÿåò ÷èñëî ýëåìåíòîâ â êýøå ïàïîê. Õîòÿ áû äëÿ îäíîãî ýëåìåíòà
227
	ним вычисляет число элементов в кэше папок. Хотя бы для одного элемента
228
	ìåñòî äîëæíî áûòü, îòñþäà îãðàíè÷åíèå â 592 Kb (94000h áàéò).
228
	место должно быть, отсюда ограничение в 592 Kb (94000h байт).
229
	Çàìå÷àíèå: ýòîò ðàçìåð íå ìîæåò ïðåâîñõîäèòü 0A0000h áàéò è
229
	Замечание: этот размер не может превосходить 0A0000h байт и
230
	íà ïðàêòèêå îêàçûâàåòñÿ íåìíîãî (íà 1-2 êèëîáàéòà) ìåíüøèì èç-çà
230
	на практике оказывается немного (на 1-2 килобайта) меньшим из-за
231
	íàëè÷èÿ	äîïîëíèòåëüíîé îáëàñòè äàííûõ BIOS "ââåðõó" áàçîâîé ïàìÿòè.
231
	наличия	дополнительной области данных BIOS "вверху" базовой памяти.
232
3. Îïðåäåëÿåò òèï ôàéëîâîé ñèñòåìû: FAT12 èëè FAT16. Ñîãëàñíî îôèöèàëüíîé
232
3. Определяет тип файловой системы: FAT12 или FAT16. Согласно официальной
233
	ñïåöèôèêàöèè îò Microsoft (âåðñèÿ 1.03 ñïåöèôèêàöèè äàòèðîâàíà,
233
	спецификации от Microsoft (версия 1.03 спецификации датирована,
234
	ê ñëîâó, 06 äåêàáðÿ 2000 ãîäà), ðàçðÿäíîñòü FAT îïðåäåëÿåòñÿ
234
	к слову, 06 декабря 2000 года), разрядность FAT определяется
235
	èñêëþ÷èòåëüíî ÷èñëîì êëàñòåðîâ: ìàêñèìàëüíîå ÷èñëî êëàñòåðîâ íà
235
	исключительно числом кластеров: максимальное число кластеров на
236
	FAT12-òîìå ðàâíî 4094 = 0xFF4. Ñîãëàñíî çäðàâîìó ñìûñëó, íà FAT12
236
	FAT12-томе равно 4094 = 0xFF4. Согласно здравому смыслу, на FAT12
237
	ìîæåò áûòü 0xFF5 êëàñòåðîâ, íî íå áîëüøå: êëàñòåðû íóìåðóþòñÿ ñ 2,
237
	может быть 0xFF5 кластеров, но не больше: кластеры нумеруются с 2,
238
	à ÷èñëî 0xFF7 íå ìîæåò áûòü êîððåêòíûì íîìåðîì êëàñòåðà.
238
	а число 0xFF7 не может быть корректным номером кластера.
239
	Win95/98/Me ñëåäóåò çäðàâîìó ñìûñëó: ðàçãðàíè÷åíèå FAT12/16 äåëàåòñÿ
239
	Win95/98/Me следует здравому смыслу: разграничение FAT12/16 делается
240
	ïî ìàêñèìóìó 0xFF5. Äðàéâåð FAT â WinNT/2k/XP/Vista âîîáùå ïîñòóïàåò
240
	по максимуму 0xFF5. Драйвер FAT в WinNT/2k/XP/Vista вообще поступает
241
	ÿâíî íåâåðíî, ñ÷èòàÿ, ÷òî 0xFF6 (èëè ìåíüøå) êëàñòåðîâ îçíà÷àåò
241
	явно неверно, считая, что 0xFF6 (или меньше) кластеров означает
242
	FAT12-òîì, â ðåçóëüòàòå ïîëó÷àåòñÿ, ÷òî ïîñëåäíèé êëàñòåð
242
	FAT12-том, в результате получается, что последний кластер
243
	(â ñëó÷àå 0xFF6) íåàäðåñóåì. Îñíîâíîé çàãðóç÷èê osloader.exe
243
	(в случае 0xFF6) неадресуем. Основной загрузчик osloader.exe
244
	[âñòðîåí â ntldr] äëÿ NT/2k/XP äåëàåò òàê æå. Ïåðâè÷íûé çàãðóç÷èê
244
	[встроен в ntldr] для NT/2k/XP делает так же. Первичный загрузчик
245
	[áóòñåêòîð FAT12/16 çàãðóæàåò ïåðâûé ñåêòîð ntldr, è ðàçáîð FAT-òàáëèöû
245
	[бутсектор FAT12/16 загружает первый сектор ntldr, и разбор FAT-таблицы
246
	ëåæèò íà í¸ì] â NT/2k ïîäâåðæåí òîé æå îøèáêå.  XP å¸ òàêè èñïðàâèëè
246
	лежит на нём] в NT/2k подвержен той же ошибке. В XP её таки исправили
247
	â ñîîòâåòñòâèè ñî ñïåöèôèêàöèåé. Linux ïðè îïðåäåëåíèè FAT12/FAT16
247
	в соответствии со спецификацией. Linux при определении FAT12/FAT16
248
	÷åñòíî ñëåäóåò ñïåöèôèêàöèè.
248
	честно следует спецификации.
249
	Çäåñü êîä îñíîâàí âñ¸ æå íà ñïåöèôèêàöèè. 9x ìåðòâà, à â ëèíåéêå NT
249
	Здесь код основан всё же на спецификации. 9x мертва, а в линейке NT
250
	Microsoft åñëè è áóäåò èñïðàâëÿòü îøèáêè, òî ñîãëàñíî ñîáñòâåííîìó
250
	Microsoft если и будет исправлять ошибки, то согласно собственному
251
	îïèñàíèþ.
251
	описанию.
252
4. Äëÿ FAT12: çàãðóæàåò â ïàìÿòü ïåðâóþ êîïèþ òàáëèöû FAT ïî àäðåñó 6000:0000.
252
4. Для FAT12: загружает в память первую копию таблицы FAT по адресу 6000:0000.
253
	Åñëè ðàçìåð, óêàçàííûé â BPB, ïðåâîñõîäèò 12 ñåêòîðîâ,
253
	Если размер, указанный в BPB, превосходит 12 секторов,
254
	ýòî îçíà÷àåò, ÷òî çàÿâëåííûé ðàçìåð ñëèøêîì áîëüøîé (ýòî íå ñ÷èòàåòñÿ
254
	это означает, что заявленный размер слишком большой (это не считается
255
	îøèáêîé ôàéëîâîé ñèñòåìû), è ÷èòàþòñÿ òîëüêî 12 ñåêòîðîâ (òàáëèöà FAT12
255
	ошибкой файловой системы), и читаются только 12 секторов (таблица FAT12
256
	çàâåäîìî âëåçàåò â òàêîé îáú¸ì äàííûõ).
256
	заведомо влезает в такой объём данных).
257
Äëÿ FAT16: èíèöèàëèçèðóåò âíóòðåííèå äàííûå, óêàçûâàÿ, ÷òî íèêàêîé ñåêòîð
257
Для FAT16: инициализирует внутренние данные, указывая, что никакой сектор
258
	FAT íå çàãðóæåí (îíè áóäóò ïîäãðóæàòüñÿ ïîçäíåå, êîãäà ïîíàäîáÿòñÿ
258
	FAT не загружен (они будут подгружаться позднее, когда понадобятся
259
	è òîëüêî òå, êîòîðûå ïîíàäîáÿòñÿ).
259
	и только те, которые понадобятся).
260
5. Åñëè êëàñòåð ðàâåí ñåêòîðó, òî áóòñåêòîð çàãðóçèë òîëüêî ÷àñòü ôàéëà
260
5. Если кластер равен сектору, то бутсектор загрузил только часть файла
261
	kordldr.f1x, è çàãðóç÷èê ïîäãðóæàåò âòîðóþ ñâîþ ÷àñòü, èñïîëüçóÿ
261
	kordldr.f1x, и загрузчик подгружает вторую свою часть, используя
262
	çíà÷åíèÿ ðåãèñòðîâ íà âõîäå â kordldr.f1x.
262
	значения регистров на входе в kordldr.f1x.
263
6. Çàãðóæàåò âòîðè÷íûé çàãðóç÷èê kord/loader ïî àäðåñó 1000:0000. Åñëè ôàéë íå
263
6. Загружает вторичный загрузчик kord/loader по адресу 1000:0000. Если файл не
264
	íàéäåí,	èëè îêàçàëñÿ ïàïêîé, èëè îêàçàëñÿ ñëèøêîì áîëüøèì, òî ïåðåõîäèò
264
	найден,	или оказался папкой, или оказался слишком большим, то переходит
265
	íà êîä îáðàáîòêè îøèáîê èç áóòñåêòîðà ñ ñîîáùåíèåì
265
	на код обработки ошибок из бутсектора с сообщением
266
	"Fatal error: cannot load the secondary loader".
266
	"Fatal error: cannot load the secondary loader".
267
	Çàìå÷àíèå: íà ýòîì ýòàïå èìÿ ôàéëà óæå ìîæíî óêàçûâàòü âìåñòå ñ ïóò¸ì
267
	Замечание: на этом этапе имя файла уже можно указывать вместе с путём
268
	è â ôîðìàòå ASCIIZ, õîòÿ ïîääåðæêè äëèííûõ èì¸í è íåàíãëèéñêèõ ñèìâîëîâ
268
	и в формате ASCIIZ, хотя поддержки длинных имён и неанглийских символов
269
	ïî-ïðåæíåìó íåò.
269
	по-прежнему нет.
270
7. Èçìåíÿåò êîä îáðàáîòêè îøèáîê áóòñåêòîðà íà ïåðåõîä íà ìåòêó hooked_err.
270
7. Изменяет код обработки ошибок бутсектора на переход на метку hooked_err.
271
	Ýòî íóæíî, ÷òîáû ïîñëåäóþùèå îáðàùåíèÿ ê êîäó áóòñåêòîðà â ñëó÷àå
271
	Это нужно, чтобы последующие обращения к коду бутсектора в случае
272
	îøèáîê ÷òåíèÿ íå âûâîäèë ñîîòâåòñòâóþùåå ñîîáùåíèå ñ ïîñëåäóþùåé
272
	ошибок чтения не выводил соответствующее сообщение с последующей
273
	ïåðåçàãðóçêîé, à ðàïîðòîâàë îá îøèáêå ÷òåíèÿ, êîòîðóþ ìîã áû
273
	перезагрузкой, а рапортовал об ошибке чтения, которую мог бы
274
	êàê-íèáóäü îáðàáîòàòü âòîðè÷íûé çàãðóç÷èê.
274
	как-нибудь обработать вторичный загрузчик.
275
8. Åñëè çàãðóçî÷íûé äèñê èìååò èäåíòèôèêàòîð ìåíüøå 0x80,
275
8. Если загрузочный диск имеет идентификатор меньше 0x80,
276
	òî óñòàíàâëèâàåò al='f' ("floppy"), ah=èäåíòèôèêàòîð äèñêà,
276
	то устанавливает al='f' ("floppy"), ah=идентификатор диска,
277
	èíà÷å al='h' ("hard"), ah=èäåíòèôèêàòîð äèñêà-0x80 (íîìåð äèñêà).
277
	иначе al='h' ("hard"), ah=идентификатор диска-0x80 (номер диска).
278
	Óñòàíàâëèâàåò bx='12', åñëè òèï ôàéëîâîé ñèñòåìû - FAT12, è
278
	Устанавливает bx='12', если тип файловой системы - FAT12, и
279
	bx='16' â ñëó÷àå FAT16.	Óñòàíàâëèâàåò si=ñìåùåíèå ôóíêöèè îáðàòíîãî
279
	bx='16' в случае FAT16.	Устанавливает si=смещение функции обратного
280
	âûçîâà. Ïîñêîëüêó â ýòîò ìîìåíò ds=0, òî ds:si îáðàçóþò ïîëíûé àäðåñ.
280
	вызова. Поскольку в этот момент ds=0, то ds:si образуют полный адрес.
281
9. Ïåðåäà¸ò óïðàâëåíèå ïî àäðåñó 1000:0000.
281
9. Передаёт управление по адресу 1000:0000.
282
 
282
 
283
Ôóíêöèÿ îáðàòíîãî âûçîâà äëÿ âòîðè÷íîãî çàãðóç÷èêà:
283
Функция обратного вызова для вторичного загрузчика:
284
	ïðåäîñòàâëÿåò âîçìîæíîñòü ÷òåíèÿ ôàéëà.
284
	предоставляет возможность чтения файла.
285
Âõîä è âûõîä îïèñàíû â ñïåöèôèêàöèè íà çàãðóç÷èê.
285
Вход и выход описаны в спецификации на загрузчик.
286
1. Ñîõðàíÿåò ñòåê âûçûâàþùåãî êîäà è óñòàíàâëèâàåò ñâîé ñòåê:
286
1. Сохраняет стек вызывающего кода и устанавливает свой стек:
287
	ss:sp = 0:(7C00-8), bp=7C00: ïàðà ss:bp ïðè ðàáîòå ñ îñòàëüíûì
287
	ss:sp = 0:(7C00-8), bp=7C00: пара ss:bp при работе с остальным
288
	êîäîì äîëæíà óêàçûâàòü íà 0:7C00, à -8 áåð¸òñÿ îò òîãî, ÷òî
288
	кодом должна указывать на 0:7C00, а -8 берётся от того, что
289
	èíèöèàëèçèðóþùèé êîä áóòñåêòîðà óæå ïîìåñòèë â ñòåê 2 äâîéíûõ ñëîâà,
289
	инициализирующий код бутсектора уже поместил в стек 2 двойных слова,
290
	è îíè äîëæíû ñîõðàíÿòüñÿ â íåèçìåííîñòè.
290
	и они должны сохраняться в неизменности.
291
2. Ðàçáèðàåò ïåðåäàííûå ïàðàìåòðû, âûÿñíÿåò, êàêîå äåéñòâèå çàïðîøåíî,
291
2. Разбирает переданные параметры, выясняет, какое действие запрошено,
292
	è âûçûâàåò íóæíóþ âñïîìîãàòåëüíóþ ïðîöåäóðó.
292
	и вызывает нужную вспомогательную процедуру.
293
3. Âîññòàíàâëèâàåò ñòåê âûçûâàþùåãî êîäà è âîçâðàùàåò óïðàâëåíèå.
293
3. Восстанавливает стек вызывающего кода и возвращает управление.
294
 
294
 
295
Âñïîìîãàòåëüíûå ïðîöåäóðû kordldr.f1x.
295
Вспомогательные процедуры kordldr.f1x.
296
Ïðîöåäóðà ïîëó÷åíèÿ ñëåäóþùåãî êëàñòåðà â FAT (get_next_cluster):
296
Процедура получения следующего кластера в FAT (get_next_cluster):
297
1. Âñïîìèíàåò ðàçðÿäíîñòü FAT, âû÷èñëåííóþ ðàíåå.
297
1. Вспоминает разрядность FAT, вычисленную ранее.
298
Äëÿ FAT12:
298
Для FAT12:
299
2. Óñòàíàâëèâàåò ds = 0x6000 - ñåãìåíò, êóäà ðàíåå áûëà ñ÷èòàíà
299
2. Устанавливает ds = 0x6000 - сегмент, куда ранее была считана
300
	âñÿ òàáëèöà FAT.
300
	вся таблица FAT.
301
3. Ïîäñ÷èòûâàåò si = (êëàñòåð) + (êëàñòåð)/2 - ñìåùåíèå â ýòîì ñåãìåíòå
301
3. Подсчитывает si = (кластер) + (кластер)/2 - смещение в этом сегменте
302
	ñëîâà, çàäàþùåãî ñëåäóþùèé êëàñòåð. Çàãðóæàåò ñëîâî ïî ýòîìó àäðåñó.
302
	слова, задающего следующий кластер. Загружает слово по этому адресу.
303
4. Åñëè êëàñòåð èìååò íå÷¸òíûé íîìåð, òî ñîîòâåòñòâóþùèé åìó ýëåìåíò
303
4. Если кластер имеет нечётный номер, то соответствующий ему элемент
304
	ðàñïîëàãàåòñÿ â ñòàðøèõ 12 áèòàõ ñëîâà, è ñëîâî íóæíî ñäâèíóòü âïðàâî
304
	располагается в старших 12 битах слова, и слово нужно сдвинуть вправо
305
	íà 4 áèòà; â ïðîòèâíîì ñëó÷àå - â ìëàäøèõ 12 áèòàõ, è äåëàòü íè÷åãî íå
305
	на 4 бита; в противном случае - в младших 12 битах, и делать ничего не
306
	íàäî.
306
	надо.
307
5. Âûäåëÿåò èç ïîëó÷èâøåãîñÿ ñëîâà 12 áèò. Ñðàâíèâàåò èõ ñ ïðåäåëîì 0xFF7:
307
5. Выделяет из получившегося слова 12 бит. Сравнивает их с пределом 0xFF7:
308
	íîìåðà íîðìàëüíûõ êëàñòåðîâ ìåíüøå, è ôëàã CF óñòàíàâëèâàåòñÿ;
308
	номера нормальных кластеров меньше, и флаг CF устанавливается;
309
	ñïåöèàëüíûå çíà÷åíèÿ EOF è BadClus ñáðàñûâàþò ôëàã CF.
309
	специальные значения EOF и BadClus сбрасывают флаг CF.
310
Äëÿ FAT16:
310
Для FAT16:
311
2. Âû÷èñëÿåò àäðåñ ïàìÿòè, ïðåäíàçíà÷åííîé äëÿ ñîîòâåòñòâóþùåãî ñåêòîðà äàííûõ
311
2. Вычисляет адрес памяти, предназначенной для соответствующего сектора данных
312
	â òàáëèöå FAT.
312
	в таблице FAT.
313
3. Åñëè ñåêòîð åù¸ íå çàãðóæåí, òî çàãðóæàåò åãî.
313
3. Если сектор ещё не загружен, то загружает его.
314
4. Âû÷èñëÿåò ñìåùåíèå äàííûõ äëÿ êîíêðåòíîãî êëàñòåðà îòíîñèòåëüíî íà÷àëà
314
4. Вычисляет смещение данных для конкретного кластера относительно начала
315
	ñåêòîðà.
315
	сектора.
316
5. Çàãðóæàåò ñëîâî â ax èç àäðåñà, âû÷èñëåííîìó íà øàãàõ 1 è 3.
316
5. Загружает слово в ax из адреса, вычисленному на шагах 1 и 3.
317
6. Ñðàâíèâàåò åãî ñ ïðåäåëîì 0xFFF7: íîìåðà íîðìàëüíûõ êëàñòåðîâ ìåíüøå, è ôëàã
317
6. Сравнивает его с пределом 0xFFF7: номера нормальных кластеров меньше, и флаг
318
	CF óñòàíàâëèâàåòñÿ; ñïåöèàëüíûå çíà÷åíèÿ EOF è BadClus ñáðàñûâàþò CF.
318
	CF устанавливается; специальные значения EOF и BadClus сбрасывают CF.
319
 
319
 
320
Ïðîöåäóðà çàãðóçêè ôàéëà (load_file):
320
Процедура загрузки файла (load_file):
321
1. Òåêóùàÿ ðàññìàòðèâàåìàÿ ïàïêà - êîðíåâàÿ. Â öèêëå âûïîëíÿåò øàãè 2-4.
321
1. Текущая рассматриваемая папка - корневая. В цикле выполняет шаги 2-4.
322
2. Êîíâåðòèðóåò èìÿ òåêóùåãî ðàññìàòðèâàåìîãî êîìïîíåíòà èìåíè (êîìïîíåíòû
322
2. Конвертирует имя текущего рассматриваемого компонента имени (компоненты
323
	ðàçäåëÿþòñÿ ñèìâîëîì '/') â FAT-ôîðìàò 8+3. Åñëè ýòî íåâîçìîæíî
323
	разделяются символом '/') в FAT-формат 8+3. Если это невозможно
324
	(áîëüøå 8 ñèìâîëîâ â èìåíè, áîëüøå 3 ñèìâîëîâ â ðàñøèðåíèè èëè
324
	(больше 8 символов в имени, больше 3 символов в расширении или
325
	áîëüøå îäíîé òî÷êè), âîçâðàùàåòñÿ ñ îøèáêîé.
325
	больше одной точки), возвращается с ошибкой.
326
3. Èùåò ýëåìåíò ñ òàêèì èìåíåì â òåêóùåé ðàññìàòðèâàåìîé ïàïêå. Äëÿ êîðíåâîé
326
3. Ищет элемент с таким именем в текущей рассматриваемой папке. Для корневой
327
	ïàïêè èñïîëüçóåòñÿ ïðîöåäóðà èç áóòñåêòîðà. Äëÿ îñòàëüíûõ ïàïîê:
327
	папки используется процедура из бутсектора. Для остальных папок:
328
	a) Ïðîâåðÿåò, åñòü ëè òàêàÿ ïàïêà â êýøå íåêîðíåâûõ ïàïîê.
328
	a) Проверяет, есть ли такая папка в кэше некорневых папок.
329
	(Èäåíòèôèêàöèÿ ïàïîê îñóùåñòâëÿåòñÿ ïî íîìåðó íà÷àëüíîãî êëàñòåðà.)
329
	(Идентификация папок осуществляется по номеру начального кластера.)
330
	Åñëè òàêîé ïàïêè åù¸ íåò, äîáàâëÿåò å¸ â êýø; åñëè òîò ïåðåïîëíÿåòñÿ,
330
	Если такой папки ещё нет, добавляет её в кэш; если тот переполняется,
331
	âûêèäûâàåò ïàïêó, ê êîòîðîé äîëüøå âñåãî íå áûëî îáðàùåíèé. (Äëÿ
331
	выкидывает папку, к которой дольше всего не было обращений. (Для
332
	êàæäîãî ýëåìåíòà êýøà õðàíèòñÿ ìåòêà îò 0 äî (ðàçìåð êýøà)-1,
332
	каждого элемента кэша хранится метка от 0 до (размер кэша)-1,
333
	îïðåäåëÿþùàÿ åãî íîìåð ïðè ñîðòèðîâêå ïî äàâíîñòè ïîñëåäíåãî îáðàùåíèÿ.
333
	определяющая его номер при сортировке по давности последнего обращения.
334
	Ïðè îáðàùåíèè ê êàêîìó-òî ýëåìåíòó åãî ìåòêà ñòàíîâèòñÿ íóëåâîé,
334
	При обращении к какому-то элементу его метка становится нулевой,
335
	à òå ìåòêè, êîòîðûå ìåíüøå ñòàðîãî çíà÷åíèÿ, óâåëè÷èâàþòñÿ íà åäèíèöó.)
335
	а те метки, которые меньше старого значения, увеличиваются на единицу.)
336
	á) Ïðîñìàòðèâàåò â ïîèñêàõ çàïðîøåííîãî èìåíè âñå ýëåìåíòû èç êýøà,
336
	б) Просматривает в поисках запрошенного имени все элементы из кэша,
337
	èñïîëüçóÿ ïðîöåäóðó èç áóòñåêòîðà. Åñëè îáíàðóæèâàåò èñêîìûé ýëåìåíò,
337
	используя процедуру из бутсектора. Если обнаруживает искомый элемент,
338
	ïåðåõîäèò ê øàãó 4. Åñëè îáíàðóæèâàåò êîíåö ïàïêè, âîçâðàùàåòñÿ èç
338
	переходит к шагу 4. Если обнаруживает конец папки, возвращается из
339
	ïðîöåäóðû ñ îøèáêîé.
339
	процедуры с ошибкой.
340
	â)  öèêëå ñ÷èòûâàåò ïàïêó ïîñåêòîðíî. Ïðè ýòîì ïðîïóñêàåò íà÷àëüíûå
340
	в) В цикле считывает папку посекторно. При этом пропускает начальные
341
	ñåêòîðû, êîòîðûå óæå íàõîäÿòñÿ â êýøå è óæå áûëè ïðîñìîòðåíû. Êàæäûé
341
	секторы, которые уже находятся в кэше и уже были просмотрены. Каждый
342
	ïðî÷èòàííûé ñåêòîð êîïèðóåò â êýø, åñëè òàì åù¸ îñòà¸òñÿ ìåñòî,
342
	прочитанный сектор копирует в кэш, если там ещё остаётся место,
343
	è ïðîñìàòðèâàåò â í¸ì âñå ýëåìåíòû. Ðàáîòàåò, ïîêà íå ñëó÷èòñÿ îäíî èç
343
	и просматривает в нём все элементы. Работает, пока не случится одно из
344
	òð¸õ ñîáûòèé: íàéäåí èñêîìûé ýëåìåíò; êîí÷èëèñü êëàñòåðû (ñóäÿ ïî
344
	трёх событий: найден искомый элемент; кончились кластеры (судя по
345
	öåïî÷êå êëàñòåðîâ â FAT); î÷åðåäíîé ýëåìåíò ïàïêè ñèãíàëèçèðóåò î êîíöå
345
	цепочке кластеров в FAT); очередной элемент папки сигнализирует о конце