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, |