Comments 73
"Каждый такой регистр имеет 16 бит в ширину и 2 байта в длину."
Это как?
• test.elf: имя входного файла (соответствующий платформе формат хранения исполняемых файлов. Windows: PE, Linux: ELF)
• -o: генерация объектного кода.
• test.o: имя выходного файла объектного кода.
слова «входной» и «выходной» надо бы поменять местами.
А MBR не покрывает более 1Tb диска.
классическая таблица разделов содержит в себе величины DWORD для описания смещений и длин разделов в секторах. 32 бита без знака позволяют описать от 0 до 4 294 967 295 секторов
При размере сектора 512 байт — это будет ровненько 2ТБ
беря в расчет менее привычные случаи, например сектор 4096 байт, получим поддерживаемую емкость в 16ТБ.
И кстати, на для рисования на x86 намаплен фреймбуфер начиная с адреса 0xA0000.
Крайне любопытно, не покидаете ссылочек что почитать?
О нет, очередная, стопицотая (даже на хабре) статья о том, как написать загрузчик для legacy-режима. Да его поддержку уже выпилить собираются из новых материнских плат.
TL;NR
- Берете EDK2
- Следуете гайду и делаете HelloWorld
- Полученный efi переименовываете как bootx64.efi и кладете в /EFI/BOOT на любом fat32 носителе.
???грузитесь с него- Profit!
Распространенные ответы:
Q: Я просто хотел понять, как это все работает "ближе к железу", без этих ваших выскоуровневых EFI
A: legacy-режим — это не ближе к железу, а слой совместимости
А черт его знает. С одной стороны даже не смешно. В 2021 году не все даже знают о дискетах. И Legacy слой действительно своего рода HAL. С другой стороны браться за x64 не представляя себе работу x86 так себе идея.
В целом согласен — лучше силы на какой-нить микроконтроллер потратить. С другой стороны современная архитектура x64 это такой монстр, что даже слой UEFI не сильно спасает.
А вот что статей про "Hello, World" на UEFI, да с графикой действительно не хватает. Больше того — я таких вообще не припомню. А вот про Legacy было очень много. Хотя, мое мнение, по этой части руководства для вирусописателей времён MSDOS и Window 3.11 много полезнее и информативные. Впрочем, они подразумевают знание ассемблера и базовой x86 обвязки, что сегодня уже редкость. Потому какую-то ценность эти статьи имеют. Не стоит, наверное, гнать их в шею. Пусть пока остаются. Мало ли кого реально заинтересует.
Весьма и весьма интересны!
p.s. про статью подумаю, все никак не выберу тему, мне все знакомые темы кажутся избитыми и неинтересными, но может это потому что я в них и варюсь? :)
Давно мечтаю прочитать такую статью, где вся информация была бы не разбросана по OsDev комьюнити а собрана в одному туториале, чтобы можно было за пару дней завести собственную флешку с MyOS
Так что пишите!
Правда практической ценности от неё будет мало, т.к. PIC уже можно похоронить, да и MSI уже начнает сдавать позиции на фоне PME, хотя девайсы на нулевой виртуально шине ещё живут в APIC спокойно.
Хотя когда я ставил эксперименты с различными укуренным вариантами загрузки (типа «мне надо SMP, но чтобы только PIC» или «APIC но без ACPI»), то современные платы весьма часто не могли загрузиться, т.к. такие комбинации уже мертвы. По большому счёту сейчас живы только три варианта: адов легаси одноядерный PIC, многоядерный APIC+ACPI ну и полный фарш.
Мое понимание внутреннего устройство ПК закончилось где-то на 386-ом/486-ом. Тогда мне это было нтересно, а начиная с «пентиумов» у меня началось исключительно прикладное использование компьютера. В том смысле, что драйвера для шинных устройств под разные оси — да, а внутреннее устройство BIOS исключительно по необходимости. Не, я в курсе про ACPI (как минимум частично), но объективно мои познания здесь весьма обрывочны и целостной картины (даже в первом приближении) не содержат. Потому я бы с удовольствием почитал. Маловероятно, что мне это понадобится в работе, но… пожалуй именно формат статей на хабре и был бы идеальным форматом для восполнения пробелов. Если вдруг заинтересует всегда можно копнуть глубже. Да и часть важных и интересных моментов из x86/x64 порастеклась. Даже в тот же ARM/aARM64. В первую очередь, конечно, PCI с обвязкой. Потому однозначно интересно.
Я не просто так спрашиваю, обычно когда такое вижу, я не бегу писать возмущённый комментарий, а просто пишу недостающую статью. Так как от комментария пользы не много (статья не появится), а вот от статьи польза есть.
Есть статьи там https://habr.com/ru/post/338264/, есть сям https://habr.com/ru/users/coderush/posts/…
Точнее, сам код примера я тоже не писал, где-то подсмотрел, я только слепил его с заголовочными файлами UEFI и заставил компилироваться (и работать на голом железе), что оказалось на удивление легко.
int i = 5 появилось позже чем mov 5, r0 (move 5 to r0)
У ассемблера именно x86...
И речь тут не идёт про процессоры с r0...r15. Вернее про DEC'овские процессоры. Потому как на ARM тоже r0...r15, но там направление приёмник-источник тоже привычное большинству народа, как на x86, i.e. сначала приёмник, а после источник. Привычное именно большинству народа сейчас, а не малой кучке динозавров (правда я и сам не молод), которые начинали с DEC
Сравним тот же Mикрочиповский MOVLW = «Move Literal to W» и MOVWF x = «Move W to Fx», и тут же рвущие шаблон интуитивно понятные SUBLW = «Subtract W from Literal» (или наоборот?) и SUBWF x = «Subtract W from Fx» (или наоборот?), которые, низачто не догадаетесь, делают абсолютно противоположные вещи: «L-W» (нелогично) и «Fx-W» (логично).
Или 8051ый: MOV R0, #0, тут уже спокойно заменяем запятую знаком "=", и SUBB A, #01h, заменяем запятую минусом.
Или z80: LD A,n это именно A=n, а SUB A это именно А-А.
Или вообще древний IBM704-ый: LDQ A будет «Load MQ from A», а STQ A «Store MQ to A»
Также, для верхнего уровня текстов программ, „если а равно б то с“, „для каждого И от 1 до 10 с шагом 2“, „делать, пока не ноль“.
А про то, что запятую надо знаком равенства заменять — это меня заранее авторы должны предупредить, тогда это уже и нельзя прочитать „переместить а в б“, а „переместить в а из б“, а это уже сложнее языковая конструкция :)
А зачем неподготовленному читателю, а не программисту, вообще читать ассемблер? Вроде уже не 60-е годы прошлого века, когда всё только зарождалось. Сейчас во всех языках программирования (кроме редкой экзотики) присваиваемое значение является левым операндом. Вот ассемблер не должен выпендриваться.
Там ещё более необычные конструкции возможны:
addl %edx, 8(%esi,%edi,4)
И как человек интуитивно догадается, что это значит:
add [esi + edi * 4 + 8], edx
Обычно, в рамках одной идеологии, проблем возникнуть не должно (кроме разве что функций в Си после комментариев Паскаля). Тонкости про [esi + edi * 4 + 8] уже смотрим в документации.
Не возникнет же проблем понять назначение, например, таких инструкций:
MOV ACC,@VarA << #10
SUB ACC,@VarB << #6
разве что сдвиг надо сделать в первую очередь, а запятую на, соответственно, равно и минус поменять во вторую.
Некая часть информации доступна здесь: https://habr.com/ru/company/selectel/blog/516810/
На ранних стадиях загрузки, в качестве ОЗУ используется процессорный кэш. Вот еще нашел: https://www.researchgate.net/publication/295010710_Booting_an_Intel_System_Architecture
void initGraphics() {
...
for(;;) { ... }
этот цикл разве не бесконечный? Где там условие выхода?
Выхода куда?
Не откуда, а куда.
Это я к тому, что из загрузчика некуда выходить — он либо грузит ОС, либо зависает.
int 18h
чтобы вернуть управление в BIOS.В каноничном PC или PC/XT это закончилось бы Бейсиком, но в текущих реалиях — перезагрузкой или зависанием (в порядке убывания вероятностей).
Сектор – это особый раздел загрузочного диска
На этом чтение данной статьи можно закончить )))
Подскажите, пожалуйста, почему у меня не компилируются test4.c и test5.c ?
Я запускаю:
gcc -c -g -Os -march=i686 -m32 -ffreestanding -Wall -Werror test4.c -o test4.o
Вывод:
/tmp/cc3WIudi.s: Assembler messages:
/tmp/cc3WIudi.s:41: Error: 4-byte relocation cannot be applied to 2-byte field
Методом исключений я выяснил, что ошибка появляется, когда используется процедура типо getch()
Почему так получается?
Потому, что автор немножечко мухлюет при использовании инструментов. gcc думает, что он генерирует код для 32-битного режима работы cpu (-march=i686 -m32), а ассемблер интерпретирует мнемоники инструкций в предположении 16-тибитного режима (.code16 в начале файла). Иногда gcc генерирует мнемоники, для которых не существует машинного кода в 16-тибитном режиме, с такой диагностикой, как у вас, тут уж как повезёт.
Возможно, ваш gcc по-умолчанию генерирует pie-код (а у автора — не-pie), и проблема уйдёт, если вы скажете своему gcc: -fno-pie
Пишем загрузчик на Ассемблере и C. Часть 1