Внутреннее устройство ядра Linux 2.4



         

Загрузка: bootsector и setup - часть 2


Строки 54-63 перемещают код начального загрузчика из адреса 0x7C00 в адрес 0x90000. Для этого:

  • в регистровую пару %ds:%si заносится значение $BOOTSEG:0 (0x7C0:0 = 0x7C00)
  • в регистровую пару %es:%di заносится значение $INITSEG:0 (0x9000:0 = 0x90000)
  • в регистр %cx записывается число 16-битовых слов (256 слов = 512 байт = 1 сектор)
  • В регистре флагов EFLAGS сбрасывается флаг направления DF (Direction Flag) (копирование с автоинкрементом адресных регистров) (cld)
  • копируется 512 байт (rep movsw)
  • Здесь умышленно не используется инструкция rep movsd (обратите внимание на директиву - .code16).

    В строке 64 выполняется переход на метку go:, в только что созданную копию загрузчика, т.е. в сегмент 0x9000. Эта, и следующие три инструкции (строки 64-76) переустанавливают регистр сегмента стека и регистр указателя стека на $INITSEG:0x4000-0xC, т.е. %ss = $INITSEG (0x9000) и %sp = 0x3FF4 (0x4000-0xC). Это и есть то самое ограничение на размер setup, которое упоминалось ранее (см. Построение образа ядра Linux).

    Для того, чтобы разрешить считывание сразу нескольких секторов (multi-sector reads), в строках 77-103 исправляются некоторые значения в таблице параметров для первого диска :

    77 # Часто в BIOS по умолчанию в таблицы параметров диска не признают 78 # чтение по несколько секторов кроме максимального числа, указанного 79 # по умолчанию в таблице параметров дискеты - что может иногда равняться 80 # 7 секторам. 81 # 82 # Поскольку чтение по одному сектору отпадает (слишком медленно), 83 # необходимо позаботиться о создании в ОЗУ новой таблицы параметров 84 # (для первого диска). Мы установим максимальное число секторов 85 # равным 36 - максимум, с которым мы столкнемся на ED 2.88. 86 # 87 # Много - не мало. А мало - плохо. 88 # 89 # Сегменты устанавливаются так: ds = es = ss = cs - INITSEG, fs = 0, 90 # а gs не используется.

    91 movw %cx, %fs # запись 0 в fs 92 movw $0x78, %bx # в fs:bx адрес таблицы 93 pushw %ds 94 ldsw %fs:(%bx), %si # из адреса ds:si 95 movb $6, %cl # копируется 12 байт 96 pushw %di # di = 0x4000-12. 97 rep # инструкция cld не нужна - выполнена в строке 66 98 movsw 99 popw %di 100 popw %ds 101 movb $36, 0x4(%di) # записывается число секторов 102 movw %di, %fs:(%bx) 103 movw %es, %fs:2(%bx)




    Содержание  Назад  Вперед