Subversion Repositories Kolibri OS

Rev

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

Rev 1065 Rev 3539
Line 24... Line 24...
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
					Sector not found. N. N.N.N. N.N.N.N.N.N.N. N.N. N.N.N.N.N.N.?
27
					Sector not found. N. N.N.N. N.N.N.N.N.N.N. N.N. N.N.N.N.N.N.?
28
 
28
 
29
Áóòñåêòîð äëÿ çàãðóçêè ñ CD/DVD ñ ôàéëîâîé ñèñòåìîé ISO-9660.
29
Бутсектор для загрузки с CD/DVD с файловой системой ISO-9660.
Line 30... Line 30...
30
(ISO-9660 è å¸ ðàñøèðåíèÿ - ñòàíäàðò äëÿ CD; DVD ìîæåò èñïîëüçîâàòü
30
(ISO-9660 и её расширения - стандарт для CD; DVD может использовать
Line 31... Line 31...
31
ëèáî ISO-9660, ëèáî UDF.)
31
либо ISO-9660, либо UDF.)
32
 
32
 
33
=====================================================================
33
=====================================================================
34
 
34
 
Line 35... Line 35...
35
Òðåáîâàíèÿ äëÿ ðàáîòû:
35
Требования для работы:
Line 36... Line 36...
36
1) Ñàì áóòñåêòîð è âñå èñïîëüçóåìûå ôàéëû äîëæíû áûòü ÷èòàáåëüíû.
36
1) Сам бутсектор и все используемые файлы должны быть читабельны.
37
2) Ìèíèìàëüíûé ïðîöåññîð - 80386.
37
2) Минимальный процессор - 80386.
38
3) Â ñèñòåìå äîëæíî áûòü êàê ìèíèìóì 452K ñâîáîäíîé áàçîâîé ïàìÿòè.
38
3) В системе должно быть как минимум 452K свободной базовой памяти.
39
 
39
 
40
=====================================================================
40
=====================================================================
41
 
41
 
42
Äîêóìåíòàöèÿ â òåìó (ññûëêè ïðîâåðÿëèñü íà âàëèäíîñòü 14.09.2008):
42
Документация в тему (ссылки проверялись на валидность 14.09.2008):
Line 43... Line 43...
43
	ñòàíäàðò ISO-9660: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf
43
	стандарт ISO-9660: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf
Line 44... Line 44...
44
	ñòàíäàðò çàãðóçî÷íîãî CD: http://www.phoenix.com/NR/rdonlyres/98D3219C-9CC9-4DF5-B496-A286D893E36A/0/specscdrom.pdf
44
	стандарт загрузочного CD: http://www.phoenix.com/NR/rdonlyres/98D3219C-9CC9-4DF5-B496-A286D893E36A/0/specscdrom.pdf
45
	îôèöèàëüíàÿ ñïåöèôèêàöèÿ ðàñøèðåíèÿ EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf
45
	официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf
46
		òî æå, âåðñèÿ 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf
46
		то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf
47
	îïèñàíèå ôóíêöèé BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html
47
	описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html
48
	îôèöèàëüíàÿ ñïåöèôèêàöèÿ Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf
48
	официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf
49
 
49
 
50
=====================================================================
50
=====================================================================
51
 
51
 
52
Ñõåìà èñïîëüçóåìîé ïàìÿòè:
52
Схема используемой памяти:
53
	1000-1800	âðåìåííûé áóôåð äëÿ ÷òåíèÿ îäèíî÷íûõ ñåêòîðîâ
53
	1000-1800	временный буфер для чтения одиночных секторов
54
	 ...-7C00	ñòåê
54
	 ...-7C00	стек
55
	7C00-8400	êîä áóòñåêòîðà
55
	7C00-8400	код бутсектора
56
	8400-8A00	èíôîðìàöèÿ î êýøå äëÿ ïàïîê: ìàññèâ âõîäîâ ñëåäóþùåãî
56
	8400-8A00	информация о кэше для папок: массив входов следующего
57
			ôîðìàòà:
57
			формата:
58
			dw ñëåäóþùèé ýëåìåíò â L2-ñïèñêå çàêýøèðîâàííûõ ïàïîê,
58
			dw следующий элемент в L2-списке закэшированных папок,
59
				óïîðÿäî÷åííîì ïî âðåìåíè èñïîëüçîâàíèÿ
59
				упорядоченном по времени использования
60
				(ãîëîâà ñïèñêà - ñàìûé ñòàðûé);
60
				(голова списка - самый старый);
61
			dw ïðåäûäóùèé ýëåìåíò â òîì æå ñïèñêå;
61
			dw предыдущий элемент в том же списке;
Line 62... Line 62...
62
			dd ïåðâûé ñåêòîð ïàïêè;
62
			dd первый сектор папки;
Line 63... Line 63...
63
			dw ðàçìåð ïàïêè â áàéòàõ;
63
			dw размер папки в байтах;
64
			dw ñåãìåíò êýøà
64
			dw сегмент кэша
65
	60000-...	ñîäåðæèìîå Path Table, åñëè îíà èñïîëüçóåòñÿ
