Лекция 8 (2012-12-03)

Начальная загрузка

Есть некая платформа -- system on chip, или процессор+чипсет+память+северный мост+южный мост, есть power source, есть периферия. Устройства подключены кто-то через южный мост, кто-то через северный. Включаем питание: в памяти полная каша, процессор ничего не помнит. Есть некоторое количество энергонезависимой памяти. Было бы недурно правильно все это безобразие инициализировать и заставить работать. Не все можно закодировать в железе. В встраиваемых системах ещё лет 20 назад вся конфигурация выполнялась замыканием проводов. Вся логика реализовывалась в железе. Конфигурация логической схемы хранилась в энергонезависимой памяти. Вся конфигурация занимала 10-100 пинов. Таким образом можно управлять микроволновками, стиральными машинами. Все это чудесно, но для чипа[сложнее мозга микроволновки] эта штука затратная. Логично вынести инициализацию во вне. Поэтому обычно есть отдельный чип, где хранится инициализационная программа.

В x86 процессор включается и начинает что-то выполнять. Инициализировался и сообразно настройке пинов что-то выполняет. У ARM и system-on-chip довольно долго был разброс и шатание -- как проводить инициализацию. Были системы типа SPARC, POWER PC, у которых все было хорошо, но однообразно. В x86 все довольно кучеряво, поэтому про него и рассказ. Это вообще обычная ситуация для x86, во всех других системах все скучно и работает, а в x86 все кучеряво.

Обычно у процессора и чипа есть некоторое множество конфигурационных чипов. Мануалы про это дело занимают не одну сотню страниц. Помимо пинов есть ещё внутреннее состояние. Тем не менее, есть возможность так или иначе (в зависимости от конкретного чипсета) завести некий диапазон адресов на энергонезависимую флешку.

Но как решается проблема инициализации? Волевым решением. Говорим, что есть адрес reset vector (который регулируем пинами), с которого начинаем выполнение. x86, даже 64-битные, начинает работать в реальном режиме. Есть адрес CS F000h IP FFF0h это получается адрес FFFF0h. В реальном режиме осталось всего 16 бит и этот адрес содержит указатель на код BIOS.

В реальности помимо BIOS сейчас есть ещё UEFI. С точки зрения инициализации они не очень отличаются, UEFI структурно более лучше, но реально нужен чтобы дропнуть большое количество легаси. Реально для южного моста, северного моста, процессора все мануалы считают, что UEFI это тот же BIOS, ибо неважно.

Можно сделать x86 вообще без BIOS, но она будет печально работать, потому что хорошо бы предоставлять хотя бы int 13h. Если его и других полезных вещей не предоставить, то придется патчить систему и большое количество драйверов.

Изначально название BIOS взялось с машин работавших с pcm(??). В конце 70х, когда появились восьмибитные 8080, никакого BIOS не было, все было в hardware. BIOS реализовал базовую работу со всем -- с видеоадаптерами, с вводом-выводом. PC XT. IBM PC/AT среди прочего появился AT_attachement и привычный BIOS -- отдельная микросхема, просто ROM, и она содержала тот самый вынесенный код для инициализации системы. Там была такая штука как POST, зачатки энумерации устройств. Интерфейс ATA конфигурировался железно, [как и?] ISA шина. Все работало довольно грустно.

Потом появилось и было стандартизовано много чего. В начале-середине 2000х появился новый стандат ACPI, APM, DMI/SMBIOS, ESCD.

С ходом времени выделилось несколько устройств с которых можно грузиться:

Все это знание приобретенное. Есть ATA устройства, с ними общение происходит посредством чтения-записи регистрового файла, который находится известно где и северный мост позволяет им управять. BIOS видит посредством интерфейса ATA, что есть несколько дисков, с одного из них можно положить 512 байт в память и на них джампнуться. Конфигурация хранилась на отдельном устройстве с батареечками, сейчас кладут на флеш или капаситор -- конденсатор большой емкости для подпитки памяти.

Помимо ATA устройств внятно сконфигурировать можно ещё PCI устройства. Там есть, условно говоря, северный или южный мост, скорее всего северный, там либо PCI арбитр, либо ещё что-то. Так или иначе, к этим PCI устройствам можно получать доступ по магическим адресам. Можно замапить на них определенный регион памяти.

В конфигурационном пространстве устойства написано, что у него есть PCI device ROM. Этот девайс ROM куда-то отмапится путем записи смещения в конфигурационное пространство, и вы чудесным образом этот ROM сможете либо считать, либо сджампиться. У него есть 2 варианта -- x86 код или байт код на форте. BIOS для второго варианта должен поддерживать open firmware. Все это грузится после POST, потому что POST включает тактирование процессора, проверку памяти, проверку периферийных устройств - жестких дисков, некоторые BIOS умеют PCI устройства.

BIOS обладает настолько когнитивными свойствами, что может понять, что некое PCI устройство на самом деле -- контроллер USB и поднять USB.

Есть ещё вариант, когда это делает сам северный мост. Лектор не помнит в каком случае что копируется, это сильно зависит от пары мостов, они могут кэщировать BIOS.

