Tiny Core Linux

Tiny Core Base => TCB Q&A Forum => Topic started by: wysiwyg on December 11, 2010, 11:25:41 PM

Title: Booting to a ramdisk
Post by: wysiwyg on December 11, 2010, 11:25:41 PM
Hi all, this will be my first post here!  I'm working on building an embedded version of GNU/Linux for some hardware I recently purchased (plus I'm interested in learning).  I've wondered around this website and think TinyCore is a great project and decided to mirror parts of it.  Starting from "scratch", I grabbed TinyCore's Linux Kernel and mostly followed the directions to install it due to mine going on an SD card vs an HD.  Using that combo, I have no problem booting up successfully into TinyCore (and might I say, in the blink of an eye!).  Knowing that grub and the kernel are working without a problem, I decided to add my own ramdisk image into the mix.  I modified the /boot/grub/menu.lst file to use my ramdisk.  At the moment my ramdisk only contains a statically linked compiled version of bash 4.1 and ram0 & console device files.  I planned on just passing "init=/bin/bash" to the kernel option in menu.lst.  At first I kept getting errors stating "please append a correct "root=" boot option; ..." and "VFS: Unable to mount root fs on unknown-block(8,3)".  Later, I added a "root=" parameter to the menu.lst and have the entire string read: kernel /boot/kernel_2.6.33.3 init=/bin/bash root=/dev/ram0
That gets further in the boot process, and (coincidentally) when it gets to the part where the USB detects the SD (via USB adapter) that's being booted off of, the boot process halts.  I'm not sure if the boot process is finished, but it doesn't know what to "init" for whatever reason or the boot process is hung.  I'm also not sure if I'm missing more mandatory files in my ramdisk.  I'd like to have my project boot up in a ramdisk and stay there just like TinyCore does.  I'd greatly appreciate any help on getting my ramdisk up and running as well as the few questions below.

Thanks,
Dave

1). Where can I get TinyCore's kernel config file to see what I might need to add or remove for my own project?
2). How can I access the TinyCore ramdisk contents?  I tried unzipping it with gunzip and dd'ing it to a ramdisk, but when I try to mount it, it keeps asking for a filesystem type.
3). What were the compile parameters used when compiling the core software packages for the TinyCore base?
Title: Re: Booting to a ramdisk
Post by: maro on December 11, 2010, 11:43:28 PM
(1) The kernel config files are here (http://distro.ibiblio.org/pub/linux/distributions/tinycorelinux/3.x/release/src/kernel/). The TC specific patches are in the sub-dirrectory and the sources already patched are in the "big file".

(2) I assume what you mean with "TinyCore ramdisk contents" is the content of the initrd (igoring the fact that files restored from backup and extensions loaded later on also become part of the ramdisk). I'd use zcat tinycore.gz | sudo cpio -idum to extract all those files from the initrd (in a different "world" you could even use something like '7zFM' to extract the lot).

(3) That might be a question for someone else to answer: The sources of the Core components should be found under here (http://distro.ibiblio.org/pub/linux/distributions/tinycorelinux/3.x/release/src), but unlike the extension sources (http://distro.ibiblio.org/pub/linux/distributions/tinycorelinux/3.x/tcz/src/) which mostly (but not always) have some build script I'm not sure where to find the same for the Core components.
Title: Re: Booting to a ramdisk
Post by: curaga on December 12, 2010, 04:12:51 AM
The conventions are different depending if you use an initramfs (cpio) or an initrd, including the location of init. I don't remember how the older side went, but a basic set of /dev and static bash as /init in a cpio archive should work.
Title: Re: Booting to a ramdisk
Post by: tinypoodle on December 12, 2010, 04:19:50 AM
2). How can I access the TinyCore ramdisk contents?  I tried unzipping it with gunzip and dd'ing it to a ramdisk, but when I try to mount it, it keeps asking for a filesystem type.

AFAIK, TC does not make any use of ramdisks at all. ramdisks would need to be formatted in order to be mounted - as opposed to initramfs, rootfs and tmpfs.

A search in wiki for "remastering" regarding unpacking and repacking of tinycore.gz might be helpful.
Title: Re: Booting to a ramdisk
Post by: wysiwyg on December 12, 2010, 12:00:51 PM
Thanks everyone!  You've provided me with some helpful information that I'm going to try to digest later this afternoon (after house chores :).  Has anyone here thought of making a tutorial/HowTo on all creating an OS of this calibur and type?  It would be an invaluable resource for people who would want to learn.  I know there are already several documents (I was using the Pocket Linux Guide), but those are all dated and not completely applicable any longer.  Food for thought!  :)

