Linux root filesystem on custom hardware


I have a custom-designed SoC implemented on FPGA, based on an ARM-processor clone, on which I am trying to boot Linux (kernel 3.10).

I have successfully added support to my custom peripherals (an USART, Interrupt Controller and Timer), allowing me to see the printk messages displayed by the kernel up to the point of trying to mount root filesystem.

I have a 2GB custom non-volatile memory, random-access, read write, mapped from address 0 to 0x7FFFFFFF from which the bootloader executes, and which contains the kernel and the filesystem partition. The bootloader copies kernel to RAM (256Mb, from 0x80000000 to 0x8FFFFFFF) and then passes control to Linux, which fails at the point: "Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)".

From my debugging and internet searches, it seems the kernel cannot recognize my non-volatile memory, therefore cannot mount the filesystem.

How do I tell the kernel that it should boot from that memory, and which code must be added to the kernel? For example, would it be possible to make the kernel think my memory is a Nand, and modify Nand drivers to access it correctly?

Thank you in advance for all help and sugestions.

asked on Super User Dec 23, 2013 by user3130285

1 Answer


I'm not sure what you are doing now for your "filesystem partition." But you can place an initrd into your nonvolatile storage that looks/acts like RAM, and then have your bootloader tell Linux to use the initrd.

Most initrds do some setup and then try to re-mount a root filesystem on a block device. In your case, your initrd would be your real root filesystem and you'd need to be placing utilities like shells, etc. in the initrd.

When booting on ARM using U-Boot, basically the boot commands load the kernel and initrd from a storage device into a fixed RAM location, and then the address of the initrd is passed to the kernel as a command line parameter, specifying the address.

Well, the MTD driver can take a section of RAM (there's a "Physical System RAM" option in the MTD driver on make menuconfig) and turn it into a block device, if you really need a readable/writeable block device. It can be used to mount graphics card RAM as a small swap partition, for example. See this.

I think the command to do it would be modprobe phram phram=0x00100000;256MiB, if you have a 256MByte filesystem at memory location 0x00100000. Then modprobe mtdblock which then makes /dev/mtdblock0. You can then do things like mount /dev/mtdblock0 and such. So you'd need a small script in an initrd that does the above, then fsck /dev/mtdblock0, and then starts your init or whatever your process 1 is.

You might even be able to specify that all on the kernel command line somehow but I'm not sure if that's supported. You might want to use a small initrd anyway just to be flexible.

answered on Super User Dec 23, 2013 by LawrenceC • edited Dec 24, 2013 by LawrenceC

User contributions licensed under CC BY-SA 3.0