65
	60000-...	содержимое Path Table, если она используется
66
			+ êýø äëÿ ïàïîê;
66
			+ кэш для папок;
67
			òî÷íûé ðàçìåð îïðåäåëÿåòñÿ ðàçìåðîì äîñòóïíîé
67
			точный размер определяется размером доступной
68
			ôèçè÷åñêîé ïàìÿòè - êàê ïðàâèëî, íåïîñðåäñòâåííî
68
			физической памяти - как правило, непосредственно
69
			ïåðåä A0000 ðàçìåùàåòñÿ EBDA, Extended BIOS Data Area
69
			перед A0000 размещается EBDA, Extended BIOS Data Area
70
 
70
 
71
=====================================================================
71
=====================================================================
72
 
72
 
73
Îñíîâíîé ïðîöåññ çàãðóçêè.
73
Основной процесс загрузки.
74
Òî÷êà âõîäà (start): ïîëó÷àåò óïðàâëåíèå îò BIOS ïðè çàãðóçêå, ïðè ýòîì
74
Точка входа (start): получает управление от BIOS при загрузке, при этом
75
	dl ñîäåðæèò èäåíòèôèêàòîð äèñêà, ñ êîòîðîãî èä¸ò çàãðóçêà
75
	dl содержит идентификатор диска, с которого идёт загрузка
76
1. Ïðè ïåðåäà÷å óïðàâëåíèÿ çàãðóçî÷íîìó êîäó â ñëó÷àå CD/DVD ïàðà cs:ip
76
1. При передаче управления загрузочному коду в случае CD/DVD пара cs:ip
77
	ðàâíà íå 0:7C00, à íà 07C0:0000. Ïîýòîìó ñíà÷àëà çàãðóç÷èê äåëàåò
77
	равна не 0:7C00, а на 07C0:0000. Поэтому сначала загрузчик делает
78
	äàëüíèé ïðûæîê íà ñàìîãî ñåáÿ ñ öåëüþ ïîëó÷èòü cs=0 (â íåêîòîðûõ
78
	дальний прыжок на самого себя с целью получить cs=0 (в некоторых
79
	ìåñòàõ èñïîëüçóåòñÿ àäðåñàöèÿ ïåðåìåííûõ çàãðóç÷èêà ÷åðåç cs, ïîñêîëüêó
79
	местах используется адресация переменных загрузчика через cs, поскольку
80
	è ds, è es ìîãóò áûòü çàíÿòû ïîä äðóãèå ñåãìåíòû).
80
	и ds, и es могут быть заняты под другие сегменты).
81
2. Íàñòðàèâàåò ñòåê ss:sp = 0:7C00 (íåïîñðåäñòâåííî ïåðåä îñíîâíûì êîäîì)
81
2. Настраивает стек ss:sp = 0:7C00 (непосредственно перед основным кодом)
82
	è ñåãìåíòíûå ðåãèñòðû ds=es=0. Ôîðñèðóåò ñáðîøåííûé ôëàã íàïðàâëåíèÿ
82
	и сегментные регистры ds=es=0. Форсирует сброшенный флаг направления
83
	è ðàçðåø¸ííûå ïðåðûâàíèÿ. Ñîõðàíÿåò èäåíòèôèêàòîð çàãðóçî÷íîãî äèñêà
83
	и разрешённые прерывания. Сохраняет идентификатор загрузочного диска
84
	â ñïåöèàëüíóþ ïåðåìåííóþ.
84
	в специальную переменную.
85
3. Ïðîâåðÿåò ïîääåðæêó LBA. Äëÿ CD/DVD íîñèòåëÿ BIOS îáÿçàíà ïðåäîñòàâëÿòü
85
3. Проверяет поддержку LBA. Для CD/DVD носителя BIOS обязана предоставлять
86
	LBA-ôóíêöèè.
86
	LBA-функции.
87
4. Èùåò îïèñàòåëü òîìà CD (Primary Volume Descriptor, PVD): ïî ñòàíäàðòó
87
4. Ищет описатель тома CD (Primary Volume Descriptor, PVD): по стандарту
88
	ISO9660 ñî ñìåùåíèÿ 10h íà÷èíàåòñÿ öåïî÷êà îïèñàòåëåé òîìà,
88
	ISO9660 со смещения 10h начинается цепочка описателей тома,
89
	çàâåðøàþùàÿñÿ ñïåöèàëüíûì îïèñàòåëåì (Volume Descriptor Set
89
	завершающаяся специальным описателем (Volume Descriptor Set
90
	Terminator). Êîä ïî î÷åðåäè ñ÷èòûâàåò âñå ñåêòîðà, ïîêà íå íàòêí¸òñÿ
90
	Terminator). Код по очереди считывает все сектора, пока не наткнётся
91
	ëèáî íà èñêîìûé îïèñàòåëü, ëèáî íà òåðìèíàòîð. Âî âòîðîì ñëó÷àå
91
	либо на искомый описатель, либо на терминатор. Во втором случае
92
	âûäà¸òñÿ ñîîòâåòñòâóþùåå ñîîáùåíèå, è çàãðóçêà ïðåêðàùàåòñÿ.