Dave
Title: Re: Booting to a ramdisk
Post by: wysiwyg on December 12, 2010, 12:05:33 PM
The conventions are different depending if you use an initramfs (cpio) or an initrd, including the location of init. I don't remember how the older side went, but a basic set of /dev and static bash as /init in a cpio archive should work.

Can you think of any mandatory /dev files other than console and ram0 at this point?  Also, if I pass "init=/bin/bash" to the kernel through grub, I shouldn't need an /init or /usr/sbin/init file right?  Shouldn't bash load automatically after the kernel has finished with the boot process?
Title: Re: Booting to a ramdisk
Post by: wysiwyg on December 12, 2010, 12:10:41 PM
AFAIK, TC does not make any use of ramdisks at all. ramdisks would need to be formatted in order to be mounted - as opposed to initramfs, rootfs and tmpfs.

A search in wiki for "remastering" regarding unpacking and repacking of tinycore.gz might be helpful.

I'm currently using an initrd (dd and gzip).  Are their advantages of one type over another?  At this point, I just want to mimic what TC is doing since it's obviously working, and working well. :)  Does someone know which of the three mentioned above is actually in use with TC?  I'll take a look at the "remastering" section to gain access to the image file.
Title: Re: Booting to a ramdisk
Post by: tinypoodle on December 12, 2010, 01:10:58 PM
You don't specify what you do with dd...

A dev would probably be able to answer your questions better, but as far as I understand, initramfs is extracted to rootfs which is a unique instance of tmpfs.
Have a look at /etc/mtab. One thing I have never understood myself is what the extra tmpfs mounted over /dev/shm is good for...

AFAIK, TC base does not make any use of images.
Noone claimed that the wiki was referring to remastering of any image file; it refers to unpacking and repacking a (gzipped) cpio archive.
Title: Re: Booting to a ramdisk
Post by: curaga on December 12, 2010, 03:09:23 PM
Can you think of any mandatory /dev files other than console and ram0 at this point?  Also, if I pass "init=/bin/bash" to the kernel through grub, I shouldn't need an /init or /usr/sbin/init file right?  Shouldn't bash load automatically after the kernel has finished with the boot process?

If you'd rather pass a param, sure. ram0 is not needed if using cpio, but null, zero, std{in,out,err}, random, urandom.

I'm currently using an initrd (dd and gzip).  Are their advantages of one type over another?  At this point, I just want to mimic what TC is doing since it's obviously working, and working well. :)  Does someone know which of the three mentioned above is actually in use with TC?  I'll take a look at the "remastering" section to gain access to the image file.

The differences are well documented in the kernel docs (initrd.txt, filesystems/ramfs-rootfs-initfamfs.txt)
TC uses initramfs, or a gzipped cpio archive.

One thing I have never understood myself is what the extra tmpfs mounted over /dev/shm is good for...

POSIX shared memory ;)
Title: Re: Booting to a ramdisk
Post by: tinypoodle on December 12, 2010, 04:08:05 PM
One thing I have never understood myself is what the extra tmpfs mounted over /dev/shm is good for...

POSIX shared memory ;)

Yes, that much I understood, and I had myself mounted tmpfs over /dev/shm years ago (~kernel 2.4.20) in scatter installed system for my own purposes.

What I do not understand is:
Quote
tmpfs                   900.5M    134.2M    766.3M  15% /
tmpfs                   500.3M         0    500.3M   0% /dev/shm

running TC in default mode, when there is a tmpfs of 90% of size of RAM mounted over / which is populated from the very beginning by the whole tree of the system hierarchy, of what purpose a second mounted tmpfs of 50% of size of RAM mounted over /dev/shm could be (which by default always remains unpopulated).
Title: Re: Booting to a ramdisk
Post by: wysiwyg on December 12, 2010, 09:11:56 PM
Ok guys, I'm still having no luck with my boot "ramdisk".  Here are the steps I've taken so far:

