Добрый день!
Хочу поделиться историей о том, как я чинилпримус свой домашний NAS D-Link DNS-325.
Сам NAS у меня обычно в режиме минимального потребления электроэнергии с выключенными жёсткими дисками WD Green (установлен fun_plug на внешнюю USB флешку, об этой «прокачке» есть статья на Хабре). Однажды, после отпуска, я включил питание на NAS, чтобы просмотреть/загрузить фотографии. Он не включился. Cветодиод питания весело замигал, загорелись индикаторы сотояния HDD, но мигание продолжалось и продолжалось без признаков жизни. При нормальных условиях мигание означает процесс загрузки, который должен завершиться полной инициализацией и установлением стабильного свечения power LED. После многих попыток запустить устройство, отключения жёстких дисков, нажатия кнопки reset (которая, кстати, безполезна пока загрузка не завершится успешно), я с горечью осознал, что это не тривиальная проблема, с которой мне прийдётся справиться самому из-за истёкшей гарантии (12 месяцев).
Осмотр содержимого жёстких дисков через USB-to-SATA показал, что данные в порядке, RAID1 сконфигурирован.
Джедайское гугление дало надежду на подключение к последовательному порту DNS-325 и возможной диагностики. Необходимо подобраться к порту, плата легко достаётся после отключения жёстких дисков и вывинчивания 4-х винтов сзади NAS (шлицы находятся под резиновыми заглушками).
Детали о распиновке UART на плате и способе подключения можно найти здесь. Оставалась одна проблема. UART на плате DNS-325 требует TTL 3.3V и может сгореть при более высоких напряжениях. У меня не оказалось RS-232-TTL 3.3V конвертора, а заказанный кабель на eBay так и не пришёл в срок. Связавшись с продавцом, я получил ответ, мол, видимо, потерялся, бывает. Деньги он вернул, но нужно было искать другой кабель или… На помощь пришла идея использовать завалявшуюся Raspberry PI (или ��росто Малину), на борту которой есть 3.3V UART.
Возможно, повторюсь, рассказывая о том, как настроить Малину с «нуля», но я сам был бы рад прочитать об этом в одном месте и последовательно.
Так как моя «Малина» была уже в работе, необходимый минимум железа имелся:
Итак, скачиваем готовый образ для SD-карты дистрибутива RASPBIAN с главного сайта www.raspberrypi.org. Далее записываем скаченый образ на SD-карту. В моём случае я использовал встроенный card-reader в ноутбуке и программу
Далее навигация по меню: «8 Advanced Options» --> «A7 Serial»:
Выбираем «No» и перезагружаемся.
Запускаем эмулятор терминала для работы с последовательным портом:
После того, как соответствующие пины последовательного порта DNS-325 подключены к Raspberry PI, наступает самый долгожданный момент включения устройства. Сейчас, собственно, хоть что-то станет ясно, почему NAS после включения входит в «крутое пике» и не подает признаков жизни. Скорость порта и прочие настройки установлены верно, само устройство оказалось «живым» и в консоли Малины побежал лог загрузки.
Раскрыв спойлер, можно увидеть весь лог загрузки:
Для доступа в shell необходимо ввести код
После беглого осмотра в консоли стало ясно, что NAS загрузился в single-user mode. Ничего не смонтировано кроме корневой системы.
Очевидно, что процесс загрузки не продолжается именно из-за проблем с монтированием основного файлового дерева из squash образа:
Сам файл, в котором squash образ, выгружается из внутренней flash в файл
Первое, что приходило в голову, была мысль о возможном повреждении самого
После чего U-Boot грузил образ другого, более старого ядра: Image Name: Linux-2.6.22.18
Забегая вперёд, хотелось бы отметить, что область
Гугление не дало готового решения, но вдохновило на jugaad, а именно: используя возможности U-Boot перезаписать uImage образ во внутренней flash памяти с помощью вырезанного образа из стоковой прошивки.
Скачиваем стоковую прошивку с сайта D-Link:
Каким-то образом необходимо было достать образ с ядром и попробовать перезаписать в повреждённую область.
Очень полезным инструментом оказался

