Вторая недели бесполезной возни с железкой.
Сабж. одноплатка EM-436B v2.1
CPU: XScale-IXP42x Family rev 2 (v5b), 266МГц (на корпусе нацарапано «PRIXP422ABB»)
RAM: 4x256Мбит = 128мегабайт (самсунги K4S561632H-UC75)
PCI-контроллер Promise PDC20275, на который навешан CompactFlash и всякий прочий эзернет.
Ничего вроде бы особенного, вот только объявились проблемы со старосборным ядром 2.6.20, без проблем работающим на ixp425 (ланнеровская железка FW-3600 A/B). Аппаратная разница по идее не настолько велика, чтоб всё дошло до несовместимости, но стойкое (100%) появление «Unable to handle kernel NULL pointer dereference at virtual address такой-то» при попытке ядра распаковать initrd приводило в уныние.
Дабы не гадать на тему бажности старого ядра и собственной косорукости при его давней сборке, я быстренько взял имеющееся под рукой 2.6.35.7, собрал его со страшной силой и максимально дефолтным конфигом. Ну и затеял грузить его с простейшим initrd, размером менее мегабайта, тоже быстро слепленным в тестовых целях.
Наконец, удалось получить шелл. Но радость была преждевременна. При самый осторожных движениях и безобидных командах валились ядерные ошибки при доступе памяти. Вызов ps мог повалить ядро. Или cat /proc/что-то_там. Ну а dd if=/dev/zero of=/tmp/file bs=1M count=16 убивало девайс стопроцентно (/tmp - это tmpfs).
Причём всегда в бектрейсе фигурировали функции kmem_cache_(alloc|free) и прочие из той же оперы. Принципиально ошибки в логе были теми же самыми, что и при запуске 2.6.20, собранного торвальдс знает когда.
Причём на ixp425(FW-3600) и старая (что давно отлажено) и новые (тестовые) сборки запускаются и работают без каких-либо проблем. Правда, на ixp425 имеем 64M рамы, а здесь на ixp422 аж 128. Причём redboot определяет 256, так что ядру приходится указывать реальный размер. Впрочем, с ограничениями по размеру я как только не экспериментировал - принципиальной разницы не наблюдается. Только DMA на CF то работает, то нет.
Вариант с запуском сборки наисвежайшего 2.6.37.2 также ничего не изменил. Разве только что вместо NULL pointer валит что-нибудь вроде
# dd if=/dev/zero of=/tmp/0 bs=1M count=16
Kernel panic - not syncing: Attempted to kill init!
[<c0032e94>] (unwind_backtrace+0x0/0xf0) from [<c02a27b4>] (panic+0x58/0x17c)
[<c02a27b4>] (panic+0x58/0x17c) from [<c0041f0c>] (do_exit+0x6c/0x60c)
[<c0041f0c>] (do_exit+0x6c/0x60c) from [<c0042538>] (do_group_exit+0x8c/0xc0)
[<c0042538>] (do_group_exit+0x8c/0xc0) from [<c004c2fc>] (get_signal_to_deliver+0x2d8/0x310)
[<c004c2fc>] (get_signal_to_deliver+0x2d8/0x310) from [<c002fd80>] (do_signal+0x50/0x5a8)
[<c002fd80>] (do_signal+0x50/0x5a8) from [<c00302f0>] (do_notify_resume+0x18/0x4c)
[<c00302f0>] (do_notify_resume+0x18/0x4c) from [<c002d694>] (work_pending+0x24/0x28)
и благополучно переходит в состояние агонии: не даёт запустить апплеты бизибокса (permission denied), а прямой вызов вроде /bin/busybox ls выдаёт какоё-нибудь sigsegv.
В общем налицо неверная работа ядра с памятью. Причём на другой похожей одноплатке (v2.0, а не 2.1) проблемы полностью аналогичны.
Изгалялся я всячески, крутил и вертел параметры, понавключал дебагги везде и всюду. Причём ядро то успевало ругнуться дебаггом аллокатора на «перезаписывание паддинга» или «нарушение Redzone», то благополучно валилось в exception со своими проклятыми пойнтерами.
Пример бэктрейса приведу.
Уже немного отчаялся и помышляю писать куда-нибудь в Спортлото кернелтрап, но сначала спрошу здесь: есть у кого мысли какие-нибудь?
Грешить на неверную инициализцию железа редбутом? Так ядро всё равно всё с нуля делает.
Что я криво что-то собрал? Перепробованы 3 версии ядра с разными конфигами. Не работает на ixp422, но работает на 425.
Сколько было соображений - все перепробовал - толку нет.
I need help!