1) dd if=/dev/zero of=/dev/ram7 bs=1k count=8190
2) mke2fs /dev/ram7
3) mount /dev/ram7 /mnt/rd
4) cd /mnt/rd
5) mkdir bin dev sbin
6) copy the statically compiled bash to bin and made the following devices: zero, null, console, tty, tty0-6, ram0, initctl
7) find | sudo cpio -o -H newc | gzip > /mnt/source/boot/ramdisks/myrd.gz (/mnt/source is the bootable partition on the media)

grub parameters:
kernel /boot/kernel_2.6.33.3 init=/bin/bash [root=/dev/ram0] (this is just a renamed TinyCore Linux Kernel)
initrd /boot/ramdisks/myrd.gz

If I don't include the "root=/dev/ram0" I get:
VFS: Cannot open root device "(null)" or unknown-block(8,3)
Please append a correct "root=" boot option; here are the available partitions:
0b00     10448575 sr0 driver: sr
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(8,3)
... some codes ...

If I do include the "root=/dev/ram0" I get:
No filesystem could mount root, tried: ext2 ext3 ext4 cramfs iso9660 fuseblk
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(1,0)

I got further along in the boot process using the following dd commands instead of cpio above:
7a) umount /mnt/rd
8a) dd if=/dev/ram7 of=/mnt/source/boot/ramdisks/myrd bs=1k count=8190
9a) gzip /mnt/source/boot/ramdisks/myrd

Any help would greatly be appreciated...
Title: Re: Booting to a ramdisk
Post by: curaga on December 13, 2010, 04:48:24 AM
What I do not understand is:
Quote
tmpfs                   900.5M    134.2M    766.3M  15% /
tmpfs                   500.3M         0    500.3M   0% /dev/shm

running TC in default mode, when there is a tmpfs of 90% of size of RAM mounted over / which is populated from the very beginning by the whole tree of the system hierarchy, of what purpose a second mounted tmpfs of 50% of size of RAM mounted over /dev/shm could be (which by default always remains unpopulated).

It's separate, so that apps may still use it with the root being full / near full. In conventional systems it is a tmpfs so that it's automatically cleaned on reboot, in addition to the "full root" part.

50% is just the default tmpfs size.


@wysiwyg

I wonder if you could post more of the dmesg (set up a netconsole/serial console? A serial console can be output to a text file in Qemu).
Title: Re: Booting to a ramdisk
Post by: tinypoodle on December 13, 2010, 06:22:17 AM
What I do not understand is:
Quote
tmpfs                   900.5M    134.2M    766.3M  15% /
tmpfs                   500.3M         0    500.3M   0% /dev/shm

running TC in default mode, when there is a tmpfs of 90% of size of RAM mounted over / which is populated from the very beginning by the whole tree of the system hierarchy, of what purpose a second mounted tmpfs of 50% of size of RAM mounted over /dev/shm could be (which by default always remains unpopulated).

It's separate, so that apps may still use it with the root being full / near full. In conventional systems it is a tmpfs so that it's automatically cleaned on reboot, in addition to the "full root" part.

50% is just the default tmpfs size.

On scatter installed systems I had made use of all that, either by relinking /tmp to /dev/shm/tmp or by specifying certain configurable paths to use a subdir of /dev/shm or by copying data and/or executables to /dev/shm.
Never though have I seen any app using /dev/shm per default (without manual user intervention), if any such exists, then it would make sense of course.
What I have seen is certain "Live" Linux systems mounting part of the file tree over /dev/shm by default, which is not the case with TC.

I'd estimate that if on TC the tmpfs mounted over / being 90% of ram size would become full, any attempt to use the tmpfs mounted over /dev/shm in addition would result in a "swap party".
OTOH, the way the swap mechanism works under kernel 2.6, I'd expect that there might still be some gain of speed in comparison to using a block device filesystem for file storage.

What is my real curiosity is what possible positive and/or negative consequences umount-ing /dev/shm while running TC in default mode could potentially have.

Title: Re: Booting to a ramdisk
Post by: wysiwyg on December 13, 2010, 10:07:12 AM
@wysiwyg

I wonder if you could post more of the dmesg (set up a netconsole/serial console? A serial console can be output to a text file in Qemu).

