Эта статья объясняет как создать минимальное ядро операционной системы, используя стандарт мультизагрузки. По факту, оно будет просто загружаться и печатать OK на экране. В последующих статьях мы расширим его, используя язык программирования Rust.


Я попытался объяснить всё в деталях и оставить код максимально простым, насколько это возможно. Если у вас возникли вопросы, предложения или какие-либо проблемы, пожалуйста, оставьте комментарий или создайте таску на GitHub. Исходный код доступен в репозитории.



Обзор


Когда вы включаете компьютер, он загружает BIOS из специальной флэш памяти. BIOS запускает тесты самопроверки и инициализацию аппаратного обеспечения, затем он ищет загрузочные устройства. Если было найдено хотя бы одно, он передаёт контроль загрузчику, который является небольшой частью запускаемого кода, сохранённого в начале устройства хранения. Загрузчик определяет местоположение образа ядра, находящегося на устройстве, и загружает его в память. Ему также необходимо переключить процессор в так называемый защищённый режим, потому что x86 процессоры по умолчанию стартуют в очень ограниченном реальном режиме (чтобы быть совместимыми с программами из 1978).


Мы не будем писать загрузчик, потому что это сам по себе сложный проект (если вы действительно хотите это сделать, почитайте об этом здесь). Вместо этого мы будем использовать один из многих испытанных загрузчиков для загрузки нашего ядра с CD-ROM. Но какой?


Мультизагрузка


К счастью, есть стандарт загрузчика: спецификация мультизагрузки. Наше ядро должно лишь указать, что поддерживает спецификацию и любой совместимый загрузчик сможет загрузить его. Мы будем использовать спецификацию Multiboot 2 (PDF)
вместе с известным загрузчиком GRUB 2.


Чтобы сказать загрузчику о поддержке Multiboot 2, наше ядро должно начинаться с заголовка мультизагрузки, который имеет следующий формат:


Field Type Value
магическое число u32 0xE85250D6
архитектура u32 0 для i386, 4 для MIPS
длина заголовка u32 общий размер заголовка включая тэги
контрольная сумма u32 -(магическое число + архитектура + длина заголовка)
тэги variable
завершающий тэг (u16, u16, u32) (0, 0, 8)

В переводе на x86 ассемблер это будет выглядеть так (Intel синтаксис):


section .multiboot_header
header_start:
    dd 0xe85250d6                ; магическое число (multiboot 2)
    dd 0                         ; архитектура 0 (защищённый режим i386)
    dd header_end - header_start ; длина заголовка
    ; контрольная сумма
    dd 0x100000000 - (0xe85250d6 + 0 + (header_end - header_start))

    ; вставьте опциональные `multiboot` тэги здесь

    ; требуюется завершающий тэг
    dw 0    ; тип
    dw 0    ; флаги
    dd 8    ; размер
header_end:

Если вы не знаете x86 ассемблер, то вот небольшая вводная:


  • заголовок будет записан в секцию, названную .multiboot_header (нам понадобится это позже),
  • header_start и header_end — это метки, которые указывают на месторасположение в памяти, мы используем их, чтобы вычислить длину заголовка,
  • dd означает define double (32bit) и dw означает define word (16bit). Они просто выводят указанные 32bit/16bit константы,
  • константа 0x100000000 в вычислении контрольной суммы — это небольшой хак, чтобы избежать предупреждений компилятора.

Мы уже можем собрать данный файл (который я назвал multiboot_header.asm) используя nasm.


Установка nasm на `archlinux`
[loomaclin@loomaclin ~]$ yaourt nasm
1 extra/nasm 2.13.02-1
    An 80x86 assembler designed for portability and modularity
2 extra/yasm 1.3.0-2
    A rewrite of NASM to allow for multiple syntax supported (NASM, TASM, GAS, etc.)
3 aur/intel2gas 1.3.3-7 (3) (0.20)
    Converts assembly language files between NASM and GNU assembler syntax
4 aur/nasm-git 20150726-1 (1) (0.00)
    80x86 assembler designed for portability and modularity
5 aur/sasm 3.9.0-1 (18) (0.61)
    Simple crossplatform IDE for NASM, MASM, GAS, FASM assembly languages
