How to create initrd/initramfs for use with tftp

(Adam B) #21

To be honest I’ve never tried to set up more than one interface in cmdline. And I don’t know how many “ip” kernel expects. You may just try what will be the reaction of kernel if oyu give him two ips.


Well, you are loading it into memory with the tftp command on a certain address. That memory block should have enough room for it, not overwriting other parts or reaching the end of your memory. The ‘keep it small’ is a general advice when you are loading the entire filesystem into memory, instead of reading it from flash on demand.

Not possible, see ip= option details (You found this already)

Edit: For nfs boot you don’t need an initramfs. You can directly “mount” the nfs as your rootfs and have the filesystem available on there.

(Frank W.) #23

currently i load the kernel with ramfs on ANY address and load it, if i want to load a ramfs containing all modules i have to look that i have enough space after that address (maybe moving it forward). currently i don’t know where are free blocks (not used by preloader/uboot/…) so i dont know if this 100MB modules can be loaded without problems.

i prefer the initramfs-method because nfs needs additional server-setup…i test a bit with it, but if i can create a initramfs with all my modules and some basic tools (also hostapd and e.g. nano) this should be enough. if i want more, i can load a debian from nfs. it seems that with ramfs i don’t need to put eth0 up so i need only 1 ip-param for wan. have not fully configured nfs yet (only basic nfs-setup, will try to access via client, bootstraped debian, changed some options like fstab)

@bitmaster how did you exactly build your ramfs…

  • create a folder for it (ext-fs)
  • unpack/install busybox ( shows no armhf)
  • add/change files?
  • any config (e.g. size of ramfs)
  • how about the “overlay”, hoe do i create this?

sorry i have not done a initrd/ramfs yet.

(Frank W.) #24

my first try for nfs

netargs=console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait ip= #ip=dhcp
netbootargs=${netargs} root=/dev/nfs rw nfsroot=${nfs_ip}:${nfs_rfs}

[    6.191858] VFS: Cannot open root device "nfs" or unknown-block(0,255): error -6
[    6.199207] Please append a correct "root=" boot option; here are the available partitions:
[    6.207545] b300        31166976 mmcblk0 
[    6.207550]  driver: mmcblk
[    6.214328]   b301          262144 mmcblk0p1 000ed6cd-01
[    6.214331] 
[    6.221080]   b302         7270400 mmcblk0p2 000ed6cd-02
[    6.221082] 
[    6.227848] b308         7634944 mmcblk1 
[    6.227852]  driver: mmcblk
[    6.234617]   b309          262144 mmcblk1p1 7de78640-01
[    6.234619] 
[    6.241382]   b30a         7270400 mmcblk1p2 7de78640-02
[    6.241385] 
[    6.248135] b320             512 mmcblk1rpmb 
[    6.248138]  (driver?)
[    6.254815] b318            4096 mmcblk1boot1 
[    6.254818]  (driver?)
[    6.261579] b310            4096 mmcblk1boot0 
[    6.261582]  (driver?)
[    6.268331] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,255)

i found no entry where nfs gets mounted (maybe a nfs-error)

it seems that my variables don’t get evaluated:

[    0.000000] Kernel command line: ${netargs} root=/dev/nfs rw nfsroot=${nfs_ip}:${nfs_rfs}

how can i control if variables will be evaluated?

nfs-boot.txt (50,1 KB)

tried also with hardcoded nfs-options:

[    0.000000] Kernel command line: console=ttyS0,115200 ip= root=/dev/nfs rw nfsroot=

but same error

tried to mount nfs from another pc works

arg…seems that i missed CONFIG_ROOT_NFS, changed to y and now it hangs at

[    8.871635] IP-Config: Complete:
[    8.874840]      device=wan, hwaddr=b2:f7:54:15:12:3c, ipaddr=, mask=, gw=
[    8.884864]      host=, domain=, nis-domain=(none)
[    8.890648]      bootserver=, rootserver=, rootpath=     nameserver0=, nameserver1=
[    8.902118] clk: Not disabling unused clocks
[    8.906373] vdd_fixed_vgpu: disabling
[    8.910028] vusb: disabling
[    8.912827] vmc: disabling
[    8.915517] vgp1: disabling
[    8.918310] vcamaf: disabling
[    8.921270] ALSA device list:
[    8.924220]   No soundcards found.
[    8.928144] md: Waiting for all devices to be available before autodetect
[    8.934911] md: If you don't use raid, use raid=noautodetect
[    8.941174] md: Autodetecting RAID arrays.
[    8.945270] md: autorun ...
[    8.948037] md: ... autorun DONE.