Вырезанный uImage образ попробуем записать во внутреннюю flash память начиная с адреса
Для того, что передавать бинарные файлы в U-Boot нам понадобится достаточно древний протокол Kermit.
Создаём
Чтобы попасть в U-Boot командную строку, необходимо успеть прервать процесс загрузки нажав Пробел и «1» в момент, когда в консоли
К сожалению, я не обнаружил в стоковом U-Boot команды
Хочу поделиться историей о том, как я чинил
Сам NAS у меня обычно в режиме минимального потребления электроэнергии с выключенными жёсткими дисками WD Green (установлен fun_plug на внешнюю USB флешку, об этой «прокачке» есть статья на Хабре). Однажды, после отпуска, я включил питание на NAS, чтобы просмотреть/загрузить фотографии. Он не включился. Cветодиод питания весело замигал, загорелись индикаторы сотояния HDD, но мигание продолжалось и продолжалось без признаков жизни. При нормальных условиях мигание означает процесс загрузки, который должен завершиться полной инициализацией и установлением стабильного свечения power LED. После многих попыток запустить устройство, отключения жёстких дисков, нажатия кнопки reset (которая, кстати, безполезна пока загрузка не завершится успешно), я с горечью осознал, что это не тривиальная проблема, с которой мне прийдётся справиться самому из-за истёкшей гарантии (12 месяцев).
Осмотр содержимого жёстких дисков через USB-to-SATA показал, что данные в порядке, RAID1 сконфигурирован.
Джедайское гугление дало надежду на подключение к последовательному порту DNS-325 и возможной диагностики. Необходимо подобраться к порту, плата легко достаётся после отключения жёстких дисков и вывинчивания 4-х винтов сзади NAS (шлицы находятся под резиновыми заглушками).
Детали о распиновке UART на плате и способе подключения можно найти здесь. Оставалась одна проблема. UART на плате DNS-325 требует TTL 3.3V и может сгореть при более высоких напряжениях. У меня не оказалось RS-232-TTL 3.3V конвертора, а заказанный кабель на eBay так и не пришёл в срок. Связавшись с продавцом, я получил ответ, мол, видимо, потерялся, бывает. Деньги он вернул, но нужно было искать другой кабель или… На помощь пришла идея использовать завалявшуюся Raspberry PI (или ��росто Малину), на борту которой есть 3.3V UART.
Возможно, повторюсь, рассказывая о том, как настроить Малину с «нуля», но я сам был бы рад прочитать об этом в одном месте и последовательно.
Настройка Raspberry PI
Так как моя «Малина» была уже в работе, необходимый минимум железа имелся:
- Собственно, сама Raspberry PI;
- Акриловый корпус;
- SD карта;
- Коннектор на GPIO/UART пины, блок питания etc.
Итак, скачиваем готовый образ для SD-карты дистрибутива RASPBIAN с главного сайта www.raspberrypi.org. Далее записываем скаченый образ на SD-карту. В моём случае я использовал встроенный card-reader в ноутбуке и программу
Win32DiskImager. По умолчанию сетевой интерфейс в дистрибутиве запрашивает адрес по DHCP, поэтому, подключив Малину к домашнему роутеру, я смог залогинится и сконфигурировать последовательный порт с помощью:root@raspberrypi:~# raspi-configДалее навигация по меню: «8 Advanced Options» --> «A7 Serial»:
Would you like a login shell to be accessible over serial? Current setting: yesВыбираем «No» и перезагружаемся.
Установка и настройка терминала
apt-get install minicomЗапускаем эмулятор терминала для работы с последовательным портом:
minicom -D /dev/ttyAMA0 -b 115200 -8После того, как соответствующие пины последовательного порта DNS-325 подключены к Raspberry PI, наступает самый долгожданный момент включения устройства. Сейчас, собственно, хоть что-то станет ясно, почему NAS после включения входит в «крутое пике» и не подает признаков жизни. Скорость порта и прочие настройки установлены верно, само устройство оказалось «живым» и в консоли Малины побежал лог загрузки.
Раскрыв спойлер, можно увидеть весь лог загрузки:
Вывод сообщений загрузки на терминал
** MARVELL BOARD: DB-88F6281A-BP LE
U-Boot 1.1.4 (May 16 2011 — 10:40:38) Marvell version: 3.4.14.DNS-325.03
U-Boot code: 00600000 -> 0067FFF0 BSS: -> 006CEE80
Soc: MV88F6281 Rev 3 (DDR2)
CPU running @ 1200Mhz L2 running @ 400Mhz
SysClock = 400Mhz, TClock = 200Mhz
DRAM CAS Latency = 5 tRP = 5 tRAS = 18 tRCD=6
DRAM CS[0] base 0x00000000 size 256MB
DRAM Total size 256MB 16bit width
Flash: 0 kB
Addresses 8M — 0M are saved for the U-Boot usage.
Mem malloc Initialization (8M — 7M): Done
NAND:128 MB
CPU: Marvell Feroceon (Rev 1)
Streaming disabled
Write allocate disabled
USB 0: host mode
PEX 0: interface detected no Link.
Net: egiga0 [PRIME]
Hit any key to stop autoboot: 0
NAND read: device 0 offset 0x100000, size 0x300000
load addr… =a00000
3145728 bytes read: OK
NAND read: device 0 offset 0x600000, size 0x300000
load addr… =f00000
Bad block at 0x780000 in erase block from 0x780000 will be skipped
3145728 bytes read: OK
## Booting image at 00a00000…
Image Name: Linux-2.6.31.8
Created: 2012-06-26 3:38:43 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2565784 Bytes = 2.4 MB
Load Address: 00008000
Entry Point: 00008000
Verifying Checksum… Bad Data CRC
NAND read: device 0 offset 0x7100800, size 0x500000
load addr… =a00000
5242880 bytes read: OK
## Booting image at 00a00000…
Image Name: Linux-2.6.22.18
Created: 2011-05-25 7:23:15 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2214860 Bytes = 2.1 MB
Load Address: 00008000
Entry Point: 00008000
Verifying Checksum… OK
OK
## Loading Ramdisk Image at 00d00000…
Image Name: Ramdisk
Created: 2011-07-11 5:47:12 UTC
Image Type: ARM Linux RAMDisk Image (gzip compressed)
Data Size: 1566183 Bytes = 1.5 MB
Load Address: 00e00000
Entry Point: 00e00000
Verifying Checksum… OK
Starting kernel…
Uncompressing Linux… done,.
Linux version 2.6.22.18 (jack@swtest4) (gcc version 4.2.1) #15 Wed May 25 15:23:11 CST 2011
CPU: ARM926EJ-S [56251311] revision 1 (ARMv5TE), cr=00053977
Machine: Feroceon-KW
Using UBoot passing parameters structure
Memory policy: ECC disabled, Data cache writeback
CPU0: D VIVT write-back cache
CPU0: I cache: 16384 bytes, associativity 4, 32 byte lines, 128 sets
CPU0: D cache: 16384 bytes, associativity 4, 32 byte lines, 128 sets
Built 1 zonelists. Total pages: 65024
Kernel command line: root=/dev/ram console=ttyS0,115200 :::DB88FXX81:egiga0:none
PID hash table entries: 1024 (order: 10, 4096 bytes)
Console: colour dummy device 80x30
Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
Memory: 256MB 0MB 0MB 0MB = 256MB total
Memory: 253696KB available (4156K code, 252K data, 124K init)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
NET: Registered protocol family 16
CPU Interface
— SDRAM_CS0 ....base 00000000, size 256MB
SDRAM_CS1 ....base 10000000, size 256MB
SDRAM_CS2 ....disable
SDRAM_CS3 ....disable
PEX0_MEM ....base e8000000, size 128MB
PEX0_IO ....base f2000000, size 1MB
INTER_REGS ....base f1000000, size 1MB
NFLASH_CS ....base fa000000, size 2MB
SPI_CS ....base f4000000, size 16MB
BOOT_ROM_CS ....no such
DEV_BOOTCS ....no such
CRYPT_ENG ....base f0000000, size 2MB
Marvell Development Board (LSP Version KW_LSP_4.3.4_patch30)-- DB-88F6281A-BP Soc: 88F6281 A1 LE
Detected Tclk 200000000 and SysClk 400000000
MV Buttons Device Load
Marvell USB EHCI Host controller #0: c06de600
PEX0 interface detected no Link.
PCI: bus0: Fast back to back transfers enabled
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
NET: Registered protocol family 2
Time: kw_clocksource clocksource has been installed.
IP route cache hash table entries: 2048 (order: 1, 8192 bytes)
TCP established hash table entries: 8192 (order: 4, 65536 bytes)
TCP bind hash table entries: 8192 (order: 3, 32768 bytes)
TCP: Hash tables configured (established 8192 bind 8192)
TCP reno registered
checking if image is initramfs...it isn't (no cpio magic); looks like an initrd
Freeing initrd memory: 1529K
cpufreq: Init kirkwood cpufreq driver
XOR registered 1 NET_DMA over 4 channels
XOR 2nd invalidate WA enabled
cesadev_init(c00119d8)
mvCesaInit: sessions=640, queue=64, pSram=f0000000
Warning: TS unit is powered off.
MV Buttons Driver Load
VFS: Disk quotas dquot_6.5.1
Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
squashfs: version 3.3 (2007/10/31) Phillip Lougher
squashfs: LZMA suppport for slax.org by jro
Installing knfsd (copyright © 1996 okir@monad.swb.de).
JFFS2 version 2.2. (NAND) ц┐ц┌ц┌б╘ 2001-2006 Red Hat, Inc.
fuse init (API version 7.8)
SGI XFS with large block numbers, no debug enabled
io scheduler noop registered
io scheduler anticipatory registered (default)
Serial: 8250/16550 driver $Revision: 1.1.1.1 $ 4 ports, IRQ sharing disabled
serial8250.0: ttyS0 at MMIO 0xf1012000 (irq = 33) is a 16550A
serial8250.0: ttyS1 at MMIO 0xf1012100 (irq = 34) is a 16550A
RAMDISK driver initialized: 16 RAM disks of 10240K size 1024 blocksize
loop: module loaded
Loading Marvell Ethernet Driver:
o Cached descriptors in DRAM
o DRAM SW cache-coherency
o Single RX Queue support — ETH_DEF_RXQ=0
o Single TX Queue support — ETH_DEF_TXQ=0
o TCP segmentation offload enabled
o LRO support supported
o Receive checksum offload enabled
o Transmit checksum offload enabled
o Network Fast Processing (Routing) supported
o Driver ERROR statistics enabled
o Driver INFO statistics enabled
o Proc tool API enabled
o SKB Reuse supported
o SKB Recycle supported
o Rx descripors: q0=128
o Tx descripors: q0=532
o Loading network interface(s):
o register under egiga0 platform
o egiga0, ifindex = 1, GbE port = 0
Warning: Giga 1 is Powered Off
mvFpRuleDb (c0f2a000): 2048 entries, 8192 bytes
Integrated Sata device found
scsi0: Marvell SCSI to SATA adapter
scsi1: Marvell SCSI to SATA adapter
NFTL driver: nftlcore.c $Revision: 1.1.1.1 $, nftlmount.c $Revision: 1.1.1.1 $
NAND device: Manufacturer ID: 0xec, Chip ID: 0xf1 (Samsung NAND 128MiB 3,3V 8-bit)
Scanning device for bad blocks
Bad eraseblock 60 at 0x00780000
Bad eraseblock 109 at 0x00da0000
Bad eraseblock 455 at 0x038e0000
Bad eraseblock 499 at 0x03e60000
Using static partition definition
Creating 6 MTD partitions on «nand_mtd»:
0x00000000-0x00100000: «u-boot»
0x00100000-0x00600000: «uImage»
0x00600000-0x00b00000: «ramdisk»
0x00b00000-0x07100000: «image»
0x07100000-0x07b00000: «mini firmware»
0x07b00000-0x08000000: «config»
ehci_marvell ehci_marvell.70059: Marvell Orion EHCI
ehci_marvell ehci_marvell.70059: new USB bus registered, assigned bus number 1
ehci_marvell ehci_marvell.70059: irq 19, io base 0xf1050100
ehci_marvell ehci_marvell.70059: USB 2.0 started, EHCI 1.00, driver 10 Dec 2004
usb usb1: configuration #1 chosen from 1 choice
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 1 port detected
USB Universal Host Controller Interface driver v3.0
mice: PS/2 mouse device common for all mice
i2c /dev entries driver
md: linear personality registered for level -1
md: raid0 personality registered for level 0
md: raid1 personality registered for level 1
device-mapper: ioctl: 4.11.0-ioctl (2006-10-12) initialised: dm-devel@redhat.com
dm_crypt using the OCF package.
usbcore: registered new interface driver usbhid
drivers/hid/usbhid/hid-core.c: v2.6:USB HID core driver
TCP cubic registered
NET: Registered protocol family 1
NET: Registered protocol family 17
md: Autodetecting RAID arrays.
md: autorun…
md:… autorun DONE.
RAMDISK: Compressed image found at block 0
EXT2-fs warning: maximal mount count reached, running e2fsck is recommended
VFS: Mounted root (ext2 filesystem).
Freeing init memory: 124K
init started: BusyBox v1.11.2 (2010-11-17 11:44:30 CST)
starting pid 276, tty '': '/etc/rc.sh'
** Mounting /etc/fstab
umount: proc: not mounted
umount: proc: not mounted
umount: /usr/local/modules: not mounted
umount: /usr/local/tmp/image.cfs: not found
umount: /usr/local/tmp: not mounted
first good block is 0
ECC failed: 0
ECC corrected: 0
Number of bad blocks: 3
Number of bbt blocks: 0
Block size 131072, page size 2048, OOB size 64
Dumping data starting at 0x00000000 and ending at 0x00000800…
image len = 36900864, image checksum = 9a5bf12
ECC failed: 0
ECC corrected: 0
Number of bad blocks: 3
Number of bbt blocks: 0
Block size 131072, page size 2048, OOB size 64
Dumping data starting at 0x00000800 and ending at 0x02d00000…
dump image checksum=9a5bf12
SQUASHFS error: Major/Minor mismatch, trying to mount newer 4.0 filesystem
SQUASHFS error: Please update your kernel
mount: wrong fs type, bad option, bad superblock on /dev/loop0,
missing codepage or other error
In some cases useful info is found in syslog — try
dmesg | tail or so
/etc/rc.sh: line 17: system_init: not found
starting pid 302, tty '': '-/bin/sh'
BusyBox v1.11.2 (2010-11-17 11:44:30 CST) built-in shell (ash)
Enter 'help' for a list of built-in commands.
U-Boot 1.1.4 (May 16 2011 — 10:40:38) Marvell version: 3.4.14.DNS-325.03
U-Boot code: 00600000 -> 0067FFF0 BSS: -> 006CEE80
Soc: MV88F6281 Rev 3 (DDR2)
CPU running @ 1200Mhz L2 running @ 400Mhz
SysClock = 400Mhz, TClock = 200Mhz
DRAM CAS Latency = 5 tRP = 5 tRAS = 18 tRCD=6
DRAM CS[0] base 0x00000000 size 256MB
DRAM Total size 256MB 16bit width
Flash: 0 kB
Addresses 8M — 0M are saved for the U-Boot usage.
Mem malloc Initialization (8M — 7M): Done
NAND:128 MB
CPU: Marvell Feroceon (Rev 1)
Streaming disabled
Write allocate disabled
USB 0: host mode
PEX 0: interface detected no Link.
Net: egiga0 [PRIME]
Hit any key to stop autoboot: 0
NAND read: device 0 offset 0x100000, size 0x300000
load addr… =a00000
3145728 bytes read: OK
NAND read: device 0 offset 0x600000, size 0x300000
load addr… =f00000
Bad block at 0x780000 in erase block from 0x780000 will be skipped
3145728 bytes read: OK
## Booting image at 00a00000…
Image Name: Linux-2.6.31.8
Created: 2012-06-26 3:38:43 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2565784 Bytes = 2.4 MB
Load Address: 00008000
Entry Point: 00008000
Verifying Checksum… Bad Data CRC
NAND read: device 0 offset 0x7100800, size 0x500000
load addr… =a00000
5242880 bytes read: OK
## Booting image at 00a00000…
Image Name: Linux-2.6.22.18
Created: 2011-05-25 7:23:15 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2214860 Bytes = 2.1 MB
Load Address: 00008000
Entry Point: 00008000
Verifying Checksum… OK
OK
## Loading Ramdisk Image at 00d00000…
Image Name: Ramdisk
Created: 2011-07-11 5:47:12 UTC
Image Type: ARM Linux RAMDisk Image (gzip compressed)
Data Size: 1566183 Bytes = 1.5 MB
Load Address: 00e00000
Entry Point: 00e00000
Verifying Checksum… OK
Starting kernel…
Uncompressing Linux… done,.
Linux version 2.6.22.18 (jack@swtest4) (gcc version 4.2.1) #15 Wed May 25 15:23:11 CST 2011
CPU: ARM926EJ-S [56251311] revision 1 (ARMv5TE), cr=00053977
Machine: Feroceon-KW
Using UBoot passing parameters structure
Memory policy: ECC disabled, Data cache writeback
CPU0: D VIVT write-back cache
CPU0: I cache: 16384 bytes, associativity 4, 32 byte lines, 128 sets
CPU0: D cache: 16384 bytes, associativity 4, 32 byte lines, 128 sets
Built 1 zonelists. Total pages: 65024
Kernel command line: root=/dev/ram console=ttyS0,115200 :::DB88FXX81:egiga0:none
PID hash table entries: 1024 (order: 10, 4096 bytes)
Console: colour dummy device 80x30
Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
Memory: 256MB 0MB 0MB 0MB = 256MB total
Memory: 253696KB available (4156K code, 252K data, 124K init)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
NET: Registered protocol family 16
CPU Interface
— SDRAM_CS0 ....base 00000000, size 256MB
SDRAM_CS1 ....base 10000000, size 256MB
SDRAM_CS2 ....disable
SDRAM_CS3 ....disable
PEX0_MEM ....base e8000000, size 128MB
PEX0_IO ....base f2000000, size 1MB
INTER_REGS ....base f1000000, size 1MB
NFLASH_CS ....base fa000000, size 2MB
SPI_CS ....base f4000000, size 16MB
BOOT_ROM_CS ....no such
DEV_BOOTCS ....no such
CRYPT_ENG ....base f0000000, size 2MB
Marvell Development Board (LSP Version KW_LSP_4.3.4_patch30)-- DB-88F6281A-BP Soc: 88F6281 A1 LE
Detected Tclk 200000000 and SysClk 400000000
MV Buttons Device Load
Marvell USB EHCI Host controller #0: c06de600
PEX0 interface detected no Link.
PCI: bus0: Fast back to back transfers enabled
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
NET: Registered protocol family 2
Time: kw_clocksource clocksource has been installed.
IP route cache hash table entries: 2048 (order: 1, 8192 bytes)
TCP established hash table entries: 8192 (order: 4, 65536 bytes)
TCP bind hash table entries: 8192 (order: 3, 32768 bytes)
TCP: Hash tables configured (established 8192 bind 8192)
TCP reno registered
checking if image is initramfs...it isn't (no cpio magic); looks like an initrd
Freeing initrd memory: 1529K
cpufreq: Init kirkwood cpufreq driver
XOR registered 1 NET_DMA over 4 channels
XOR 2nd invalidate WA enabled
cesadev_init(c00119d8)
mvCesaInit: sessions=640, queue=64, pSram=f0000000
Warning: TS unit is powered off.
MV Buttons Driver Load
VFS: Disk quotas dquot_6.5.1
Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
squashfs: version 3.3 (2007/10/31) Phillip Lougher
squashfs: LZMA suppport for slax.org by jro
Installing knfsd (copyright © 1996 okir@monad.swb.de).
JFFS2 version 2.2. (NAND) ц┐ц┌ц┌б╘ 2001-2006 Red Hat, Inc.
fuse init (API version 7.8)
SGI XFS with large block numbers, no debug enabled
io scheduler noop registered
io scheduler anticipatory registered (default)
Serial: 8250/16550 driver $Revision: 1.1.1.1 $ 4 ports, IRQ sharing disabled
serial8250.0: ttyS0 at MMIO 0xf1012000 (irq = 33) is a 16550A
serial8250.0: ttyS1 at MMIO 0xf1012100 (irq = 34) is a 16550A
RAMDISK driver initialized: 16 RAM disks of 10240K size 1024 blocksize
loop: module loaded
Loading Marvell Ethernet Driver:
o Cached descriptors in DRAM
o DRAM SW cache-coherency
o Single RX Queue support — ETH_DEF_RXQ=0
o Single TX Queue support — ETH_DEF_TXQ=0
o TCP segmentation offload enabled
o LRO support supported
o Receive checksum offload enabled
o Transmit checksum offload enabled
o Network Fast Processing (Routing) supported
o Driver ERROR statistics enabled
o Driver INFO statistics enabled
o Proc tool API enabled
o SKB Reuse supported
o SKB Recycle supported
o Rx descripors: q0=128
o Tx descripors: q0=532
o Loading network interface(s):
o register under egiga0 platform
o egiga0, ifindex = 1, GbE port = 0
Warning: Giga 1 is Powered Off
mvFpRuleDb (c0f2a000): 2048 entries, 8192 bytes
Integrated Sata device found
scsi0: Marvell SCSI to SATA adapter
scsi1: Marvell SCSI to SATA adapter
NFTL driver: nftlcore.c $Revision: 1.1.1.1 $, nftlmount.c $Revision: 1.1.1.1 $
NAND device: Manufacturer ID: 0xec, Chip ID: 0xf1 (Samsung NAND 128MiB 3,3V 8-bit)
Scanning device for bad blocks
Bad eraseblock 60 at 0x00780000
Bad eraseblock 109 at 0x00da0000
Bad eraseblock 455 at 0x038e0000
Bad eraseblock 499 at 0x03e60000
Using static partition definition
Creating 6 MTD partitions on «nand_mtd»:
0x00000000-0x00100000: «u-boot»
0x00100000-0x00600000: «uImage»
0x00600000-0x00b00000: «ramdisk»
0x00b00000-0x07100000: «image»
0x07100000-0x07b00000: «mini firmware»
0x07b00000-0x08000000: «config»
ehci_marvell ehci_marvell.70059: Marvell Orion EHCI
ehci_marvell ehci_marvell.70059: new USB bus registered, assigned bus number 1
ehci_marvell ehci_marvell.70059: irq 19, io base 0xf1050100
ehci_marvell ehci_marvell.70059: USB 2.0 started, EHCI 1.00, driver 10 Dec 2004
usb usb1: configuration #1 chosen from 1 choice
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 1 port detected
USB Universal Host Controller Interface driver v3.0
mice: PS/2 mouse device common for all mice
i2c /dev entries driver
md: linear personality registered for level -1
md: raid0 personality registered for level 0
md: raid1 personality registered for level 1
device-mapper: ioctl: 4.11.0-ioctl (2006-10-12) initialised: dm-devel@redhat.com
dm_crypt using the OCF package.
usbcore: registered new interface driver usbhid
drivers/hid/usbhid/hid-core.c: v2.6:USB HID core driver
TCP cubic registered
NET: Registered protocol family 1
NET: Registered protocol family 17
md: Autodetecting RAID arrays.
md: autorun…
md:… autorun DONE.
RAMDISK: Compressed image found at block 0
EXT2-fs warning: maximal mount count reached, running e2fsck is recommended
VFS: Mounted root (ext2 filesystem).
Freeing init memory: 124K
init started: BusyBox v1.11.2 (2010-11-17 11:44:30 CST)
starting pid 276, tty '': '/etc/rc.sh'
** Mounting /etc/fstab
umount: proc: not mounted
umount: proc: not mounted
umount: /usr/local/modules: not mounted
umount: /usr/local/tmp/image.cfs: not found
umount: /usr/local/tmp: not mounted
first good block is 0
ECC failed: 0
ECC corrected: 0
Number of bad blocks: 3
Number of bbt blocks: 0
Block size 131072, page size 2048, OOB size 64
Dumping data starting at 0x00000000 and ending at 0x00000800…
image len = 36900864, image checksum = 9a5bf12
ECC failed: 0
ECC corrected: 0
Number of bad blocks: 3
Number of bbt blocks: 0
Block size 131072, page size 2048, OOB size 64
Dumping data starting at 0x00000800 and ending at 0x02d00000…
dump image checksum=9a5bf12
SQUASHFS error: Major/Minor mismatch, trying to mount newer 4.0 filesystem
SQUASHFS error: Please update your kernel
mount: wrong fs type, bad option, bad superblock on /dev/loop0,
missing codepage or other error
In some cases useful info is found in syslog — try
dmesg | tail or so
/etc/rc.sh: line 17: system_init: not found
starting pid 302, tty '': '-/bin/sh'
BusyBox v1.11.2 (2010-11-17 11:44:30 CST) built-in shell (ash)
Enter 'help' for a list of built-in commands.
Для доступа в shell необходимо ввести код
5784468. После беглого осмотра в консоли стало ясно, что NAS загрузился в single-user mode. Ничего не смонтировано кроме корневой системы.
Очевидно, что процесс загрузки не продолжается именно из-за проблем с монтированием основного файлового дерева из squash образа:
SQUASHFS error: Major/Minor mismatch, trying to mount newer 4.0 filesystemSQUASHFS error: Please update your kernelmount: wrong fs type, bad option, bad superblock on /dev/loop0,Сам файл, в котором squash образ, выгружается из внутренней flash в файл
/usr/local/tmp/image.cfs с помошью nanddump.mount -o loop /usr/local/tmp/image.cfs /mnt приводило к такой же ошибке, что и при загрузке.Первое, что приходило в голову, была мысль о возможном повреждении самого
image.cfs во flash памяти. Но очередного просмотра лога загрузки я обратил внимание на сообщение об ошибке, которое изначально затерялось в длинном тексте лога: Image Name: Linux-2.6.31.8 ..... Verifying Checksum ... Bad Data CRCПосле чего U-Boot грузил образ другого, более старого ядра: Image Name: Linux-2.6.22.18
NAND read: device 0 offset 0x7100800, size 0x500000
load addr .... =a00000
5242880 bytes read: OK
## Booting image at 00a00000 ...
Image Name: Linux-2.6.22.18
Created: 2011-05-25 7:23:15 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2214860 Bytes = 2.1 MB
Load Address: 00008000
Entry Point: 00008000
Verifying Checksum ... OK
Забегая вперёд, хотелось бы отметить, что область
"mini firmware" внутренней flash, откуда загрузился образ с ядром в аварийном режиме, по-видимому, предназначена для подобных ситуаций. Если бы у меня стояла более ранняя прошивка, загрузка бы прошла успешно и я бы и не узнал о повреждении. Но в прошивке 1.04 новое ядро 2.6.31.8 и поэтому монтирование образа сжатой файловой системой (опять же, нового формата) на старом ядре завершалось ошибкой.Гугление не дало готового решения, но вдохновило на jugaad, а именно: используя возможности U-Boot перезаписать uImage образ во внутренней flash памяти с помощью вырезанного образа из стоковой прошивки.
Достаём образ uImage с ядром из прошивки
Скачиваем стоковую прошивку с сайта D-Link:
DLINK_DNS325.1.04b05 (на тот момент у меня стояла именна эта версия).Каким-то образом необходимо было достать образ с ядром и попробовать перезаписать в повреждённую область.
Очень полезным инструментом оказался
binwalk:Вырезанный uImage образ попробуем записать во внутреннюю flash память начиная с адреса
0x100000. Установка и настройка Kermit
Для того, что передавать бинарные файлы в U-Boot нам понадобится достаточно древний протокол Kermit.
apt-get install ckermitСоздаём
.kermrc с таким содержимым:set line /dev/ttyAMA0
set speed 115200
set carrier-watch off
set handshake none
set flow-control none
robust
set file type bin
set rec pack 1000
set send pack 1000
set window 5
Загрузка расширенного U-Boot
Чтобы попасть в U-Boot командную строку, необходимо успеть прервать процесс загрузки нажав Пробел и «1» в момент, когда в консоли
minicom на эту операцию отводится 2 секунды:PEX 0: interface detected no Link.Net: egiga0 [PRIME]Hit any key to stop autoboot: 1К сожалению, я не обнаружил в стоковом U-Boot команды
loadb , которая позволяет загружать бинарный файл по указанному адресу в памяти.
Поэтому прийдётся скачать и сконфигурировать утилиту для загрузки расширенного U-Boot через последовательный порт.
Необходим компилятор для сборки на Малине:
apt-get install gcc
Скачаем U-Boot:
git clone -b dns320_support github.com/lentinj/u-boot.git
Собираем:
make distclean && make dns325_config && make u-boot.kwb
(Если вы подключились с помощью кабеля USB-Uart-TTL и производите сборку на x86 платформе, необходимо установить ARM-компилятор: export CROSS_COMPILE=arm-linux-gnueabi-)
Запускаем утилиту для передачи U-Boot:
root@raspberrypi:~/u-boot# cd u-boot
root@raspberrypi:~/u-boot# ./tools/kwboot -p -b u-boot.kwb -B115200 -t /dev/ttyAMA0
Sending boot message. Please reboot the target.../
Всё готово к передаче, выключаем NAS, ждём 10 с, включаем и следим за процессом передачи u-boot.kwb.
Процесс займёт несколько минут. В консоле вы сможете видеть процесс передачи в виде бегущих точек.
По окончании передачи необходимо прервать загрузку в момент Hit any key to stop autoboot: 4 (см. выше).
Выйдем из программы с помошью Ctrl+/ затем "c"
Передача образа и запись во flash
Запускаем kermit на Малине и инициируем передачу файла uKernel, который мы вырезали ранее из прошивки:
root@raspberrypi:~# kermit
и переходим в режим коесоли последовательного порта:
(/root/) C-Kermit>connect
Connecting to /dev/ttyAMA0, speed 115200
Escape character: Ctrl-\ (ASCII 28, FS): enabled
Type the escape character followed by C to get back,
or followed by ? to see other options.
----------------------------------------------------
Здесь, в командной строке U-Boot, даём команду на приём файла по адресу 0x000000 (загружаем мы временно для перезаписи, поэтому базовый адрес не важен):
=> loadb 0x00000000
U-Boot переходит в режим ожидания файла, а мы выходим в командную строку Kermit нажатием Ctrl+\ и "c" и передаем файл:
(/root/) C-Kermit>send uKernel

Через несколько минут файл передан и готов к записи во flash:
=> nand erase 0x100000 0x300000 - Очистка flash области 0x100000-0x300000
=> nand write 0x000000 0x100000 0x300000 - Запись из памяти со смещением 0x000000
ВСЁ... можно перезагрузиться.
NAS успешно загрузился с установленными дисками и USB флешкой как ни в чём не бывало.
Для перестраховки я загрузил последнюю версию прошивки стандартным путём через страничку управления.
P.S. Подобные операции с U-Boot и перезаписыванием внутренней flash я производил впервые, поэтому остаётся открытыми вопросы эффективности описанных выше шагов. В частности, я не смог найти ответы или проверить:
- Что произошло и как этого избежать в будущем?
- Реальный размер uImage образа существенно меньше считываемого U-Boot'ом размера 0x300000;
- Использование
tftp для передачи образа uImage;
- Использование USB flash для загрузки образа uImage (в расширеном U-Boot есть возможность инициализации USB);
- Бэкап разделов внутренней flash памяти на внешнюю USB память.