92
	выдаётся соответствующее сообщение, и загрузка прекращается.
93
Âîîáùå ãîâîðÿ, â ñëó÷àå ìóëüòèñåññèîííûõ CD îñíîâíîé êàòàëîã ñîäåðæèìîãî CD
93
Вообще говоря, в случае мультисессионных CD основной каталог содержимого CD
94
	ðàñïîëàãàåòñÿ â	ïîñëåäíåé ñåññèè. È ñïåöèôèêàöèÿ ElTorito çàãðóçî÷íîãî
94
	располагается в	последней сессии. И спецификация ElTorito загрузочного
95
	CD îïåðèðóåò òàêæå ñ ïîñëåäíåé ñåññèåé. Îäíàêî íà ïðàêòèêå îêàçûâàåòñÿ,
95
	CD оперирует также с последней сессией. Однако на практике оказывается,
96
	÷òî: âî-ïåðâûõ, ðåàëüíûå BIOSû íå ïîíèìàþò ìóëüòèñåññèîííûõ CD è
96
	что: во-первых, реальные BIOSы не понимают мультисессионных CD и
97
	âñåãäà èñïîëüçóþò ïåðâóþ ñåññèþ; âî-âòîðûõ, BIOSîâñêèé int 13h ïðîñòî
97
	всегда используют первую сессию; во-вторых, BIOSовский int 13h просто
98
	íå ïîçâîëÿåò ïîëó÷èòü èíôîðìàöèþ î ïîñëåäíåé ñåññèè.  ñâÿçè ñ ýòèì
98
	не позволяет получить информацию о последней сессии. В связи с этим
99
	çàãðóç÷èê òàêæå èñïîëüçóåò ïåðâóþ ñåññèþ. (Â-òðåòüèõ, â îäíîé èç BIOS
99
	загрузчик также использует первую сессию. (В-третьих, в одной из BIOS
100
	îáíàðóæèëàñü çàãîòîâêà, êîòîðàÿ â ñëó÷àå çàïðîñà ñåêòîðà 10h, â êîòîðîì
100
	обнаружилась заготовка, которая в случае запроса сектора 10h, в котором
101
	âî âñåõ íîðìàëüíûõ ñëó÷àÿõ è ðàñïîëàãàåòñÿ PVD, ïåðåíàïðàâëÿåò åãî
101
	во всех нормальных случаях и располагается PVD, перенаправляет его
102
	íà ñåêòîð 10h+(íà÷àëî ñåññèè). Åñëè áû ýòîò BIOS åù¸ è ãðóçèëñÿ ñ
102
	на сектор 10h+(начало сессии). Если бы этот BIOS ещё и грузился с
103
	ïîñëåäíåé ñåññèè, òî áëàãîäàðÿ çàãîòîâêå çàãðóç÷èê áåç âñÿêèõ
103
	последней сессии, то благодаря заготовке загрузчик без всяких
104
	ìîäèôèêàöèé òàêæå ÷èòàë áû ïîñëåäíþþ ñåññèþ.)
104
	модификаций также читал бы последнюю сессию.)
105
5. (ìåòêà pvd_found) Ñ÷èòûâàåò èç PVD íåêîòîðóþ èíôîðìàöèþ î òîìå âî
105
5. (метка pvd_found) Считывает из PVD некоторую информацию о томе во
106
	âíóòðåííèå ïåðåìåííûå: ðàçìåð ëîãè÷åñêîãî áëîêà (ñîãëàñíî ñïåöèôèêàöèè,
106
	внутренние переменные: размер логического блока (согласно спецификации,
107
	äîëæåí áûòü ñòåïåíüþ äâîéêè îò 512 äî ðàçìåðà ëîãè÷åñêîãî ñåêòîðà,
107
	должен быть степенью двойки от 512 до размера логического сектора,
108
	ðàâíîãî 2048 äëÿ CD è DVD); ïîëîæåíèå íà äèñêå êîðíåâîé ïàïêè;
108
	равного 2048 для CD и DVD); положение на диске корневой папки;
109
	âû÷èñëÿåò ÷èñëî áëîêîâ â ñåêòîðå (èç ïðåäûäóùåãî ïðèìå÷àíèÿ ñëåäóåò,
109
	вычисляет число блоков в секторе (из предыдущего примечания следует,
110
	÷òî îíî âñåãäà öåëîå è ñàìî ÿâëÿåòñÿ ñòåïåíüþ äâîéêè).
110
	что оно всегда целое и само является степенью двойки).
111
6. Ïîëó÷àåò ðàçìåð áàçîâîé ïàìÿòè âûçîâîì int 12h; íà åãî îñíîâå âû÷èñëÿåò
111
6. Получает размер базовой памяти вызовом int 12h; на его основе вычисляет
112
	ðàçìåð ïðîñòðàíñòâà, êîòîðîå ìîæåò èñïîëüçîâàòü çàãðóç÷èê (îò
112
	размер пространства, которое может использовать загрузчик (от
113
	àäðåñà 6000:0000 äî êîíöà äîñòóïíîé ïàìÿòè).
113
	адреса 6000:0000 до конца доступной памяти).
