LINUX.ORG.RU

Вопросы по баги BIOS int13h и GRUB2

 , ,


2

3

Написал такие вопросы в рассылку GRUB2, если кто из олдов помнит баги BIOS’ов и как всё это должно работать корректно — расскажите, пожалуйста. По моему мнению получается, что баги во всех трёх компонентах: BIOS, GRUB, gdisk/установщик debian.

Hello list,

I noticed that GRUB 2.06 menu and Linux kernel and initrd load times are greatly influenced by the "last sector" data in the first partition entry (byte 0x06 in MBR partition entry, offset 0x1c4 from the beginning of the disk for the first partition) on my WYSE C10LE x86 thin client (32-bit VIA Eden Esther with Phoenix bios, from 2008).

Fresh Debian 12 installation takes about 5 seconds to show GRUB menu (GRUB loading... for 5 seconds), the kernel (4.5 MB) is loaded in 27 seconds, and initrd takes ages to load.

However, if I use gdisk software to perform MBR→GPT→MBR partition table type conversion, without touching any partitions per se, GRUB speeds up by an order of magnitude: the menu is shown instantly and the kernel is loaded under 3 seconds, initrd takes about 8 seconds.

Several hours of debugging resulted in the following observations:

1. My BIOS returns some strange C/H/S values in int13h, influenced by "last sector" data in the first partition entry of MBR. With stock Debian MBR it's 301/255/2, with MBR→GPT→MBR it's 480/255/63.

Debian's MBR contain 4/4/1 CHS start, 255/254/194 CHS end.
Converted MBR contain 1/0/1 CHS start, 255/254/255 CHS end.

Is this a BIOS bug, or some kind of quirk? I don't see this behavior on SeaBIOS in qemu. Does Debian installer fill MBR correctly? Does gdisk fill it correctly?

2. Slow loading times are due to low sector value with stock MBR. GRUB is forced to read only 2 sectors at a time.

3. GRUB obeys CHS layout even if LBA via IBM/MS INT13 Extensions is used. My BIOS supports INT13 extensions and the reads are performed using it, but GRUB still reads by 2 sectors.

grub-core/disk/i386/pc/biosdisk.c, function grub_biosdisk_open contains the following logic for HDD:

if (grub_biosdisk_get_diskinfo_standard() != 0) /* if it fails */ {
  if (data->flags & GRUB_BIOSDISK_FLAG_LBA) {
    data->sectors = 63;
    data->heads = 255;
    ...
  }
}

That means it rewrites the value for LBA only if CHS function fails. Shouldn't LBA mode ignore CHS values and read as many as possible? Is this a GRUB bug? I've changed the function to always rewrite data for LBA to 64 (not 63) sectors, to fill the whole segment in a single read, and it seem to work fine. With 63 sectors GRUB reads 63 sectors, then 1 sector, then 63 sectors, then 1 sector again, which decreases the performance, but not by much.


P.S. nativedisk doesn't have any performance problems.
Thanks.
★★★★★

Последнее исправление: ValdikSS (всего исправлений: 1)

1. My BIOS returns some strange C/H/S values in int13h, influenced by «last sector» data in the first partition entry of MBR.

Не хватает подробностей. Зачем ему вообще CHS? У современных дисков его снаружи не видно, биос эмулирует как может. Хотя брать числа из первого сектора по-моему не самая лучшая идея (тем более что они там быть совсем не обязаны, о чём вообще речь?). Но у меня подозрение что автор всё-таки что-то напутал.

3. GRUB obeys CHS layout even if LBA via IBM/MS INT13 Extensions is used. My BIOS supports INT13 extensions and the reads are performed using it, but GRUB still reads by 2 sectors.

Это наверно баг, да.

gdisk/установщик debian.

А они тут совсем ни при чём.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от firkax

В MBR, в каждом разделе (partition entry), есть поля начала и окончания раздела по C/H/S, а не только по LBA.

https://en.wikipedia.org/wiki/Master_boot_record#PTE

Debian при установке записал 4/4/1 CHS start, 255/254/194 end, а gdisk при переконвертировании записал 1/0/1 CHS start, 255/254/255 CHS end.

BIOS моего устройства парсит CHS End раздела и выдаёт разный CHS диска (вообще какой-то другой), в зависимости от того, что там указано.

P.S. Если в 6 байте (где 2 бита цилиндра и 6 битов секторов) указать цилиндры, не задав сектора, то BIOS при запуске просто зависает, не реагируя на ctrl+alt+del.

ValdikSS ★★★★★
() автор топика
Последнее исправление: ValdikSS (всего исправлений: 1)
Ответ на: комментарий от ValdikSS

А, речь про границы разделов? Ну они не обязаны быть выровнены по геометрии диска (хотя линуксовый fdisk и пишет варнинги если не выровнены, но создавать такие разделы не запрещает).