Мануалы для BIOS программера для sp5100 -- 150 страниц. Описание всех фич. Там можно настраивать то, как раскидываются PCIe лейны, как конфигурировать 6 линий ATA, которые у него есть, и много чего ещё . Куча таблиц связанных с конфигурацией встроенной поддержки звука, и т.д.

BIOS занимается чем -- поднимается. Есть ещё некая логика, которая управляет сигналами питания -- включили железку в блок питания, это тоже есть некое взаимодействие. Помимо вольтажа питания стандарт ATX предусматривает наличие сигналов типа PowerGood, после которого сигналы питания могут роутиться дальше. Питание стабилизировалось -- можно отдавать дальше. Оно идет на периферию, платформу... По поводу того, как питается это хозяйство -- там довольно много преобразователей прямого тока, потому что напряжение платформы может составлять сотни ватт.

ACPI

В начале исторически был APN. Этот стандарт был разработан совместно Intel и Microsoft по поводу advanced power management. Доступ был к зашедоуленному диапазону адресов. Нажали кнопку питания, садится батарейка с одной стороны, с другой стороны перевод со стороны софта происходят переходы в разное состояние. С другой стороны стандарт дропнут через 10 лет окончательно, что часто случается со стандартами Microsoft.

С одной стороны ACPI энумерирует устройства, с другой стороны позволяет управлять питанием.

Есть несколько наборов стейтов:

Различные устройства -- процессор, северный и южный мост поддерживают переходы в различное состояние. Если переходим в C2 clock off, процессор софту доступен, но типа спит. Этому соответствует погашивание клока и остаются интерфейсные схемы, чтобы перевести обратно в C0. Самое рабочее состояние 0, остальные -- всякое энергосбережение.

С стейты специфичны для процессоров. В K8 K10 есть C1S который типа лучше чем C1 в плане энергосбережения. Но зато они пожертвовали C2.

ASPM

Power management. В PCI появились стейты, и между ними можно было как-то переходить, но никто этим никогда не пользовался. Все отдавалось на усмотрение производителя железки. В PCIe это все было стандартизовано, и этим могло управлять программное обеспечение. В стандарте все было прописано. Дефакто все на это забивают и до сих пор если какое-то железо начинает пропадать или очень странно определяться, один из первых вариантов -- выключить ASPM.

DMI/SMBIOS

Ещё один способ энумерации железа.

SMBIOS стандартизирует способ доступа к таблицам и формат таблиц с информацией о платформе. dmadecode - утилита рассказывает много интересного о системе.

Ручек к BIOS из ос немного -- 13 прерывание, а сам BIOS вы с ним особенно ничего не поделаете, а SMBIOS дает возможность на что-то из железа повлиять.

ESCD

Пример, касающийся маппинга ресурсов -- IRQ, DMA-каналы, регионы. Если BIOS при загрузке видит, что конфигурация совпала, он берет предыдущий маппинг, а если не совпала, то по некоему алгоритму.

MMIO

в x86, и не только, он введен через диапазон адресов, при чтении и записи в которые работает некий мозг записи на определенные пины. У вас есть последовательный порт, сейчас он ногами н торчит, северный мост знает, что его надо отдать, и он у него в печенке сидит.

Последовательный порт это 003f8. Если вы будете писать в этот порт байтики.

Схема.

Может быть включится лампочка.

Все это было нагромождением тайного знания. Если вы пишите собственный BIOS, это тайное знание все равно надо поддерживать.

UEFI имеет некоторую модульную структуру. У UEFI базовый стандарт открыт, закрыты некоторые расширения. Для понимания базового стандарта достаточно.

Есть некий кернел, который представляет собой все тот же самый чуть ли не BIOS, поверх которого вешаются сервисы, которых может быть довольно много, с которыми взаимодейстует ОС. Теперь, вместо того, чтобы писать байтики напрямую, вы будете использовать красивый интерфейс для делания того же самого. Он подмял под себя все, что раньше регулировалось пачкой стандартов.

Как вы могли заметить, загрузка устройства -- штука простая, магии никакой нет. Подают питание, а дальше флешка с произвольным кодом, который должен либо загрузить ОС, либо восстановить.

ОС реализуют ту же функциональность -- энумерируют шины, вот это все. Почему бы на не выкинуть BIOS и не воткнуть туда ОС? Идея закономерная и реализуемая. Есть такая штука как speedboot. LinuxBIOS, coreboot, которая собственно и занимается тем, что инициализирует железо.

Один из вариантов реализации BIOSа, который интересен тем, что он познаваем. Амишный BIOS, felix можно уже посмотреть. С этой точки зрения представляет интерес.

Зачастую BIOS не копируется. BIOS разделен на 3-4 части и эти разные части имеют разное назначение. Есть часть которая не перепрошивается, там может не быть энумерации но систему оно поднимет, чексумму остальных частей проверит.

LecturesCMC/ComputerArchitecture2012/Conspects/07 (последним исправлял пользователь Allena 2012-12-21 02:34:19)