114
7. Çàãðóæàåò òàáëèöó ïóòåé CD (Path Table) - îáëàñòü äàííûõ, êîòîðàÿ ñîäåðæèò
114
7. Загружает таблицу путей CD (Path Table) - область данных, которая содержит
115
	áàçîâóþ èíôîðìàöèþ îáî âñåõ ïàïêàõ íà äèñêå. Åñëè òàáëèöà ñëèøêîì
115
	базовую информацию обо всех папках на диске. Если таблица слишком
116
	âåëèêà (áîëüøå 62K èëè áîëüøå ïîëîâèíû äîñòóïíîé ïàìÿòè), òî îíà
116
	велика (больше 62K или больше половины доступной памяти), то она
117
	èãíîðèðóåòñÿ. Åñëè òàáëèöà ïóòåé íåäîñòóïíà, òî çàïðîñ òèïà
117
	игнорируется. Если таблица путей недоступна, то запрос типа
118
	dir1/dir2/dir3/file ïðèâåä¸ò ê ïîñëåäîâàòåëüíîìó ðàçáîðó êîðíåâîé
118
	dir1/dir2/dir3/file приведёт к последовательному разбору корневой
119
	ïàïêè è ïàïîê dir1,dir2,dir3; åñëè äîñòóïíà, òî äîñòàòî÷íî ðàçîáðàòü
119
	папки и папок dir1,dir2,dir3; если доступна, то достаточно разобрать
120
	ñàìó òàáëèöó ïóòåé (ãäå çàïèñàíî ïîëîæåíèå ïàïêè dir1/dir2/dir3)
120
	саму таблицу путей (где записано положение папки dir1/dir2/dir3)
121
	è ïàïêó dir3. Åñëè òàáëèöà çàãðóæåíà, òî ñîîòâåòñòâåííî óìåíüøàåòñÿ
121
	и папку dir3. Если таблица загружена, то соответственно уменьшается
122
	îáú¸ì îñòàâøåéñÿ äîñòóïíîé ïàìÿòè è óâåëè÷èâàåòñÿ óêàçàòåëü íà
122
	объём оставшейся доступной памяти и увеличивается указатель на
123
	ñâîáîäíóþ îáëàñòü.
123
	свободную область.
124
8. Çàïîìèíàåò îáùèé ðàçìåð è íà÷àëî êýøà äëÿ ïàïîê (âñÿ îñòàâøàÿñÿ ïîñëå ï.7
124
8. Запоминает общий размер и начало кэша для папок (вся оставшаяся после п.7
125
	äîñòóïíàÿ ïàìÿòü îòâîäèòñÿ ïîä ýòîò êýø).
125
	доступная память отводится под этот кэш).
126
9. Âûäà¸ò çàïðîñ íà ÷òåíèå ôàéëà âòîðè÷íîãî çàãðóç÷èêà kord/loader. Ïðè îøèáêå
126
9. Выдаёт запрос на чтение файла вторичного загрузчика kord/loader. При ошибке
127
	ïå÷àòàåò ñîîòâåòñòâóþùåå ñîîáùåíèå è ïðåêðàùàåò çàãðóçêó ñ CD.
127
	печатает соответствующее сообщение и прекращает загрузку с CD.
128
10. Óñòàíàâëèâàåò ðåãèñòðû äëÿ âòîðè÷íîãî çàãðóç÷èêà: al='c' èäåíòèôèöèðóåò
128
10. Устанавливает регистры для вторичного загрузчика: al='c' идентифицирует
129
	òèï óñòðîéñòâà - CD/DVD; ah=BIOS-èäåíòèôèêàòîð äèñêà; bx='is'
129
	тип устройства - CD/DVD; ah=BIOS-идентификатор диска; bx='is'
130
	èäåíòèôèöèðóåò ôàéëîâóþ ñèñòåìó ISO-9660; ds:si óêàçûâàåò íà
130
	идентифицирует файловую систему ISO-9660; ds:si указывает на
131
	callback-ôóíêöèþ, êîòîðóþ ìîæåò âûçûâàòü âòîðè÷íûé çàãðóç÷èê.
131
	callback-функцию, которую может вызывать вторичный загрузчик.
132
11. Ïåðåäà¸ò óïðàâëåíèå âòîðè÷íîìó çàãðóç÷èêó, ñîâåðøàÿ äàëüíèé ïðûæîê
132
11. Передаёт управление вторичному загрузчику, совершая дальний прыжок
133
	íà àäðåñ, êóäà kord/loader áûë çàãðóæåí.
133
	на адрес, куда kord/loader был загружен.
134
 
134
 
135
Ôóíêöèÿ îáðàòíîãî âûçîâà äëÿ âòîðè÷íîãî çàãðóç÷èêà (callback):
135
Функция обратного вызова для вторичного загрузчика (callback):
136
	ïðåäîñòàâëÿåò âîçìîæíîñòü ÷òåíèÿ ôàéëà.
136
	предоставляет возможность чтения файла.