6 aur/yasm-git 1.3.0.r30.g6caf1518-1 (0) (0.00)
    A complete rewrite of the NASM assembler under the BSD License
==> Enter n° of packages to be installed (e.g., 1 2 3 or 1-3)
==> ---------------------------------------------------------
==> 1

[sudo] password for loomaclin: 
resolving dependencies...
looking for conflicting packages...

Packages (1) nasm-2.13.02-1

Total Download Size:   0.34 MiB
Total Installed Size:  2.65 MiB

:: Proceed with installation? [Y/n] 
:: Retrieving packages...
 nasm-2.13.02-1-x86_64                                                                                346.0 KiB  1123K/s 00:00 [#############################################################################] 100%
(1/1) checking keys in keyring                                                                                                 [#############################################################################] 100%
(1/1) checking package integrity                                                                                               [#############################################################################] 100%
(1/1) loading package files                                                                                                    [#############################################################################] 100%
(1/1) checking for file conflicts                                                                                              [#############################################################################] 100%
(1/1) checking available disk space                                                                                            [#############################################################################] 100%
:: Processing package changes...
(1/1) installing nasm                                                                                                          [#############################################################################] 100%
:: Running post-transaction hooks...
(1/1) Arming ConditionNeedsUpdate...
[loomaclin@loomaclin ~]$ nasm --version
NASM version 2.13.02 compiled on Dec 10 2017
[loomaclin@loomaclin ~]$ 

Следующая команда произведёт плоский двоичный файл, результирующий файл будет содержать 24 байта (в little endian, если вы работаете на x86 машине):


[loomaclin@loomaclin ~]$ cd IdeaProjects/
[loomaclin@loomaclin IdeaProjects]$ mkdir a_minimal_multiboot_kernel
[loomaclin@loomaclin IdeaProjects]$ cd a_minimal_multiboot_kernel/
[loomaclin@loomaclin a_minimal_multiboot_kernel]$ nano multiboot_header.asm
[loomaclin@loomaclin a_minimal_multiboot_kernel]$ nasm multiboot_header.asm 
[loomaclin@loomaclin a_minimal_multiboot_kernel]$ hexdump -x multiboot_header
0000000    50d6    e852    0000    0000    0018    0000    af12    17ad
0000010    0000    0000    0008    0000                                
0000018
[loomaclin@loomaclin a_minimal_multiboot_kernel]$ 

Загрузочный код


Чтобы загрузить наше ядро, мы должны добавить код, который сможет вызвать загрузчик. Давайте создадим файл boot.asm:


global start

section .text
bits 32
start:
    ; печатает `OK` на экране
    mov dword [0xb8000], 0x2f4b2f4f
    hlt

Здесь есть несколько новых команд:


  • global экспортирует метки (делает их публичными). Метка start будет входной точкой в наше ядро, она должна быть публичной,
  • .text секция — это секция по умолчанию для исполняемого кода,
  • bits 32 говорит о том, что следующие строки — это 32-битные инструкции. Это необходимо потому что процессор ещё находится в защищённом режиме, когда GRUB запускает наше ядро. Когда переключимся в Long mode в следующей статье, сможем запускать bits 64 (64-битные инструкции),
  • mov dword инструкция помещает 32-битную константу 0x2f4b2f4f в адрес памяти b8000 (это выводит OK на экран, объяснено будет в следующих статьях),
  • hlt — это инструкция, которая говорит процессору остановить выполнение команд.

После сборки, просмотра и дизассемблирования мы можем увидеть опкоды процессора в действии:


[loomaclin@loomaclin a_minimal_multiboot_kernel]$ nano boot.asm
[loomaclin@loomaclin a_minimal_multiboot_kernel]$ nasm boot.asm 
[loomaclin@loomaclin a_minimal_multiboot_kernel]$ hexdump -x boot
0000000    05c7    8000    000b    2f4f    2f4b    00f4                
000000b
[loomaclin@loomaclin a_minimal_multiboot_kernel]$ ndisasm -b 32 boot
00000000  C70500800B004F2F  mov dword [dword 0xb8000],0x2f4b2f4f
         -4B2F
0000000A  F4                hlt
[loomaclin@loomaclin a_minimal_multiboot_kernel]$ 

Создание исполняемого файла


Чтобы загрузить наш исполняемый файл позже через GRUB, он должен быть исполняемым ELF файлом. Поэтому необходимо с помощью nasm создать ELF объектные файлы вместо простых бинарников. Для этого мы просто добавляем в аргументы -f elf64.


Для создания самого ELF исполняемого кода мы должны связать объектные файлы. Будем использовать кастомный скрипт для связывания, называемый linker.ld:


ENTRY(start)

SECTIONS {
    . = 1M;

    .boot :
    {
        /* в начале оставим заголовк мультизагрузки */
        *(.multiboot_header)
    }

    .text :
    {
        *(.text)
    }
}

Переведём что написано на человеческий язык:


  • start — это точка входа, загрузчик перейдёт к этой метке после загрузки ядра,
  • . = 1M; уставливает адрес загрузки первой секции с 1-го мегабайта, это стандарт расположения для загрузки ядра,
  • исполняемая часть имеет две секции: в начале boot и .text после,
  • конечная секция .text будет содержать в себе все входящие секции .text,
  • секции, именованные как .multiboot_header, будут добавлены в первую выходную секцию (.boot), чтобы они располагались в начале исполняемого кода. Это необходимо, потому что GRUB ожидает найти заголовок мультизагрузки в начале файла.

Давайте создадим ELF объектные файлы и слинкуем их, используя вышеуказанный линкер скрипт:


[loomaclin@loomaclin a_minimal_multiboot_kernel]$ nasm -f elf64 multiboot_header.asm
[loomaclin@loomaclin a_minimal_multiboot_kernel]$ nasm -f elf64 boot.asm 
[loomaclin@loomaclin a_minimal_multiboot_kernel]$ ld -n -o kernel.bin -T linker.ld multiboot_header.o boot.o
[loomaclin@loomaclin a_minimal_multiboot_kernel]$ 

Очень важно передать -n (или --nmagic) флаг линкеру, который отключает автоматическое выравнивание секций в исполняемом файле. В противном случае линкер может выравнить страницу секции .boot в исполняемом файле. Если это произойдёт, GRUB не сможет найти заголовок мультизагрузки, потому что он будет находиться уже не в начале.


Воспользуемся командой objdump для того, чтобы вывести секции сгенерированного исполняемого файла и проверить, что .boot секция имеет наименьшее смещение в файле:


[loomaclin@loomaclin a_minimal_multiboot_kernel]$ objdump -h kernel.bin 

kernel.bin:     file format elf64-x86-64

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .boot         00000018  0000000000100000  0000000000100000  00000080  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .text         0000000b  0000000000100020  0000000000100020  000000a0  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
[loomaclin@loomaclin a_minimal_multiboot_kernel]$ 

Примечание: команды ld и objdump платформо-зависимы. Если вы работаете не на x86_64 архитектуре, вы нуждаетесь в кросс компиляции binutils. После этого воспользуйтесь x86_64?elf?ld и x86_64?elf?objdump вместо ld и objdump соответственно.

Создание ISO-образа


Все персональные компьютеры, работающие на базе BIOS, знают, как загружаться с CD-ROM, так что нам необходимо создать загружаемый образ CD-ROM, содержащий наше ядро и файлы загрузчика GRUB в единственном файле, называемом ISO. Создайте следующую структуру директорий и скопируйте kernel.bin в директорию boot:


isofiles
L-- boot
    +-- grub
    ¦   L-- grub.cfg
    L-- kernel.bin

grub.cfg указывает имя файла нашего ядра и совместимость с multiboot 2. Выглядит это так:


set timeout=0
set default=0

menuentry "my os" {
    multiboot2 /boot/kernel.bin
    boot
}

Исполняем команды:


[loomaclin@loomaclin a_minimal_multiboot_kernel]$ mkdir isofiles
[loomaclin@loomaclin a_minimal_multiboot_kernel]$ mkdir isofiles/boot
[loomaclin@loomaclin a_minimal_multiboot_kernel]$ mkdir isofiles/boot/grub
[loomaclin@loomaclin a_minimal_multiboot_kernel]$ cp kernel.bin isofiles/boot/
[loomaclin@loomaclin a_minimal_multiboot_kernel]$ nano grub.cfg
[loomaclin@loomaclin a_minimal_multiboot_kernel]$ cp grub.cfg isofiles/boot/grub/

Теперь мы можем создать загружаемый образ, используя следующую команду:


[loomaclin@loomaclin a_minimal_multiboot_kernel]$ grub-mkrescue -o os.iso isofiles
xorriso 1.4.8 : RockRidge filesystem manipulator, libburnia project.

Drive current: -outdev 'stdio:os.iso'
Media current: stdio file, overwriteable
Media status : is blank
Media summary: 0 sessions, 0 data blocks, 0 data, 7675m free
Added to ISO image: directory '/'='/tmp/grub.jN4u6m'
xorriso : UPDATE : 898 files added in 1 seconds
Added to ISO image: directory '/'='/home/loomaclin/IdeaProjects/a_minimal_multiboot_kernel/isofiles'
xorriso : UPDATE : 902 files added in 1 seconds
xorriso : NOTE : Copying to System Area: 512 bytes from file '/usr/lib/grub/i386-pc/boot_hybrid.img'
ISO image produced: 9920 sectors
Written to medium : 9920 sectors at LBA 0
Writing to 'stdio:os.iso' completed successfully.

Примечание: вызов grub-mkrescue может вызвать проблемы на некоторых платформах. Если она у вас не сработала, попробуйте следующие шаги:
  • запустить команду с --verbose,
  • удостовериться, что библиотека xorriso установлена (xorriso или libisoburn пакет).


На `Archlinux пришлось поставить `libisoburn`

[loomaclin@loomaclin a_minimal_multiboot_kernel]$ yaourt xorriso
1 extra/libisoburn 1.4.8-2
frontend for libraries libburn and libisofs
==> Enter n° of packages to be installed (e.g., 1 2 3 or 1-3)
==> — ==> 1


[sudo] password for loomaclin:
resolving dependencies…
looking for conflicting packages...


Packages (3) libburn-1.4.8-1 libisofs-1.4.8-1 libisoburn-1.4.8-2


Total Download Size: 1.15 MiB
Total Installed Size: 3.09 MiB


:: Proceed with installation? [Y/n]
:: Retrieving packages…
libburn-1.4.8-1-x86_64 259.7 KiB 911K/s 00:00 [#############################################################################] 100%
libisofs-1.4.8-1-x86_64 237.8 KiB 2.04M/s 00:00 [#############################################################################] 100%
libisoburn-1.4.8-2-x86_64 683.8 KiB 2.34M/s 00:00 [#############################################################################] 100%
(3/3) checking keys in keyring [#############################################################################] 100%
(3/3) checking package integrity [#############################################################################] 100%
(3/3) loading package files [#############################################################################] 100%
(3/3) checking for file conflicts [#############################################################################] 100%
(3/3) checking available disk space [#############################################################################] 100%
:: Processing package changes…
(1/3) installing libburn [#############################################################################] 100%
(2/3) installing libisofs [#############################################################################] 100%
(3/3) installing libisoburn


  • если вы используете EFI-систему, grub-mkrescue попробует создать EFI образ по умолчанию. Вы можете задать аргумент -d /usr/lib/grub/i386-pc, чтобы избавиться от этого поведения, или установить пакет mtools и получить работающий EFI образ
  • на некоторых системах команда названа grub2-mkrescue.

Загрузка


Пришло время загрузить нашу ОС. Для этого воспользуемся QEMU:


[loomaclin@loomaclin a_minimal_multiboot_kernel]$ qemu-system-x86_64 -cdrom os.iso 

(qemu-system-x86_64:10878): Gtk-WARNING **: Allocating size to GtkScrollbar 0x7f2337e5a280 without calling gtk_widget_get_preferred_width/height(). How does the code know the size to allocate?

(qemu-system-x86_64:10878): Gtk-WARNING **: Allocating size to GtkScrollbar 0x7f2337e5a480 without calling gtk_widget_get_preferred_width/height(). How does the code know the size to allocate?

(qemu-system-x86_64:10878): Gtk-WARNING **: Allocating size to GtkScrollbar 0x7f2337e5a680 without calling gtk_widget_get_preferred_width/height(). How does the code know the size to allocate?

Появится окно эмулятора:
Окно эмулятора


Обратите внимание на зелёный текст OK в верхнем левом углу. Если у вас это не работает, посмотрите секцию комментариев.


Резюмируем, что произошло:


  1. BIOS загружает загрузчик (GRUB) из виртуального CD-ROM (ISO).
  2. Загрузчик прочёл исполняемый код ядра и нашёл заголовок мультизагрузки.
  3. Скопировал секцию .boot и .text в память (по адресу 0x100000 и 0x100020).
  4. Переместился к точке входа (0x100020, это можно узнать вызвав objdump -f).
  5. Ядро вывело на экран текст OK зелёным цветом и остановило процессор.

Вы также можете протестировать это на настоящем железе. Необходимо записать получившийся образ на диск или USB накопитель и загрузиться с него.


Автоматизация сборки


Сейчас необходимо вызывать 4 команды в правильном порядке каждый раз, когда мы меняем файл. Это плохо. Давайте автоматизируем этот процесс, с помощью Makefile. Но для начала мы должны создать подходящую структуру директорий чтобы отделить архитектурно-зависимые файлы:


…
+-- Makefile
L-- src
    L-- arch
        L-- x86_64
            +-- multiboot_header.asm
            +-- boot.asm
            +-- linker.ld
            L-- grub.cfg

Создаём:


[loomaclin@loomaclin a_minimal_multiboot_kernel]$ mkdir -p src/arch/x86_64
[loomaclin@loomaclin a_minimal_multiboot_kernel]$ cp multiboot_header.asm src/arch/x86_64/
[loomaclin@loomaclin a_minimal_multiboot_kernel]$ cp boot.asm src/arch/x86_64/
[loomaclin@loomaclin a_minimal_multiboot_kernel]$ cp linker.ld src/arch/x86_64/
[loomaclin@loomaclin a_minimal_multiboot_kernel]$ cp grub.cfg src/arch/x86_64/
[loomaclin@loomaclin a_minimal_multiboot_kernel]$ nano Makefile

Makefile должен иметь следующий вид:


arch ?= x86_64
kernel := build/kernel-$(arch).bin
iso := build/os-$(arch).iso

linker_script := src/arch/$(arch)/linker.ld
grub_cfg := src/arch/$(arch)/grub.cfg
assembly_source_files := $(wildcard src/arch/$(arch)/*.asm)
assembly_object_files := $(patsubst src/arch/$(arch)/%.asm,     build/arch/$(arch)/%.o, $(assembly_source_files))

.PHONY: all clean run iso

all: $(kernel)

clean:
    @rm -r build

run: $(iso)
    @qemu-system-x86_64 -cdrom $(iso)

iso: $(iso)

$(iso): $(kernel) $(grub_cfg)
    @mkdir -p build/isofiles/boot/grub
    @cp $(kernel) build/isofiles/boot/kernel.bin
    @cp $(grub_cfg) build/isofiles/boot/grub
    @grub-mkrescue -o $(iso) build/isofiles 2> /dev/null
    @rm -r build/isofiles

$(kernel): $(assembly_object_files) $(linker_script)
    @ld -n -T $(linker_script) -o $(kernel) $(assembly_object_files)

# compile assembly files
build/arch/$(arch)/%.o: src/arch/$(arch)/%.asm
    @mkdir -p $(shell dirname $@)
    @nasm -felf64 $< -o $@

Некоторые комментарии (если вы не работали до этого с make, посмотрите makefile туториал):


  • $(wildcard src/arch/$(arch)/*.asm) выбирает все файлы ассемблера в директории src/arch/$(arch), так что вам не нужно обновлять Makefile при добавлении файлов,
  • операция patsubst для assembly_object_files просто переводит src/arch/$(arch)/XYZ.asm в build/arch/$(arch)/XYZ.o,
  • таргеты сборки$< и $@ это автоматически выводимые переменные,
  • если вы используете кросс-комплированные binutils просто замените ld на x86_64-elf-ld.

Теперь мы можем вызвать make и все обновлённые файлы ассемблера будут скомпилированы и скомпонованы. Команда make iso также создаёт ISO образ, а make run в дополнение запускает QEMU.


Что дальше?


В следующей статье мы создадим таблицу страниц и проведем некоторую конфигурацию процессора для переключения в 64-битный long-mode режим.


Примечания


  1. Формула из таблицы -(magic + architecture + header_length) создает отрицательное значение, которое не влезает в 32 бита. С помощью вычитания из 0x100000000 мы оставляем значение положительным без изменения вычтенного значения. В результате без дополнительного знакового бита результат помещается в 32 бита и компилятор счастлив :)
  2. Мы не хотим загружать ядро по офсету 0x0, так как много специфичных областей памяти может быть расположено до метки в 1 мегабайт (для примера, так называемый VGA буфер по адресу 0xb8000, который мы используем чтобы вывести OK на экран).

Комментарии (13)


  1. CodeRush
    22.03.2018 07:40
    +12

    Ребят, все прекрасно, только вот использовать древний интерфейс BIOS для загрузки в 2018 году — это настолько моветон, что страшно подумать.
    Это все нафиг не нужно, простите, и давно уже. Система не стартует в 16-битном режиме, система не имеет фреймбуфера по адресу 0xB8000, все это вам криво эмулируется, а уже в 2020 году перестанет это делать.
    Более того, ассемблер тут не нужен вообще и все можно написать прямо на Расте, а загрузчик вам не нужен никакой, достаточно свое ядро собрать в PE-файл.

    Я понимаю, что статья обучающая и не про это, но целая гора забористого текста вместо

    EFI_STATUS EFIAPI EntryPoint(EFI_HANDLE Handle, EFI_SYSTEM_TABLE *SystemTable)
    {...поехали...} 
    с примечаниями вроде
    ; Тут хитрая магия, некогда объяснять
    — это точно не то, чему надо учить новичков.

    BIOS умер, похороните его! Насилие над трупом — не наш метод!


    1. Malligan0
      22.03.2018 09:43
      +2

      А где можно почитать о модныхсовременных способах как построения, так и загрузки ядра ОС?


      1. LooMaclin Автор
        22.03.2018 09:45

        OSDev wiki уже видели? Если нет, то там есть разделы Environment и Booting and Setup.


      1. CodeRush
        22.03.2018 10:20
        +2

        Поддерживаю OSDev Wiki, но ссылка должна быть сюда.
        Вообще, обучающих материалов по написанию EFI-приложений в сети довольно много, а загрузчиком ОС такие приложения становятся сразу же, как только в их коде появляется вызов ExitBS (т.е. «не нужен ты мне больше, EFI, теперь я здесь ОС»).


        1. CodeRush
          22.03.2018 18:06
          +1

          Вот этот еще цикл статей порекомендую, он на русском и для новичков.


    1. LooMaclin Автор
      22.03.2018 10:03
      +2

      Напомню, что это перевод статьи 2015 года (мне серия статей показалась интересной). Ничего плохого в BIOS в 2018 году не вижу. Предполагаю, что после 2020 года (кстати почему он?) информация останется полезной. Касательно смены ассемблера на раст — я только всеми руками за, надо попробовать.


      P.S Возможно, это не насилие, а любовь.


      1. CodeRush
        22.03.2018 10:38
        +2

        Даже для 2015 года это все равно уже устарело до точки невозврата, а после 2020 этот набор костылей времен царя Гороха просто перестанет работать.

        CSM (тот самый БИОС, который не насилие, а любовь) — дырявый, глючный, кривой как бараний рог шмат древнего кода на ассемблере, обмазаный сверху трамплинами в 16 битный реальный режим и обратно, сделаный ради одной цели — чтобы некрофилы любители старины могли дальше грузить свои загрузочные вирусы мультистадийные легаси-загрузчики из MBR.

        Если серьезно и без сарказма, то CSM — это слой обеспечения совместимости с DOS, который до сих пор поддерживается и включен по умолчанию на машинах с Intel KabyLake и новее, у которых для ОС старше Windows 10 уже даже драйверов нет — настолько сильна инерция производителей железа. Если у вас нет древних видеокарт, каких-нибудь еще устройств с OptionROM (вроде рейд-контролеров внешних), то вы от выключения CSM и использования UEFI-загрузки только выиграете.

        Долой легасню, даешь прогресс!


        1. BiosUefi
          22.03.2018 18:39

          >>Долой легасню, даешь прогресс!

          А производители ОСРВ будут довольны?
          Ну там еще у производителей бызовых станций для мобильной связи поинтересоваться, о согласии с «Долой легасню, даешь прогресс!».


          1. CodeRush
            22.03.2018 20:22

            Не могу спорить с нуждами эмбеддеда и индустрии — там CSM будут поддерживать до последнего патрона, я уже писал об этом. Но тут то совсем другой случай, совместимость с далеким и славным прошлым не нужна от слова совсем, а ее продолжают на ассемблере писать…


    1. atrosinenko
      22.03.2018 15:54

      Это все нафиг не нужно, простите, и давно уже.

      Начинать в 2018 году учебный проект (который в ближайшие три года, может, и на реальном железе ни разу не запустят) с поддержки BIOS, может, и не имеет смысла (кстати, спасибо за ссылку, где указано, как включить поддержку UEFI в QEMU), но вот выкидывать эту поддержку на свалку из реальных продуктов, ИМХО, преждевременно. У меня, например, совсем недавно появился дома первый компьютер с поддержкой UEFI. Нет, я сидел не за еле живой системой, не тянущей ничего современного (про игры, правда, утверждать не буду) — это был вполне живой ноутбук с мобильным Core i3 первого поколения (2 ядра / 4 потока) и 8 Гб оперативки. Я бы, наверное, и ещё пару лет мог бы за ним поработать, машинка вполне мощная. Однако в нём, вроде, ничего кроме классического BIOS не было.


      1. CodeRush
        22.03.2018 18:05

        Выкидывать эту поддержку на свалку из реальных продуктов, ИМХО, преждевременно.

        Поддержка настоящей EFI-загрузки без использования CSM появилась у массовых ОС для ПК в конце 2012 года, и ровно с этого момента для CSM пошел обратный отсчет.
        Проблема с CSM в том, что на современном железе его поддержка — это непрерывная боль и страдания, а нужна она исключительно тем, кто никак не может сконвертировать свои диски в GPT и перестать запускать на своих системах Windows 7, Windows CE 6 или MSDOS 6.22. А так как современное (выпуска прошлого и нынешнего года т.е.) ни одну из этих систем уже официально не поддерживает и никогда не будет — CSM нужно было убить еще в прошлом году, а не тащить этот чемодан без ручки в светлое будущее. Я понимаю, кому он нужен, и для чего, но тут ребята совершенно новую ОС пишут, и им не нужно ничего из того, что предоставляет интерфейс BIOS, особенно потому, что EFI предоставляет и больше намного, и значительно более простыми средствами, не требующими ни ассемблера, ни магических констант, ни сборки ISO-образов, ни знакомства со спецификацией multiboot, такой же мертвой, как и сам CSM.


        1. atrosinenko
          22.03.2018 18:33

          Вероятно, я плохо сформулировал свой комментарий. Когда ребята допишут свою ОС, о CSM, вполне возможно, уже и забудут все. А говорил я вообще про сохранение (пока) поддержки CSM в существующих ОС (на случай ещё достаточно мощного железа, но с древней прошивкой), я не имел в виду, что мне нужна поддержка CSM со стороны прошивки. Ну то есть, кому-то она, может, и нужна, но мне не особо. :) Кстати, читал ваш цикл статей про безопасность UEFI и всё думал: "Как же страшно было жить в 2015" — надеюсь, сейчас всё уже не так плохо? :)


  1. atrosinenko
    22.03.2018 15:23
    +1

    "Истинный программист способен написать операционную систему на Rust даже на ассемблере"? Нет, я понимаю, что это первая, подготовительная, часть из большого цикла, но заголовок забавно сочетается с остальным текстом...