1 Отредактировано Voldemar0 (13-03-2019 11:43)

Тема: ОС Школьница, баги & глюки

Привет!

Случайно столкнулся с багом Школьницы, малозаметным на реале, но в эмуляторе вылез.
Задевает, как минимум, РАПИРу и ДОК. Может и копировщик тоже, семёрочные версии, до-ИКПшные.

Драйвер дисковода в этих системах ещё не имел отложенных операций и поддержки 840ки, возможно, когда его переписывали всё уже было исправлено. Но в оригинальных семёрочных версиях ошибка присутствует: драйвер зависает, если контроллер дисковода стоит в 6м слоте.

How Do They Do It?
Чтобы зря не гонять головку дисковода, в драйвере есть буфер для хранения текущих положений головок.
Буфер описан примерно так: u_int8_t drv_A[5], drv_B[5].
Т.е. два массива для первого и второго приводов по всем слотам.
Проблема в том, что слоты нумеруются от 1 до 6.
Нулевые элементы массива использованы под что-то вроде счётчиков попыток чтений (к ним обращение по абсолютным адресам), а элементы с 1 по 6 - для хранения фаз головок. Ну и дальше понятно - при работе с 6м слотом получаем index out of range.

Поскольку работаем с приводом A, то 6й слот попадает на B[0] - а там счётчик попыток поиска сектора.
Драйвер задаёт счетчик попыток, этим портит фазу. Затем пытается позиционировать голову, но так как фаза разрушена, голова едет не на нужный трек. Дальше делается попытка найти нужный сектор, его нет, пытается перетащить голову, но текущая фаза указана неверно, голова съезжает в сторону, а счётчик попыток обновляется, причем на значительную величину и никак не может достичь нуля (счётчик фаз считает в диапазоне [0..69], счётчик попыток - [4..-1]). Нет  нуля - нет ретрейса. Нет ретрейса - нет правильного позиционирования. Драйвер завис.

Интересно, что всё успешно работает если дисковод воткнуть в виртуальный 1-й слот, который даже не всегда распаивается на семёрке.