I'd love to, but I don't have dmesg compiled as of yet.  I'm still trying to get the "ramdisk" containing just bash up and running.  I'm also not familiar with setting up a netconsole or serial console.  Would any of the codes from the failed boot be of any help?

 Is it possible for anyone to construct a "ramdisk" in the fashion I provided above (or in your own way) to see if I can use it with my install?  I'm just not sure if it's something I'm doing or some config on my dev computer.
Title: Re: Booting to a ramdisk
Post by: sandras on December 14, 2010, 01:27:41 PM
I myself am growing a Linux/Busybox/uClibc system. And I think I have some thing to note.

First, you should get rid of the first three steps in constructing your ramdisk. Because actually, what you are constructing is a simple archive which is later loaded by the bootloader to the ram and kernel extracts it into an instance of a ramdisk.

So you should go like this:
1) mkdir /tmp/myrd
2) cd /tmp/myrd
3) mkdir bin, dev, sbin , etc, etc. (see what i did there? : D)
4) make device nodes in dev, copy over bash.
5) find | sudo cpio -o -H newc | gzip > /mnt/source/boot/ramdisks/myrd.gz
something like this...

Second, I don't know why exactly, but I too have had problems with pointing the  kernel to what the real init is, but was able to boot, when i really had an /init (not /sbin/init, not /bin/init, not /usr/bin/init). Whatever stood for init, it worked. I think I had similar problems with kernel not mounting ramdisk too, but as far as I can remember most of the problems were solved by having something to stand there as an /init.
Title: Re: Booting to a ramdisk
Post by: wysiwyg on December 15, 2010, 10:10:01 AM
Thanks for the reply Sandras.  I've been working on this since the original post and have made a little progress, but still no bash prompt.  I have, however, noticed some strange behavior.  First I wanted to make sure that the bash that I compile was working right, so I added it to the tinycore ramdisk and upon reaching the grub menu changed it's kernel line to include "init=/bin/bash" only to find that tinycore booted up normally instead of just going to the bash prompt.  Is this normal behavior?  Does the "init=" line for grub even work any more or has it been deprecated (NOTE: I'm using legacy grub)?

In additional efforts to figure out what's going on, I decided to copy the /dev directory from the TinyCore ramdisk to my project and now I no longer get the errors mentioned above, but the boot process still hangs when the flash driving that I'm booting off of is detected by the kernel when booting to my own ramdisk.  Any thoughts anyone?

Something else that was odd while trying to get this to work... instead of using my compiled bash, I figured I'd give the busybox from TinyCore a shot to see if that would work.  I copied the entire /bin contents from the TinyCore ramdisk to my own (since it's just busybox with associated symlinks).  I then ran ldd on busybox so I could copy over any libs.  Doing so produced a list of 4-5 that needed to be copied over.  However, none of those libs exist on the TinyCore ramdisk!!!  Now I'm really confused!

Also, Sandras, thanks for the tips using cpio without a ramdisk.  I've removed the steps you mentioned from the process.  I've also tried creating symlinks for /init and /sbin/init pointing to /bin/bash with no luck.  Any other thoughts?

Dave
Title: Re: Booting to a ramdisk
Post by: wysiwyg on December 15, 2010, 10:44:21 AM
UPDATE: when looking at the ldd output from busybox, I realized that the files actually do exist in /lib except for linux-gate.so.1.  What threw me off initially is that I was looking for the "end result" of where the symlinks of the libs were pointing (which actually does not exist) based on the ldd output.  The actual symlinks do point to valid files however.  Anyone care to enlighten me what's going on here? :)


$ ldd busybox
        linux-gate.so.1 =>  (0x00b80000)
        libcrypt.so.1 => /lib/tls/i686/cmov/libcrypt.so.1 (0x00b0b000)
        libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0x00bb6000)
        libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00d39000)
        /lib/ld-linux.so.2 (0x00646000)

The /lib/tls directory doesn't exist on the TinyCore ramdisk nor does the linux-gate.so.1 lib.
Title: Re: Booting to a ramdisk
Post by: sandras on December 15, 2010, 10:48:21 AM
It's just a thought, but perhaps when kernel is booting into an initial ramdisk, it does'nt take the "init=" option? It just seems so, because "init=" works when root is something like hda2. At least it is so for me.