and quits with

[  109.937672] VFS: Unable to mount root fs via NFS, trying floppy.
[  109.944024] VFS: Cannot open root device "nfs" or unknown-block(2,0): error -6

cmdline looks like this:

[    0.000000] Kernel command line: console=ttyS0,115200 ip= root=/dev/nfs rw nfsroot=


I found various reasons why this might fail:

hi thank you everyone. i got it working.

i enabled


in the kernel config.

i also removed rdinit=/sbin/init from the kernel command line.

one of these 2 actions probably fixed the problem.


The problem turned out to be the NFS protocol version. The target board apparently wants to use version 2 by default, but that isn’t supported in CentOS 7. Adding “,nfsvers=3” to the nfsroot variable in bootargs solved the problem.


modern NFSv4 server has no UDP based connection support anymore. but the linux kernel is trying to mount rootfs over UDP by default, even for the NFSv4 yet. missing option would be to ask kernel to mount NFS over TCP as following:

Linux PPC load:

root=/dev/nfs rw nfsroot=,tcp ip=dhcp

for the complete reliable parameters set it would be good to ask for the NFSv4 protocol version specifically also:

root=/dev/nfs rw nfsroot=,vers=4,tcp ip=dhcp

in case of failure use a very helpful flag nfsrootdebug at the tail of the bootargs:

root=/dev/nfs rw nfsroot=,vers=4,tcp ip=dhcp nfsrootdebug


You have to modify your /etc/exports from

/nfs 192.168.1.*(rw,sync,no_root_squash)


/nfs *(rw,sync,no_root_squash)

even if your computer is of an IP address 192.168.1.* …


Can you try if these fix your problem?

Edit: For your own initramfs I would start by downloading busybox and running make menuconfig. Then you can discover all it has to offer. You can just provide the CROSS_COMPILE flag to the make command to compile it for a different platform (if PATH is set correctly as well). The FAQ is really useful to get you started with busybox’ basics. After make install check the busybox output folder (set by CONFIG_PREFIX) and you will see what I mean with “your rootfs folder” in the previous posts.

(Frank W.) #26

the kernel-options above are already set to y

changed my netargs-param like this:

netargs=console=ttyS0,115200 ip= root=/dev/nfs rw nfsroot=,nfsvers=3,tcp nfsrootdebug

i got my debian booted :wink: seems that nfsver or the tcp-option fixed it:

root@bpi-r2-nfs:~# mount                                                                                                                                                                                                     on / type nfs (rw,relatime,vers=3,rsize=4096,wsize=4096,namlen=255,hard,nolock,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=,mountvers=3,mountproto=tcp,local_lock=all,addr= 

btw. here in debian, my dns-setting is working from cmdline, seems it is overridden in your initramfs

have you an idea why the variables in uboot don’t get evaluated? i use them in uenv.txt after defining them, so i think they should get evaluated…its hard to edit such a long string in uboot-cli


They might be evaluated, but maybe a dhcp client is started and overwrites the values in /etc/resolv.conf (e.g. udhcpc uses /usr/share/udhcpc/default.script)

(Frank W.) #28

i see the vars itself (not the data) in cmdline on kernel-bootup


Ah wait, yes I misunderstood. The variables are only set when you run setenv. For example you can configure it something like this:

set_bootargs=setenv bootargs nfsroot=${nfs_ip}:${nfs_rfs}
boot_nfs=run set_bootargs; tftp XX; bootm

If you would do this, the variables in bootargs are not expanded:

boot_nfs=tftp XX; bootm

(Frank W.) #30

this is my current config

netargs=console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait ip=                                                                                       
netargs=console=ttyS0,115200 ip= root=/dev/nfs rw nfsroot=,nfsvers=3,tcp nfsrootdebug                                      
#new bootmenuentries (start at bootmenu_6) require reload bootmenu because uenv.txt is not loaded before display menu                                                                                                                 
bootnet=printenv; setenv bootargs "${netargs}";tftp 0x80200000 ${bootfile};bootm                                                                                                                                                      
bootmenu_1=2. Boot kernel from TFTP.=run bootnet

how can i replace a var with the same content and add new data

netargs=console=run setenv netargs "${netargs} root=/dev/nfs rw nfsroot=${nfs_ip}:${nfs_rfs},nfsvers=3,tcp nfsrootdebug"


mhm, seems that i can only run on a menu-entry, not on var-definition…that makes a bit difficult to append options


You can just run: setenv netargs $netargs x=y y=z

Or consider:

set_netargs=setenv netargs $netargs x=y y=z
boot_nfs=run set_netargs; run ......