137
Âõîä è âûõîä îïèñàíû â ñïåöèôèêàöèè íà çàãðóç÷èê.
137
Вход и выход описаны в спецификации на загрузчик.
138
Ïåðåíàïðàâëÿåò çàïðîñ ñîîòâåòñòâóþùåé ëîêàëüíîé ïðîöåäóðå (load_file ïðè
138
Перенаправляет запрос соответствующей локальной процедуре (load_file при
139
	ïåðâîì çàïðîñå íà çàãðóçêó ôàéëà, loadloop.loadnew ïðè ïîñëåäóþùèõ
139
	первом запросе на загрузку файла, loadloop.loadnew при последующих
140
	çàïðîñàõ íà ïðîäîëæåíèå çàãðóçêè ôàéëà).
140
	запросах на продолжение загрузки файла).
141
 
141
 
142
Âñïîìîãàòåëüíûå ïðîöåäóðû.
142
Вспомогательные процедуры.
143
Êîä îáðàáîòêè îøèáîê (err):
143
Код обработки ошибок (err):
144
1. Âûâîäèò ñòðîêó ñ ñîîáùåíèåì îá îøèáêå.
144
1. Выводит строку с сообщением об ошибке.
145
2. Âûâîäèò ñòðîêó "Press any key...".
145
2. Выводит строку "Press any key...".
146
3. Æä¸ò íàæàòèÿ any key.
146
3. Ждёт нажатия any key.
147
4. Âûçûâàåò int 18h, äàâàÿ øàíñ BIOSó ïîïûòàòüñÿ çàãðóçèòüñÿ îòêóäà-íèáóäü åù¸.
147
4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё.
148
5. Äëÿ ïîäñòðàõîâêè çàöèêëèâàåòñÿ.
148
5. Для подстраховки зацикливается.
149
 
149
 
150
Ïðîöåäóðà ÷òåíèÿ ñåêòîðîâ (read_sectors):
150
Процедура чтения секторов (read_sectors):
Line 304... Line 304...
304
	â öèêëå çàãðóæàåò íåïðåðûâíûå ÷àñòè ñ ïîìîùüþ òîé æå ôóíêöèè,
304
	в цикле загружает непрерывные части с помощью той же функции,
305
	â ïðîìåæóòêàõ ìåæäó ÷àñòÿìè óâåëè÷èâàÿ íîìåð íà÷àëüíîãî áëîêà.
305
	в промежутках между частями увеличивая номер начального блока.
306
	Ïîêà íå êîí÷èòñÿ ôðàãìåíò èëè ïîêà íå íàáåð¸òñÿ çàïðîøåííîå ÷èñëî áàéò.
306
	Пока не кончится фрагмент или пока не наберётся запрошенное число байт.
307
	Ïðè îøèáêå ÷òåíèÿ äåëàåò òî æå ñàìîå, ÷òî è â ïðåäûäóùåì ñëó÷àå.
307
	При ошибке чтения делает то же самое, что и в предыдущем случае.
308
27. (loadloop.loadcontinue) Åñëè ôðàãìåíòû åù¸ íå êîí÷èëèñü è ïðåäåëüíûé ðàçìåð
308
27. (loadloop.loadcontinue) Если фрагменты ещё не кончились и предельный размер
309
	åù¸ íå äîñòèãíóò, ïåðåõîäèò ê ñëåäóþùåìó ôðàãìåíòó è ï.20. Â ïðîòèâíîì
309
	ещё не достигнут, переходит к следующему фрагменту и п.20. В противном
310
	ñëó÷àå óñòàíàâëèâàåò bx=0 ëèáî bx=1 â çàâèñèìîñòè îò òîãî, áûëî ëè
310
	случае устанавливает bx=0 либо bx=1 в зависимости от того, было ли
311
	ïåðåïîëíåíèå â ï.23.
311
	переполнение в п.23.
312
28. (loadloop.calclen) Ïîäñ÷èòûâàåò îáùóþ äëèíó ôàéëà, ñóììèðóÿ äëèíû âñåõ
312
28. (loadloop.calclen) Подсчитывает общую длину файла, суммируя длины всех
313
	ôðàãìåíòîâ.
313
	фрагментов.
314
 
314
 
315
Ïðîöåäóðà ïðîâåðêè, ÿâëÿåòñÿ ëè òåêóùàÿ êîìïîíåíòà èìåíè ôàéëà ïîñëåäíåé
315
Процедура проверки, является ли текущая компонента имени файла последней
316
	(is_last_component):
316
	(is_last_component):
317
íà âõîäå: ds:si = óêàçàòåëü íà èìÿ
317
на входе: ds:si = указатель на имя
318
íà âûõîäå: ôëàã CF óñòàíîâëåí, åñëè åñòü ïîñëåäóþùèå êîìïîíåíòû
318
на выходе: флаг CF установлен, если есть последующие компоненты
319
 öèêëå çàãðóæàåò ñèìâîëû èìåíè â ïîèñêàõ íóëåâîãî è '/'; åñëè íàø¸ëñÿ ïåðâûé,
319
В цикле загружает символы имени в поисках нулевого и '/'; если нашёлся первый,
320
	òî âûõîäèò (ïðè ýòîì CF=0); åñëè íàø¸ëñÿ âòîðîé, òî óñòàíàâëèâàåò CF