Вобщем да, брать оттуда инфу для эмуляции CHS - плохая идея, лучше бы sectors=255 heads=63 делали просто. А на пустом диске там вообще нули будут, что он возьмёт?

Хотя, с другой стороны, возможно это костыль для переноса диска с операционной системой, работающей через CHS, на другую материнку. Типа а вдруг разные биосы будут с разными дефолтами, и операционка в итоге запутается из-за неожиданно сменившейся геометрии.

P.S. Если в 6 байте (где 2 бита цилиндра и 6 битов секторов) указать цилиндры, не задав сектора, то BIOS при запуске просто зависает, не реагируя на ctrl+alt+del.

Зависает именно биос, или всё-таки запущеный им бут-сектор или то-то дальше?

firkax ★★★★★
()

Наврал со значениями MBR, т.к. взял первый попавшийся mbr parser в интернете. Вот правильные:

$ ./mbrparse_my.py mbr_bad_debian.bin 
Status:                 0x80
Start C/H/S:            4 4 1
Type:                   0x83
End C/H/S:              1023 254 2
LBA of first sector:    2048
Numer of sectors:       16773120

$ ./mbrparse_my.py mbr_good_gdisk.bin 
Status:                 0x0
Start C/H/S:            1 0 1
Type:                   0x83
End C/H/S:              1023 254 63
LBA of first sector:    2048
Numer of sectors:       16773120

Получается, BIOS берёт значение секторов из конца раздела, полагая, что геометрия диска заканчивается на конце раздела.

Правильно ли Debian поступает, записывая именно такой MBR?

ValdikSS ★★★★★
() автор топика
Ответ на: комментарий от ValdikSS

Правильно ли Debian поступает, записывая именно такой MBR?

Дебиановский вариант хотя бы консистентный. Если он почему-то считает, что цилиндр из 255 головок и 2 секторов, то 4/4/1 оказывается

4*(255*2) + 4*2 + (1-1) = 2048
Хотя 2 сектора на дорожку это конечно странно и непонятно где он их взял.

А второй, если там 255 головок и 63 сектора, начало 1/0/1 соответствует LBA=16065.

В любом случае, содержимое этих полей на работу современного софта влиять никак не должно.

firkax ★★★★★
()
Ответ на: комментарий от ValdikSS

указать цилиндры, не задав сектора,

В смысле, указать номер сектора равный нулю?

А как диск определён в BIOS setup?

Как я понимаю, у вас этот случай:

In AHCI mode, the disk geometry (Device Parameter Table) is recalculated (Translated) based on the ending CHS address of the 1st partition

because BIOS thinked that partition end is aligned to end of cylinder.

https://superuser.com/questions/860219/rewriting-partition-table-to-be-bios-d...

И, это не баг, это фича из лучших побуждений, так как в MBR не хранился CHS-размерность диска, BIOS пытался определить её из MBR на случай, если диск переткнули с другого компа или ещё что.

А количество багов в BIOS'а было такое, что лучше не пытаться запомнить...

mky ★★★★★
()
Последнее исправление: mky (всего исправлений: 1)
Ответ на: комментарий от mky

В смысле, указать номер сектора равный нулю?

Да.

А как диск определён в BIOS setup?

Это USB-флешка, как отдельный диск в настройках BIOS не определяется, int13h эмулирует диск (hd).

ValdikSS ★★★★★
() автор топика

Testdisk после установки Debian пишет:

Disk debian-new-32.img - 8589 MB / 8192 MiB - CHS 1045 255 63
Current partition structure:
     Partition                  Start        End    Size in sectors

 1 * Linux                    0  32 33  1044  52 32   16773120

Bad relative sector.
ValdikSS ★★★★★
() автор топика
Ответ на: комментарий от mky

Как я понимаю, у вас этот случай

Вот это blast from the past, у меня на Gigabyte P45-DS3 такое было, производитель исправил проблему в новом биосе после моего сообщения.

Но нет, здесь у меня нет Intel AHCI и вообще SATA-портов. Это старая платформа от VIA.

ValdikSS ★★★★★
() автор топика
Ответ на: комментарий от mky

Баги BIOS — фиг с ними. Что насчёт поведения GRUB’а? Он использует int13h extended services, производя чтение по LBA, но при этом указывает size в соответствии с размером секторов диска, не больше.

Сами int13h extended services позволяют читать до 65535 секторов за раз, но из-за багов биоса советуют читать не более 127. Меньшую цифру я не видел.

ValdikSS ★★★★★
() автор топика
Ответ на: комментарий от ValdikSS

Я видел рекомендацию, во всяком случае для AH=02h, не более 127, не выходить за границу сегмента (буфера в ОЗУ) и не пересекать границу цилиндра. Я не совсем понял что значит:

указывает size в соответствии с размером секторов диска

код grub мне смотреть лень. Но, возможно, так реализуется чтение не пересекая границу цилиндра. Возможно этот код не стали править, чтобы он работал и с базовым int13 и с расширеным.

Хотя здесь https://www.phantom.sannata.org/viewtopic.php?f=12&t=36525&start=110 написано, что на MFМ-контроллере нельзя было выходить за границу дорожки (track), а не цилиндра.

Если посмотреть исходники других загрузчиков, то единого мнения касательно «BIOS should do reads that cross track boundaries»/«Must not cross track boundaries» не наблюдается :)

А по поводу BIOS. Хоть и фиг с ним, но для USB там код был ещё чудесатее. По наличию MBR, числу разделов MBR и числу секторов в CHS-end первого раздела, BIOS определял USB-FDD, USB-ZIP, USB-HDD и отображал флешку как: целиком в диск A:, первый раздел в диск A: или диск C: (0x80). И это в идеале, а какие в том коде могли быть баги вобще мало кто тестировал. Как мне кажется, хоть эти USB-FDD,-ZIP,-HDD бысто исчезли из меню BIOS'а, код их обрабатывающий мог остаться...

Это я всё к ответу на вопрос:

Is this a BIOS bug, or some kind of quirk?

А зачем дебиан делает два сектора на дорожку нужно в его инсталяторе искать.

mky ★★★★★
()
Ответ на: комментарий от mky

но, возможно, так реализуется чтение не пересекая границу цилиндра.

Да, похоже на то.

Если посмотреть исходники других загрузчиков, то единого мнения касательно «BIOS should do reads that cross track boundaries»/«Must not cross track boundaries» не наблюдается

Именно. Syslinux игнорирует это и загружает быстро, и такое поведение кажется логичным, иначе откуда бы взялась рекомендация в 127 секторов — это больше возможных 63. GRUB никогда не использует больше 63 секторов, в т.ч. при LBA-чтении.

По наличию MBR, числу разделов MBR и числу секторов в CHS-end первого раздела, BIOS определял USB-FDD, USB-ZIP, USB-HDD

Я от своей машины не смог добиться такой эмуляции с обычной флешкой, хотел эмулировать floppy. Чуть поискал в интернете — ничего не нашел. Помните какие-либо подробности?

А по ссылке обсуждают совсем древнегреческие системы, GRUB 32-битный, 386+

ValdikSS ★★★★★
() автор топика
Последнее исправление: ValdikSS (всего исправлений: 3)
Ответ на: комментарий от bugs-bunny

Это в каком году широко не завезли? В 2023 и даже ранее уже почти нереально найти железяку, которая не может в uefi. Или вы свои на мусорке собираете? Никто не будет даже шевелиться ради 1.5 некрофила с помойки.

ZemidKadum
()
Ответ на: комментарий от ZemidKadum

1.5 некрофила с помойки

Это вы так ТС-а назвали? Пост то прочитали о какой железке речь?

on my WYSE C10LE x86 thin client (32-bit VIA Eden Esther with Phoenix bios, from 2008)

В 2019-м кажись уже отказались окончательно и от CFM в UEFI-биосах. Удивляет то, что LBA32 победила CHS в конце 90-х, а в 2008-м проблемы. Точнее, почему Grub2 еще ждет в MBR-таблице CHS? В Int13h вроде бы отсутствие функций для LBA означало, что это гавно мамонта с CHS (просто припоминаю код MBR-загрузчика DiskCryptor).

Это в начале 90-х биосы не могли сами определять параметры диска и пользователю предлагалось выбрать из 32 конфигураций CHS. Потом поперли объемы 80-120-МБ (МБ, не ГБ!) и понадобился LBA и чтение параметров диска из него самого. И 32-битные поля CHS начала/конца диска в MBR превратились в LBA начала и размер в секторах.

bugs-bunny
()
Последнее исправление: bugs-bunny (всего исправлений: 1)

I noticed that GRUB 2.06 menu and Linux kernel and initrd load times …

Т.е. это регрессия, а раньше работало? На Дебиане, который по возрасту ближе к 2008-му или всё ещё и на 11-ом?

… are greatly influenced by the «last sector» data in the first partition entry …

Напомнило мне одну особенность «биоса» (загрузчика из ROM) AM335x на BeagleBoard. Обнаружилась после обновления dosfstools.

«Recently I sent patch to util-linux’s fdisk tool to try reconstruct geometry (number-of-heads and sectors-per-track) from MBR table and fills correct C/H/S values in MBR table when creating/updating partitions. …» (09.04.2022)

Может, это как-то связано с наблюдаемым поведением.

gag ★★★★★
()