(Frank W.) #32

seems this works only once…tried like this:

netargs=console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait ip=${ipaddr}:${serverip}:${serverip}:${netmask}::wan::${serverip}:                                                             
#netargs=console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait ip=                                                   
#netargs=console=ttyS0,115200 ip= root=/dev/nfs rw nfsroot=,nfsvers=3,tcp nfsrootdebug  
nfs_args=root=/dev/nfs rw nfsroot=${nfs_ip}:${nfs_rfs},nfsvers=3,tcp nfsrootdebug                                                                                                                  
bootnet=printenv; setenv bootargs "${netargs} ${nfsargs}";tftp 0x80200000 ${bootfile};bootm                               
bootmenu_1=2. Boot kernel from TFTP.=run bootnet

results in this (nfs_args missing is a typo):

root@bpi-r2-ubuntu:~# cat /proc/cmdline                                                                                                       
console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait ip=${ipaddr}:${serverip}:${serverip}:${netmask}::wan::${serverip}:

i need it cascaded, or should i run setenv twice anyhow first build the complete var and then setenv again (to evaluate the vars inside the vars)?

bootnet=setenv netargs ${netargs};setenv nfsargs ${nfsargs}; setenv bootargs "${netargs} ${nfsargs}" ...

does also not work…i hope you understand what i try to do…

edit: i had understand how you did it :slight_smile:

set_netargs=setenv netargs "console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait ip=${ipaddr}:${serverip}:${serverip}:${netmask}::wan::${serverip}:"                                        
#netargs=console=ttyS0,115200 ip= root=/dev/nfs rw nfsroot=,nfsvers=3,tcp nfsrootdebug  
set_nfsargs=setenv nfsargs "root=/dev/nfs rw nfsroot=${nfs_ip}:${nfs_rfs},nfsvers=3,tcp nfsrootdebug"                                                                                              
#new bootmenuentries (start at bootmenu_6) require reload bootmenu because uenv.txt is not loaded before display menu                                                                              
bootnet=run set_netargs;run set_nfsargs; setenv bootargs "${netargs} ${nfsargs}"; printenv; tftp 0x80200000 ${bootfile};bootm
bootmenu_1=2. Boot kernel from TFTP.=run bootnet

and hooray…it boots the nfs :slight_smile:

have added my infos here in my wiki, if anybody wants to try (have to make it more pretty :slight_smile: )…


Perfect! Good job :smiley:

Are you still planning to try initramfs? This typically is a powerful method for embedded devices because when you have your complete filesystem in memory, you cannot mess it up (e.g. with an unexpected powercycle). After a reboot everything is back the way it was. Second advantage is firmware upgrade is as simple as overwriting the initrd file. You don’t have to remount, chroot, or whatever tricks to release the root flash partition. For saving persistent configuration you could mount a writable partition on flash to save a file.

(Frank W.) #34

I will try initramfs too,but it seems a bit more work than simply unpack some files and repack them with modules


Oh yes you can do this, but it’s much more flexible to understand where those ‘files’ came from, so you can change anything you like, instead of only the modules.

Take your time :slight_smile:

(Frank W.) #36

can you give me you config for bpi-r2…i hang on the target options :smiley:

I thought i can only define external crosscompiler arm-linux-gnueabihf-gcc and select the applications


Yes sorry I just got home. I didn’t touch this for a long time but as I remember it still was almost default (except the required options). It’s a config file for version 1.28.2. bpi_r2_defconfig (26.5 KB). I guess you can upgrade it with make oldconfig.

I quickly checked the config again but didnt really find any special flags. Dont forget to set:

PATH= ...

(Frank W.) #38
export ARCH=arm;
export CROSS_COMPILE=arm-linux-gnueabihf-
make bpi_r2_defconfig #after copy it to configs-folder

seems to ignore my Crosscompiler (see download of gcc)…i wait till the compile finishes and test the binaries with file…

seems my crosscompiler is completely ignored

[14:41:31]$ file output/target/bin/busybox
output/target/bin/busybox: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/, stripped


Ok, yes. I also do it like this.

Can you execute arm-linux-gnueabihf-gcc in the folder you are running make?

You don’t need the additional ; after ARCH=arm

I expect I am messing something up with the config file. I have some time this weekend to check it.

(Frank W.) #40

what do you want to see?

[14:49:14]$ arm-linux-gnueabihf-gcc
arm-linux-gnueabihf-gcc: fatal error: no input files
compilation terminated.

as expected…

i see something strange in the makefile:

 396 unexport CROSS_COMPILE
 397 unexport ARCH

so this needs to be set in the config…