320
	то выходит (при этом CF=0); если нашёлся второй, то устанавливает CF
321
	è âûõîäèò.
321
	и выходит.
322
 
322
 
323
Ïðîöåäóðû ïðîâåðêè íà ñîâïàäåíèå òåêóùåé êîìïîíåíòû èìåíè ôàéëà ñ èìåíåì
323
Процедуры проверки на совпадение текущей компоненты имени файла с именем
324
òåêóùåãî ýëåìåíòà (test_filename1 äëÿ òàáëèöû ïóòåé, test_filename2 äëÿ ïàïêè):
324
текущего элемента (test_filename1 для таблицы путей, test_filename2 для папки):
325
íà âõîäå: ds:si = óêàçàòåëü íà èìÿ, es:di = óêàçàòåëü íà ýëåìåíò
325
на входе: ds:si = указатель на имя, es:di = указатель на элемент
326
	òàáëèöû ïóòåé äëÿ test_filename1, ïàïêè äëÿ test_filename2
326
	таблицы путей для test_filename1, папки для test_filename2
327
íà âûõîäå: CF óñòàíîâëåí, åñëè èìåíà íå ñîâïàäàþò
327
на выходе: CF установлен, если имена не совпадают
328
 öèêëå ïðîâåðÿåò ñîâïàäåíèå ïðèâåä¸ííûõ ê âåðõíåìó ðåãèñòðó î÷åðåäíûõ ñèìâîëîâ
328
В цикле проверяет совпадение приведённых к верхнему регистру очередных символов
329
	èì¸í ôàéëà è ýëåìåíòà. Óñëîâèÿ âûõîäà èç öèêëà: çàêîí÷èëîñü èìÿ ôàéëà
329
	имён файла и элемента. Условия выхода из цикла: закончилось имя файла
330
	â ds:si (òî åñòü, î÷åðåäíîé ñèìâîë - íóëåâîé ëèáî '/') - ñîâïàäåíèå
330
	в ds:si (то есть, очередной символ - нулевой либо '/') - совпадение
331
	âîçìîæíî òîëüêî â ñèòóàöèè òèïà èìåíè "filename.ext" è ýëåìåíòà
331
	возможно только в ситуации типа имени "filename.ext" и элемента
332
	"filename.ext;1" (â ISO9660 ";1" - âåðñèÿ ôàéëà, ýëåìåíòû ñ îäèíàêîâûìè
332
	"filename.ext;1" (в ISO9660 ";1" - версия файла, элементы с одинаковыми
333
	èìåíàìè â ïàïêå îòñîðòèðîâàíû ïî óáûâàíèþ âåðñèé);
333
	именами в папке отсортированы по убыванию версий);
334
	íåñîâïàäåíèå ñèìâîëîâ - îçíà÷àåò, ÷òî èìåíà íå ñîâïàäàþò;
334
	несовпадение символов - означает, что имена не совпадают;
335
	çàêîí÷èëîñü èìÿ ýëåìåíòà - íóæíî ïðîâåðèòü, çàêîí÷èëîñü ëè ïðè ýòîì èìÿ
335
	закончилось имя элемента - нужно проверить, закончилось ли при этом имя
336
	ôàéëà, è â çàâèñèìîñòè îò ýòîãî ïðèíèìàòü ðåøåíèå î ñîâïàäåíèè.
336
	файла, и в зависимости от этого принимать решение о совпадении.
337
 
337
 
338
Ïðîöåäóðà ïðèâåäåíèÿ ñèìâîëà â âåðõíèé ðåãèñòð (toupper):
338
Процедура приведения символа в верхний регистр (toupper):
339
íà âõîäå: ASCII-ñèìâîë
339
на входе: ASCII-символ
340
íà âûõîäå: òîò æå ñèìâîë â âåðõíåì ðåãèñòðå (îí ñàì, åñëè ïîíÿòèå ðåãèñòðà ê
340
на выходе: тот же символ в верхнем регистре (он сам, если понятие регистра к
341
	íåìó íåïðèìåíèìî)
341
	нему неприменимо)
342
Èç ñèìâîëîâ â äèàïàçîíå 'a' - 'z' âêëþ÷èòåëüíî âû÷èòàåò êîíñòàíòó 'a'-'A',
342
Из символов в диапазоне 'a' - 'z' включительно вычитает константу 'a'-'A',
343
	îñòàëüíûå ñèìâîëû íå òðîãàåò.
343
	остальные символы не трогает.
344
 
344
 
345
Ïðîöåäóðà ïîèñêà ôàéëà â äàííûõ ïàïêè (scan_for_filename_in_sector):
345
Процедура поиска файла в данных папки (scan_for_filename_in_sector):
346
íà âõîäå:
346
на входе:
347
	ds:si = óêàçàòåëü íà èìÿ ôàéëà
347
	ds:si = указатель на имя файла
348
	es:bx = óêàçàòåëü íà íà÷àëî äàííûõ ïàïêè
348
	es:bx = указатель на начало данных папки
349
	es:dx = óêàçàòåëü íà êîíåö äàííûõ ïàïêè