Also I think you don't need to provide a "root= " option when booting to a ramdisk. But maybe that's just me.
Title: Re: Booting to a ramdisk
Post by: tinypoodle on December 15, 2010, 11:19:55 AM
The /lib/tls directory doesn't exist on the TinyCore ramdisk nor does the linux-gate.so.1 lib.

linux-gate.so.1 is not a file, it's a virtual dynamically shared object
Title: Re: Booting to a ramdisk
Post by: tinypoodle on December 15, 2010, 11:35:39 AM
It's just a thought, but perhaps when kernel is booting into an initial ramdisk, it does'nt take the "init=" option? It just seems so, because "init=" works when root is something like hda2. At least it is so for me.

Also I think you don't need to provide a "root= " option when booting to a ramdisk. But maybe that's just me.

I think you need to provide a "root=" option when booting to a ramdisk - as opposed to when booting to a initramfs.
You might wanna try "rdinit=" instead with a initramfs.

A pointer to documentation regarding differences had been provided in reply #8
Title: Re: Booting to a ramdisk
Post by: wysiwyg on December 15, 2010, 12:07:08 PM
The /lib/tls directory doesn't exist on the TinyCore ramdisk nor does the linux-gate.so.1 lib.

linux-gate.so.1 is not a file, it's a virtual dynamically shared object

Ahh, nice to know.  That would explain why I can't locate it!  :)  Thanks for the tip!
Title: Re: Booting to a ramdisk
Post by: wysiwyg on December 15, 2010, 02:59:15 PM
It's just a thought, but perhaps when kernel is booting into an initial ramdisk, it does'nt take the "init=" option? It just seems so, because "init=" works when root is something like hda2. At least it is so for me.

Also I think you don't need to provide a "root= " option when booting to a ramdisk. But maybe that's just me.

I think you need to provide a "root=" option when booting to a ramdisk - as opposed to when booting to a initramfs.
You might wanna try "rdinit=" instead with a initramfs.

A pointer to documentation regarding differences had been provided in reply #8

I haven't looked at the documentation provided in that reply yet because I've stopped using the grub parameters to pass to the kernel (root=... init=...), but thanks for posting it.  I might have a look at it later just for the information.

Using a "root=" parameter has been removed in my setup because 1) TC doesn't use it to boot and I'm trying to mimic it 2) the failed boot is later than the previous posts (which was saying something along the lines of  "Can't find/mount root").  I know this for a fact because I created an /init bash script pointing to /bin/sh (busybox) that simply echo's "loading bash!!!" which I see on the screen and at which point the boot process stops (or at least I don't see the bash prompt).  I've also tried adding the line "exec /bin/bash" at the end of the /init file and actually copied bash to /init with no luck.  Any thoughts?
Title: Re: Booting to a ramdisk
Post by: wysiwyg on December 16, 2010, 01:51:56 PM
Ok, after long periods of testing, this is what I've come up with...

1) The ramdisk image *HAS TO HAVE* an "init" file in the root (/init) and *NOWHERE* else (e.g. /sbin/init, /bin/init, or /etc/init).  It doesn't matter if /init is a bash script, symlink, or bash itself renamed to /init, as long as that file is present and is a shell or init binary or a symlinking point to one.  The absence of /init will produce faulty/erroneous error messages by the Linux Kernel stating either "You must include a root= parameter" or "Couldn't determine the filesystem of the ramdisk; tried ext2, ext3, etc".  (NOTE: those aren't the exact error messages, but that's what they're conveying)

2)  Also the legacy grub kernel parameter "init=" does *NOT* work.  I'm not sure if these are "patches" to the TinyCore Linux kernel to increase speed or what.  Anyone have any contributions to why this is the case?

3) Apparently all the previous boots that got past the invalid error messages listed in #1 were a successful boot and I didn't know because my wireless keyboard wouldn't work (probably because of the absence of a /dev file).  As soon as I plugged in a wired keyboard and got to the point where the boot flash drive was detected, I could hit enter and see the good old familiar bash prompt!  I included #3 so that if anyone behind me ran into the same problems, hopefully they'll stumble upon this post...

Dave
Title: Re: Booting to a ramdisk
Post by: sandras on December 16, 2010, 02:36:15 PM
Even with my own kernel I noticed that init= option doesn't work well on initramfs. At least for me it didn'r might have done something wrong. Anyway, so it seems you must have /init in the .gz cpio archive that gets extracted to the in ram file system at boot time.
Title: Re: Booting to a ramdisk
Post by: tinypoodle on December 16, 2010, 04:57:39 PM
Even with my own kernel I noticed that init= option doesn't work well on initramfs. At least for me it didn'r might have done something wrong. Anyway, so it seems you must have /init in the .gz cpio archive that gets extracted to the in ram file system at boot time.

Have you read Reply #19?
Title: Re: Booting to a ramdisk
Post by: sandras on December 16, 2010, 05:49:28 PM
Sorry, I missed that. Actually, I'll have to try "rdinit=" option just out of pure curiosity.
Title: Re: Booting to a ramdisk
Post by: maro on December 16, 2010, 06:02:40 PM
I also initially skipped over reply #19, but I had a quick search over the kernel sources and there is the following snippit in 'init/main.c':
Code: [Select]
if (!ramdisk_execute_command)
ramdisk_execute_command = "/init";
And then the penny dropped, insofar as I figured that 'ramdisk_execute_command' gets populated with the value of 'rdinit=...'.

A quick test with the un-altered initrd using QEMU (i.e. qemu -kernel bzImage -initrd tinycore.gz -m 48 -append "rdinit=/bin/sh") confirmed just that. I ended up in a truely minimal root shell, which I consider to be exactly what wysiwyg wants.
Title: Re: Booting to a ramdisk
Post by: wysiwyg on December 17, 2010, 02:36:47 PM
Even with my own kernel I noticed that init= option doesn't work well on initramfs. At least for me it didn'r might have done something wrong. Anyway, so it seems you must have /init in the .gz cpio archive that gets extracted to the in ram file system at boot time.

Have you read Reply #19?


Sorry TinyPoodle, when you were mentioning that command, I thought you were saying to use rdinit= in order to specify the ramdisk image (which was already working properly with my config).  I just tried that parameter instead of init= and it worked like a charm!  Thanks for the tip!  Sorry I misunderstood.  :)

Anyone got any experience with compiling busybox (Sandras)?  I keep running into an error when issuing the "make" command after running "make menuconfig" and saving to a .config file.  Error snippets:

  HOSTCC  applets/usage
In file included from applets/usage.c:24:
include/usage.h:23:28: warning: missing terminating " character
In file included from applets/usage.c:24:
include/usage.h:25: error: expected identifier or ‘(’ before string constant
include/usage.h:33:10: warning: missing terminating " character
include/usage.h:33: error: missing terminating " character
include/usage.h:38:26: warning: missing terminating " character
include/usage.h:41:29: warning: missing terminating " character
include/usage.h:40: error: missing terminating " character
include/usage.h:50:24: warning: missing terminating " character
...
applets/usage.c:37: error: dereferencing pointer to incomplete type
applets/usage.c:37: error: dereferencing pointer to incomplete type
applets/usage.c:37: error: dereferencing pointer to incomplete type
applets/usage.c: In function ‘main’:
applets/usage.c:52: error: request for member ‘usage’ in something not a structure or union
applets/usage.c:52: error: request for member ‘usage’ in something not a structure or union
make[1]: *** [applets/usage] Error 1
make: *** [applets_dir] Error 2
Title: Re: Booting to a ramdisk
Post by: tinypoodle on December 17, 2010, 04:22:56 PM
Even with my own kernel I noticed that init= option doesn't work well on initramfs. At least for me it didn'r might have done something wrong. Anyway, so it seems you must have /init in the .gz cpio archive that gets extracted to the in ram file system at boot time.

Have you read Reply #19?

Sorry TinyPoodle, when you were mentioning that command, I thought you were saying to use rdinit= in order to specify the ramdisk image (which was already working properly with my config).  I just tried that parameter instead of init= and it worked like a charm!  Thanks for the tip!  Sorry I misunderstood.  :)

Never ever having had a need to use it, I wouldn't have remembered that detail, all I did was looking at the documentation to which you had been referred 19(!!) posts earlier:

The differences are well documented in the kernel docs (initrd.txt, filesystems/ramfs-rootfs-initfamfs.txt)
TC uses initramfs, or a gzipped cpio archive.

and there it is very obvious!