349
	es:dx = указатель на конец данных папки
350
íà âûõîäå:
350
на выходе:
351
	CF ñáðîøåí, åñëè íàéäåí ôèíàëüíûé ôðàãìåíò ôàéëà
351
	CF сброшен, если найден финальный фрагмент файла
352
		(è äàëüøå ñêàíèðîâàòü ïàïêó íå íóæíî)
352
		(и дальше сканировать папку не нужно)
353
	â îáëàñòü äëÿ èíôîðìàöèè î ôðàãìåíòàõ ôàéëà çàïèñûâàåòñÿ íàéäåííîå
353
	в область для информации о фрагментах файла записывается найденное
354
 öèêëå ïðîñìàòðèâàåò âñå âõîäû ïàïêè, ïðîïóñêàÿ òå, ó êîòîðûõ óñòàíîâëåí
354
В цикле просматривает все входы папки, пропуская те, у которых установлен
355
	áèò Associated (ýòî ñïåöèàëüíûå âõîäû, äîïîëíÿþùèå îñíîâíûå). Åñëè
355
	бит Associated (это специальные входы, дополняющие основные). Если
356
	èìÿ î÷åðåäíîãî âõîäà ñîâïàäàåò ñ èìåíåì ôàéëà, òî çàïîìèíàåò íîâûé
356
	имя очередного входа совпадает с именем файла, то запоминает новый
357
	ôðàãìåíò. Åñëè ôðàãìåíò ôèíàëüíûé (íå óñòàíîâëåí áèò Multi-Extent),
357
	фрагмент. Если фрагмент финальный (не установлен бит Multi-Extent),
358
	òî êîä âûõîäèò ñ CF=0. Åñëè äîñòèãíóò êîíåö äàííûõ, òî êîä âûõîäèò
358
	то код выходит с CF=0. Если достигнут конец данных, то код выходит
359
	ñ CF=1. Åñëè î÷åðåäíîé âõîä íóëåâîé (ïåðâûé áàéò íàñòîÿùåãî âõîäà
359
	с CF=1. Если очередной вход нулевой (первый байт настоящего входа
360
	ñîäåðæèò äëèíó è íå ìîæåò áûòü íóë¸ì), òî ïðîöåäóðà ïåðåõîäèò ê
360
	содержит длину и не может быть нулём), то процедура переходит к
361
	ðàññìîòðåíèþ ñëåäóþùåãî ëîãè÷åñêîãî áëîêà. Ïðè ýòîì ïîòåíöèàëüíî
361
	рассмотрению следующего логического блока. При этом потенциально
362
	âîçìîæíî ïåðåïîëíåíèå ïðè äîáàâëåíèè ðàçìåðà áëîêà; ïîñêîëüêó òàêîé
362
	возможно переполнение при добавлении размера блока; поскольку такой
Line 363... Line 363...
363
	ñöåíàðèé îçíà÷àåò, ÷òî ïðîöåäóðà âûçâàíà äëÿ êýøèðîâàííîé ïàïêè
363
	сценарий означает, что процедура вызвана для кэшированной папки
364
	ñ ðàçìåðîì ïî÷òè 64K è íà÷àëîì äàííûõ bx=0 (ýòî ñâîéñòâî âûçûâàþùåãî
364
	с размером почти 64K и началом данных bx=0 (это свойство вызывающего
365
	êîäà), à ðàçìåð áëîêà - ñòåïåíü äâîéêè, òî ïîñëå ïåðåïîëíåíèÿ âñåãäà
365
	кода), а размер блока - степень двойки, то после переполнения всегда
366
	bx=0, òàê ÷òî ýòî ìîæíî îáíàðóæèòü ïî âçâåä¸ííîìó ZF ïîñëå ñëîæåíèÿ;
366
	bx=0, так что это можно обнаружить по взведённому ZF после сложения;
367
	â ýòîì ñëó÷àå òàêæå ïðîèñõîäèò âûõîä (à ïîñëå ïåðåïîëíåíèÿ CF=1).
367
	в этом случае также происходит выход (а после переполнения CF=1).
368
 
368
 
369
Ïðîöåäóðà ïåðåâîäà ëîãè÷åñêîãî áëîêà â íîìåð ñåêòîðà:
369
Процедура перевода логического блока в номер сектора:
370
íà âõîäå: eax = ëîãè÷åñêèé áëîê
370
на входе: eax = логический блок
371
íà âûõîäå: eax = ôèçè÷åñêèé ñåêòîð, dx = íîìåð ëîãè÷åñêîãî áëîêà â ñåêòîðå
371
на выходе: eax = физический сектор, dx = номер логического блока в секторе
372
Îñóùåñòâëÿåò îáû÷íîå äåëåíèå 32-áèòíîãî ÷èñëà íà 32-áèòíîå (÷èñëî ëîãè÷åñêèõ
372
Осуществляет обычное деление 32-битного числа на 32-битное (число логических
373
	áëîêîâ â ñåêòîðå, õðàíÿùååñÿ âî âíóòðåííåé ïåðåìåííîé).
373
	блоков в секторе, хранящееся во внутренней переменной).
374
 
374
 
375
Ïðîöåäóðà çàãðóçêè ôèçè÷åñêîãî ñåêòîðà, ñîäåðæàùåãî óêàçàííûé ëîãè÷åñêèé áëîê
375
Процедура загрузки физического сектора, содержащего указанный логический блок
376
	(load_phys_sector_for_lb_force):
376
	(load_phys_sector_for_lb_force):
377
íà âõîäå: eax = ëîãè÷åñêèé áëîê;
377
на входе: eax = логический блок;
378
	si - èíäèêàòîð, çàäàþùèé, ñëåäóåò ëè ÷èòàòü äàííûå â ñëó÷àå,
378
	si - индикатор, задающий, следует ли читать данные в случае,
379
		åñëè ëîãè÷åñêèé áëîê íà÷èíàåòñÿ ñ íà÷àëà ôèçè÷åñêîãî:
379
		если логический блок начинается с начала физического:
380
	si = 0 - íå íóæíî, si íåíóëåâîé - íóæíî
380
	si = 0 - не нужно, si ненулевой - нужно
381
íà âûõîäå:
381
на выходе:
382
	ôèçè÷åñêèé ñåêòîð çàãðóæåí ïî àäðåñó 0000:1000
382
	физический сектор загружен по адресу 0000:1000
383
	si óêàçûâàåò íà äàííûå ëîãè÷åñêîãî áëîêà
383
	si указывает на данные логического блока
384
	CF óñòàíîâëåí ïðè îøèáêå ÷òåíèÿ
384
	CF установлен при ошибке чтения
385
Ïðåîáðàçóåò ïðåäûäóùåé ïðîöåäóðîé íîìåð ëîãè÷åñêîãî áëîêà â íîìåð ôèçè÷åñêîãî
385
Преобразует предыдущей процедурой номер логического блока в номер физического
386
	ñåêòîðà è íîìåð ëîãè÷åñêîãî áëîêà âíóòðè ñåêòîðà; åñëè ïîñëåäíÿÿ
386
	сектора и номер логического блока внутри сектора; если последняя
387
	âåëè÷èíà íóëåâàÿ è íèêàêèõ äåéñòâèé â ýòîì ñëó÷àå íå çàïðîøåíî (si=0),
387
	величина нулевая и никаких действий в этом случае не запрошено (si=0),
388
	òî íè÷åãî è íå äåëàåò; èíà÷å óñòàíàâëèâàåò si â ñîîòâåòñòâèè ñ íåé
388
	то ничего и не делает; иначе устанавливает si в соответствии с ней
389
	è ÷èòàåò ñåêòîð.
389
	и читает сектор.
390
 
390
 
391
Ïðîöåäóðû ÷òåíèÿ íóæíîãî ÷èñëà áàéò èç íåïðåðûâíîé öåïî÷êè ëîãè÷åñêèõ áëîêîâ
391
Процедуры чтения нужного числа байт из непрерывной цепочки логических блоков
392
	(read_many_bytes è read_many_bytes.with_first):
392
	(read_many_bytes и read_many_bytes.with_first):
393
íà âõîäå:
393
на входе:
394
	eax = ëîãè÷åñêèé áëîê
394
	eax = логический блок
395
	esi = ÷èñëî áàéò äëÿ ÷òåíèÿ
395
	esi = число байт для чтения
396
	es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå
396
	es:bx = указатель на начало буфера, куда будут прочитаны данные
397
	cur_limit = ðàçìåð áóôåðà (íå ìåíüøå esi)
397
	cur_limit = размер буфера (не меньше esi)
398
íà âûõîäå:
398
на выходе:
399
	es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå
399
	es:bx указывает на конец буфера, в который были прочитаны данные
400
	åñëè ïðîèçîøëà îøèáêà ÷òåíèÿ, ôëàã CF óñòàíîâëåí
400
	если произошла ошибка чтения, флаг CF установлен
401
	cur_limit ñîîòâåòñòâóþùèì îáðàçîì óìåíüøåí
401
	cur_limit соответствующим образом уменьшен
402
Îòëè÷èå äâóõ ïðîöåäóð: âòîðàÿ äîïîëíèòåëüíî ïðèíèìàåò âî âíèìàíèå ïåðåìåííóþ
402
Отличие двух процедур: вторая дополнительно принимает во внимание переменную
403
	[first_byte], íà÷èíàÿ ÷òåíèå ïåðâîãî áëîêà ñî ñìåùåíèÿ [first_byte];
403
	[first_byte], начиная чтение первого блока со смещения [first_byte];
404
	ñîîòâåòñòâåííî, ïåðâàÿ ÷èòàåò áëîê ñ íà÷àëà, îáíóëÿÿ [first_byte]
404
	соответственно, первая читает блок с начала, обнуляя [first_byte]
405
	ïðè âõîäå.
405
	при входе.
406
1. Îòäåëüíî ñ÷èòûâàåò ïåðâûé ôèçè÷åñêèé ñåêòîð âî âðåìåííóþ îáëàñòü 0000:1000,
406
1. Отдельно считывает первый физический сектор во временную область 0000:1000,