# [HowTo] gentoo linux on a compact flash card (chroot-build!)

## pi-cubic

Introduction

This HowTo describes how to create a system booting from a Compact Flash (CF) card, but operating (almost only) in the RAM. Because of the limited program-/erase-cycles of a CF card, it is important to reduce these cycles to a minimum. Though, your system should be able to save some configuration-changes in /etc. That's why I decided to put /etc on an extra r/w-partition on the cf-card. Everything else in / is in RAM an lost when the system reboots (!). 

The flexibility of my approach ist the gentoo-chroot behind the scenes. the system is built from a chroot which gives you full control over all packages with portage, easy updating and customization possibilities.

This HowTo also implies that you have an IDE-CF-controller which is accessable via /hdX. Of course, if your card-reader has a different controller, replace /hdX with your card-reader device.

Here's a brief overview about the system-architecture:

1) the CF-card has two partitions: hdc1 (for /boot and root.tgz) and hdc2 (for /etc)

2) the system boots with grub and uses the initrd from /boot

3) in the "pre-boot-enviroment" (initrd), hdc1 (ro) and hdc2 (rw) are mounted to /cf 

4) then the root.tgz tarball is extracted to /new and hdc2 mounted to /new/etc (still in the initrd)

5) pivot_root makes /new to our new root enviroment

6) control is passed to init booting the system

Requirements

You need to have enough space on your system. Depending on what packages you need to include in your CF-system, this will vary. I'd say in average a 4GB free space is fair enough.

You must be familiar with installing Gentoo using a stage1/2 tarball because that's what we're going to use in this mini-HowTo. If you're in doubt, consult the Gentoo Handbook (http://www.gentoo.org/doc/en/handbook/).

Setting up the build environment

Our build environment is a directory we will 'chroot' into and install gentoo. Its contents will make the CF-system later on. I will use the name 'source' for it, and will create it under a directory in my home called 'base'.

```

cd ~

mkdir -p base/source

```

Download a stage1 or stage2 tarball from one of the gentoo mirrors to your home directory. I'm using an x86 stage2. Once downloaded untar it to 'source'. Then create necessary 'oldroot' directory which will be used during initial boot.

```

cd base/source

tar xvjpf ~/stage1-x86-2005.0.tar.bz2 

# or

tar xvjpf ~/stage2-x86-2005.0.tar.bz2 

mkdir oldroot

```

Now, download the latest portage snapshot to your home directory and untar it to your new build directory

```

cd base/source/usr/

tar xvjf ~/portage-whatever.tar.bz2

```

If you need to download packages during the installation, then setup whatever files in 'base/source/etc' required to reach the internet. For example 'resolv.conf'.

Your source directory is now ready to start installating gentoo.

Installing gentoo

Setup necessary mount points before you 'chroot' to your build directory and start installation. On my system I keep 'distfiles' under the default '/usr/portage' directory. I'm going to use it instead of downloading distfiles again during the installation.

```

cd base/source

mount -o bind /proc proc

mkdir usr/portage/distfiles

mount -o bind /usr/portage/distfiles usr/portage/distfiles

```

Now 'chroot' to source and start the installation. Be careful with the modification of your /etc/make.conf, the more USE-flags you put in it, the bigger the system will be. I use a minimalistic set us USE-flags. Here is my example 'make.conf' for a VIA Samuel CPU:

```

######################################

#   /etc/make.conf

######################################

USE="alsa -arts -avi -bitmap-fonts -cdr -cups -dvd -emacs -esd -foomaticdb -gif -gtk -gtk2 -jpeg -gnome -kde -nls -motif -mp3 -mpeg -oggvorbis -opengl -oss perl -pdflib -png -ppds -qt -quicktime samba -spell -truetype -truetype-fonts -type1-fonts -X -xmms"

#from http://radagast.bglug.ca/epia/epia_howto/index.html

# notice the -Os optimization for small binaries!

CFLAGS="-march=i586 -m3dnow -mmmx -Os -pipe -fomit-frame-pointer"

CHOST="i586-pc-linux-gnu"

CXXFLAGS="${CFLAGS}"

GENTOO_MIRRORS="http://ftp.uni-erlangen.de/pub/mirrors/gentoo http://ftp.tu-clausthal.de/pub/linux/gentoo http://gentoo.oregonstate.edu http://www.ibiblio.org/pub/Linux/distributions/gentoo"

MAKEOPTS="-j2"

```

Let's do the installation!

```

cd base/source

chroot . /bin/bash --login

env-update && source /etc/profile

cd /usr/portage; scripts/bootstrap.sh (stage1 only: bootstrap system)

emerge --newuse system                (stage1, stage2 only: install base system)

ln -sf /usr/share/zoneinfo/<path to time zone file> /etc/localtime

emerge syslog-ng vixie-cron hotplug udev

rc-update add syslog-ng default

rc-update add vixie-cron default

rc-update add hotplug default (add also hostname, domainname, net.eth?, etc.)

emerge foo bar baz ... (custom packages)

```

Before we merge the kernel and boot loader, let's modify important files in '/etc'. First, fstab

```

# <fs>                  <mountpoint>    <type>          <opts>                  <dump/pass>

none                    /               tmpfs           defaults                0 0

/dev/hdc2               /etc            ext3            noatime                 0 0

none                    /proc           proc            defaults                0 0

none                    /dev/shm        tmpfs           defaults                0 0

```

Now, modify other '/etc' files as you see fits (e.g. hostname, rc.conf, conf.d/rc for udev, conf.d/*, and so on)

Merge your desired kernel now. I decided to use the 'hardened-dev-sources' since my system will be on the internet and should be armed against evil intruders like 'eve' or 'trudy' :)

When configuring your kernel, make sure the following is compiled in

1. initrd support, set size to 8MB (8192kb)

2. ext2/ext3 filesystem support (which we use for our initrd image and cf-card)

3. tmpfs filesystem support

```

emerge hardened-dev-sources

cd /usr/src/linux

make menuconfig 

make -j? && make modules_install && cp arch/i386/boot/bzImage /boot (? = cpu-count+1)

```

The final step is merging and configuring the boot loader. We're going to use the latest GRUB.

```

echo 'sys-boot/grub ~x86 >> /etc/portage/package.keywords'

emerge grub

```

And here's '/boot/grub/grub.conf'

```

default 0

timeout 5

splashimage=(hd0,0)/boot/grub/splash.xpm.gz

title globalways gentoo linux

        root (hd0,0)

        kernel /boot/bzImage root=/dev/ram0 rw init=/linuxrc 

        initrd /boot/initrd

```

creating the initrd image

This is where most of the action occures during booting. It's a very simple task once you get the hang of it. First create the image, I'm using an 8MB initrd but feel free to expand/reduce that if you need more/less, just remember to set the option in your kernel configuration for the maximum ramdisk size properly.

```

touch /boot/initrd

dd if=/dev/zero of=/boot/initrd bs=1024k count=8

losetup /dev/loop0 /boot/initrd

mke2fs /dev/loop0

mkdir /mnt/initrd

mount /dev/loop0 /mnt/initrd

```

Now populate the image with required directories and files:

```

cd /mnt/initrd

mkdir etc dev lib bin proc new cf

touch linuxrc

chmod +x linuxrc

touch etc/mtab

touch etc/fstab

```

linuxrc is what will get executed when linux boots. More on it below.

Now you need to copy necessary files into bin and lib. For bin, copy the following:

```

/bin/sh

/bin/cat

/bin/mount

/bin/umount

/bin/mkdir

/bin/chroot

/bin/tar

/sbin/pivot_root

/usr/bin/beep

```

For lib, you'll need to find out which lib files are needed by each of the binaries above. After having copied the necessary binaries, do the following:

```

cd /mnt/initrd/bin

ls | xargs ldd | grep '/' | cut -d '(' -f 1 | sort -n | uniq   

cp /lib/libc.so.6 /mnt/initrd/lib/

cp /lib/ld-linux.so.2 /mnt/initrd/lib/

... (do this for all libraries shown)

```

This is just one way (maybe not that nice) to get a list of all libraries you need for your binaries, maybe someone has a better idea? i didn't put much brain in the pipe, probably someone likes to write a tiny script copying the binaries over :)

...and there it is. JeffW makes our lives easier with this sweet line:

```
carter initrd # find /bin -type f | xargs ldd | grep '/lib/' | awk '{print $3}' | sort -n | uniq | xargs -i, cp , /mnt/initrd,

carter initrd # find

.

./cf

./bin

./dev

./etc

./lib

./lib/libm.so.6

./lib/libacl.so.1

./lib/libresolv.so.2

./lib/libcom_err.so.2

./lib/libncurses.so.5

./lib/libe2p.so.2

./lib/libattr.so.1

./lib/libproc.so.3.1.15

./lib/libcrypt.so.1

./lib/ld-linux.so.2

./lib/libdl.so.2

./lib/libuuid.so.1

./lib/libpthread.so.0

./lib/libpam_misc.so.0

./lib/libpam.so.0

./lib/libc.so.6

./lib/librt.so.1

./new

./usr

./usr/lib

./usr/lib/libcrack.so.2

./usr/lib/liblockfile.so.1

./proc

carter initrd # 
```

Now, we need to create necessary devices under dev directory:

```

mknod /mnt/initrd/dev/console c 5 1

mknod /mnt/initrd/dev/null c 1 3 

mknod /mnt/initrd/dev/hda b 3 0

mknod /mnt/initrd/dev/hdb b 3 64

mknod /mnt/initrd/dev/hdc b 22 0

mknod /mnt/initrd/dev/hdc1 b 22 1

mknod /mnt/initrd/dev/hdc2 b 22 2

mknod /mnt/initrd/dev/hdd b 22 64

mknod /mnt/initrd/dev/tty c 4 0

mknod /mnt/initrd/dev/loop0 b 7 0

```

note: use the appropriate device files your card-reader/cf-controller works with. mine detects the card as /dev/hdc, so i created 2 partitions for hdc1 and hdc2. I listed the device-numbers above for you, so you can create your own device-files with mknod (just leave the first number and change the last number to the number of your partition, e.g. hdc1 is ...b 22 1)

Finally, we need to create our linuxrc script. The script will do the follwoing:

1. Save whatever is passed to the kernel to pass it later on to /sbin/init

2. Mount hdc1 (fist partitiong on the CF-card) /cf and extract it to /new. This will become our root filesystem, which is read-only

3. Mount hdc2 to /cf/etc and extract the etc-tarball to /new/etc

4. Finally, pivot the root filesystem on newroot and start the real init process

```

#!/bin/sh

#

# hdc1 = read-only for /boot and root.tar

# hdc2 = read/write for /etc

#

# we need to access the binaries in the initrd

export PATH=/bin

# get kernel CMDLINE

mount -t proc none /proc

CMDLINE=`cat /proc/cmdline`

umount /proc

# mount compact flash device

mount -t ext3 -o ro /dev/hdc1 /cf &> /dev/null 

if [ $? != 0 ]; then

        echo "[ !! ]   couldn't mount root file-system !"

        exec /bin/sh

else 

        echo "[ ok ]   root file-system successfully mounted (ro) !"

fi

# create the tmpfs for / and untar the system into it

mount -t tmpfs -o size=256m none /new &> /dev/null

cd /new 

tar zxpf /cf/root.tgz &> /dev/null

if [ $? != 0 ]; then

        echo "[ !! ]   couldn't untar root file-system !"

        /bin/beep -f 1500 -r 100000 -l 200 -d 1000

else 

        echo "[ ok ]   root file-system successfully untared !"

        /bin/beep -f 1000  -r 3 -l 200 -d 500

fi

# check for an existing /etc (possibly from the root-tarball)

mkdir /new/etc

if [ $? != 0 ]; then

        echo "[ !! ]   /etc already exists, cleaning ...!"

        rm -rf /new/etc/*

else 

        echo "[ ok ]   /etc created !"

fi

# mount writeable /etc in new root-enviroment

mount -t ext3 /dev/hdc2 /new/etc &> /dev/null

if [ $? != 0 ]; then

        echo "[ !! ]   couldn't mount /etc !"

else 

        echo "[ ok ]   /etc mounted (rw) !"

        /bin/beep -f 1000 -l 200 -d 500

fi

# pivot root and start real init

cd /new

pivot_root . oldroot

exec chroot . /bin/sh <<- EOF >dev/console 2>&1

umount /oldroot/cf

umount /oldroot

exec /sbin/init ${CMDLINE}

EOF

```

Notice that I'm using 256 MB tmpfs filesystems. Reduce or expand it if your wish.  I thought of specifying the system-size as boot-parameter in grub, but haven't realized this idea yet.

Our source directory is ready. Exit 'chroot' and unmount proc and distfiles (and maybe some customized binds). 

Building the CF-system

Building the CF-system invloves the follwoing steps:

1. Clean up unnecessary directories in source (like /tmp and /var/tmp)

2. Create the target directory that will contain the files on the CF-card

3. call `geninc` to generate our included files (includes.lst) in our root-tarball

4. create the file-system-tarballs for each CF-partition

To help automate these steps, create a simple 'build' script inside 'base'

```

cd base

touch build

chmod +x build

```

And here's the script:

```

#!/bin/bash

INCLUDES='../includes.lst'

# prepare the source-tree

rm -rf source/var/tmp/*

rm -rf source/var/run/*

rm -rf source/var/lock/*

rm -rf source/tmp/*

rm -f source/etc/mtab 

touch source/etc/mtab

# copy /boot and /etc 

rm -rf target 

mkdir target

cp -a source/boot target/

cp -a source/etc target/

# generate the file list

echo "[ >> ]   generating include-list..."

./geninc

# create the rootFS

cd source/

echo "[ >> ]   building root.tgz..."

tar czpf ../target/root.tgz -T $INCLUDES #&> /dev/null

cd ../target

echo "[ >> ]   building exportable tarballs..."

tar cpf ../last-boot.tar boot root.tgz && echo "[ ok ]   /boot & root.tgz built!" 

cd etc

tar cpf ../../last-etc.tar * && echo "[ ok ]   /etc built!" 

```

this script invokes another script called geninc which generates the list of the files which will be included in our system. geninc generates our 'includes.lst' which is used by the tar. you might now think "what the...", but i'll explain my idea :). the idea behind this is to have script generating an include-list with all files, so you don't have to add every needed library by hand in the include-file (e.g. notice the find-command). with the geninc-approach, you have a 'meta-include-file-generator' making the include.lst on the fly when you ./build your system! here is my geninc-file:

```

#!/bin/bash

SOURCETEE='./source'

INC='includes.lst'

############################

# populating root

#

cat << EOF > $INC

bin

dev

home

lib

mnt

oldroot

opt

proc

root

sbin

sys

tmp

EOF

############################

# populating var

#

cat << EOF > $INC

var/cache

var/empty

var/lib

var/lock

var/log

var/mail

var/run

var/spool

var/state

var/tmp

EOF

############################

# populating usr/lib (aka the big guy)

#

# basic libraries

find ${SOURCETREE}/usr/lib -maxdepth 1 -iname '*.so*' >> $INC

# special stuff

find ${SOURCETREE}/usr/lib -iname 'libstdc++.so*' >> $INC

cat << EOF >> $INC

usr/lib/groff

usr/lib/gcc-config

usr/lib/gentoolkit

usr/lib/perl5

usr/lib/pkgconfig

usr/lib/portage

usr/lib/pppd

usr/lib/quagga

usr/lib/tc

EOF

############################

# rest of /usr (what is really necessary?)

cat << EOF >> $INC

usr/bin

usr/i586-pc-linux-gnu

usr/libexec

usr/local

usr/man

usr/sbin

usr/share/consolefonts

usr/share/keymaps

usr/share/misc/file/magic

usr/share/nmap

usr/share/zoneinfo/Europe/Berlin

usr/tmp

EOF

# possible candidates ?!

# -------------------

# usr/lib/hotplug

# usr/lib/binutils

# usr/lib/gconv

# usr/lib/glib

# usr/lib/grub

# usr/share/cracklib

# usr/share/gettext

```

warning: i haven't played much with the selection of libraries and binaries and how the behave in harmony. this part is up to you. include what you want depending on how much ram you have!

After executing the build-script, you will have to new files in your current directory:

last-boot.tar

last-etc.tar

these 2 files represent your 2 partitions on your compact flash device. the first is extracted to hdc1 and the second to hdc2.

here is a sample script for deploying the system on a CF-card:

```

#!/bin/bash

#

#  this script deploys the latest tarball of the cf-system

#  it should be started from the machine with the cf-card!

#

BOOT='/base/last-boot.tar'

ETC='/base/last-etc.tar'

BOOT_MOUNT='/mnt/base/boot'

ETC_MOUNT='/mnt/base/etc'

# mounting the devices

echo "[ >> ]   creating and mounting the partitions..."

mke2fs /dev/hdc1 

tune2fs -j -i 0 -c 0 /dev/hdc1

mke2fs /dev/hdc2 

tune2fs -j -i 0 -c 0 /dev/hdc2

mount /dev/hdc1 ${BOOT_MOUNT}

mount /dev/hdc2 ${ETC_MOUNT}

# extracting the tarballs

echo "[ >> ]   extracting the tarballs..."

tar xpf ${BOOT} -C ${BOOT_MOUNT}

tar xpf ${ETC} -C ${ETC_MOUNT}

# install grub on hdc1

grub-install --root-directory=${BOOT_MOUNT} /dev/hdc

# unmounting the devices

echo "[ >> ]   unmounting the devices..."

umount ${BOOT_MOUNT}

umount ${ETC_MOUNT}

# say something ;)

if [ $? != 0 ]; then

        echo "[ !! ]   an error occured while deploying the system !"

else 

        echo "[ ok ]   system deployed !"

fi

```

I use 256MB RAM on my CF-system, so i need to reduce the system-size to a minimum. the more RAM you have the less you have to care about the size of your root-filesystem in the RAM. 

I use a simple script to chroot to my build source each time I need to sync portage, merge new packages, customize configuration files. I called it 'work'.

```

cd base

touch work

chmod +x work

```

and the work-script:

```

#!/bin/bash

mount -o bind /proc source/proc

mount -o bind /sys source/sys

#mount -o bind /dev source/dev

#mount -o bind /dev/pts source/dev/pts

mount -o bind /usr/portage/distfiles source/usr/portage/distfiles

chroot source/ /bin/bash --login

umount source/proc

umount source/sys

#umount source/dev/pts

#umount source/dev

umount source/usr/portage/distfiles

```

Mounting /dev is important to get things like X to work from a chroot environment. Depends on the purpose of your system, I don't need it.

Troubleshooting

If booting the CF fails at some point during linuxrc script execution, you can always change your grub line to 'init=/bin/sh' instead of linuxrc. This will give you a nice little shell inside the initrd image at boot time. From there you can type the commands in the linuxrc script manually and try to find out with one is failing and why.

Thanks

Actually you shouldn't thank me, but rather veezi who allowed me to copy the scaffold for this HowTo from is own LiveCD-HowTo.

I only copied all his work and modified some essential parts, because I love his chroot-concept. Comments are expressly desired!

Please help me to make this HowTo more robust, i just collected my thoughts during the development of the system, so some steps might miss or seem unclear. your feedback will improve this HowTo and will make it easy reproducable for everyone !!Last edited by pi-cubic on Fri Aug 05, 2005 1:32 pm; edited 2 times in total

----------

## nife

I really like this idea, I don't think I can use it since I can't afford a card big enough right now, but I just wanted to say that this HOWTO is very very well written.  And sounds like great work.  I might use this to see if I can get a similar thing going with a usb drive that I have.  Thanks

----------

## pi-cubic

i use a CF-card from Kingston with 128 MB. the system size is currently around the half. your card doesn't need to be big! you can even strip down the system to 30 MB, but i am a lazy guy  :Smile: . just modify the geninc script to define what will be included in your system.

----------

## firestrike

Great tutorial and exactly what I needed! Thanks for that  :Smile: 

but I've encountered two problems:

when linuxrc tries to umount oldroot/cf and oldroot I get a segmentation fault. It seems to umount it though. Do you have the same problem?

And on a reboot the init script stops at "can't find /etc/init.d/reboot.sh" and thus does not reboot. Do you have a solution for that? I want to administrate this pc remotely, but it is not good if I always have to drive there for a reboot  :Smile: 

I made 3 small changes in your geninc script:

```

[....snip....]

cat << EOF >> $INC

[....snip....]

cd ${SOURCETREE}

find usr/lib -maxdepth 1 -iname '*.so*' >> ../$INC

cd ..

# special stuff

cd ${SOURCETREE}

find usr/lib -iname 'libstdc++.so*' >> ../$INC

cd ..

[....snip....]

```

----------

## pi-cubic

 *Quote:*   

> Great tutorial and exactly what I needed! Thanks for that 

 

i appreciate you like it, keep on testing! 

 *Quote:*   

> when linuxrc tries to umount oldroot/cf and oldroot I get a segmentation fault. It seems to umount it though. Do you have the same problem?

 

yes, i do have the same problem, haven't solved it though...as you said, the umount works  :Smile: 

 *Quote:*   

> And on a reboot the init script stops at "can't find /etc/init.d/reboot.sh" and thus does not reboot. Do you have a solution for that? I want to administrate this pc remotely, but it is not good if I always have to drive there for a reboot 

 

yes, i took me a while to find the solution for this problem. since /etc isn't mounted any more when reboot should take place, you have to customize the following (excerpt from my changelog):

----------------------------

changes to the gentoo-files:

----------------------------

* proper reboot & shutdown:     /sbin/rc:671

* no fsck.error on boot:        /etc/init.d/checkroot:28

/sbin/rc looks in the specified range like this:

```
ource /etc/init.d/halt.sh

    if [ "${SOFTLEVEL}" = "reboot" ]

    then

        source /etc/init.d/reboot.sh

    else

        source /etc/init.d/shutdown.sh

    fi

```

hope this helps you!

bye,

pi

----------

## preacher

Great howto, thanks a lot!

I'm thinking about using this approach for my coming Epia-based frontend to mythtv to get a small, fast and silent machine.

However I'm not sure how much space I'm gonna need on the card and for RAM. I was thinking going for a 256mb flash and 1 gb of RAM just to be sure I have enough. Could I "go cheap" and step down to 128mb for the flash and 512mb RAM?

Mythtv needs X and QT, which takes some space. Could the system be stripped down enough to fit?

Thanks again.

----------

## pi-cubic

 *preacher wrote:*   

> 
> 
> However I'm not sure how much space I'm gonna need on the card and for RAM. I was thinking going for a 256mb flash and 1 gb of RAM just to be sure I have enough. Could I "go cheap" and step down to 128mb for the flash and 512mb RAM?
> 
> Thanks again.

 

our system fits perfectly on a 256 MB RAM and 256 MB CF. we still have 128 MB RAM 'left' as RAM, so i think you definitively could "go cheap"...

----------

## metalfan

i got one of these via nehemia boards, mII1200....is the cf slot able to read and write the card?

greets

metalfan

----------

## TheDauthi

I like this.  It's conceptually similar to something I'm working on right now that uses perl and a set of config files to build the disk.  One of the main points of difference being that my ldd for the library listing and linking is a lot uglier.  I'm currently working on a clean way to remove perl, python and gcc from the build directory when they're not in use.

One thing that is working well for me, anyway, is to rebind the entire /usr/portage directory, so I don't have to sync inside the build enviroment, as if I were sharing it over NFS.  No one else seems to do that, so I assume that it's broken in some way that I haven't found yet.  Another has been to use a ramdisk for the /var/tmp/portage directory.

----------

## pi-cubic

 *TheDauthi wrote:*   

>  I'm currently working on a clean way to remove perl, python and gcc from the build directory when they're not in use.

 

perl has a nice use flag called "minimal", you might be interested in it.

 *Quote:*   

> 
> 
> One thing that is working well for me, anyway, is to rebind the entire /usr/portage directory, so I don't have to sync inside the build enviroment, as if I were sharing it over NFS.

 

don't forget to 'emerge --metadata' since you only mount the /usr/portage directory and don't update the portage-cache at the same time!

----------

## Root Moose

 *metalfan wrote:*   

> i got one of these via nehemia boards, mII1200....is the cf slot able to read and write the card?
> 
> greets
> 
> metalfan

 

Yes, but you cannot boot from that card.

----------

## TheDauthi

 *pi-cubiq wrote:*   

>  *TheDauthi wrote:*    I'm currently working on a clean way to remove perl, python and gcc from the build directory when they're not in use. 
> 
> perl has a nice use flag called "minimal", you might be interested in it.
> 
> 

 

Yes, I've tried it, but it doesn't (didn't) build the Data::Dumper module, which something in the base install complained about if I didn't build.  Silly: that's not really a module you'd expect an app to need to build.  I should probably look at that, too.  Of course, I could just grab that from CPAN, but I thought a generic 'remove-perl' script would be more useful for the case that it's not needed for the boot, at all.

 *pi-cubiq wrote:*   

>  *TheDauthi wrote:*   
> 
> One thing that is working well for me, anyway, is to rebind the entire /usr/portage directory, so I don't have to sync inside the build enviroment, as if I were sharing it over NFS. 
> 
> don't forget to 'emerge --metadata' since you only mount the /usr/portage directory and don't update the portage-cache at the same time!

 

Hmm.  Didn't think about the metadata, but isn't that stored in /usr/portage/metadata/?

----------

## metalfan

Root Moose: a driver issue or is it in generell not meant to be bootable?

greets

metalfan

----------

## Root Moose

 *metalfan wrote:*   

> Root Moose: a driver issue or is it in generell not meant to be bootable?

 

Not meant to be bootable.

There wa s rumour that VIA planned to release a BIOS rev to make it bootable but it never happened.

----------

## metalfan

well, maybe bootcds arent that bad  :Wink: 

greets

metalfan

----------

## Root Moose

 *metalfan wrote:*   

> well, maybe bootcds arent that bad 

 

Get one of those CF-2-IDE converter dongles and make it a device on chain 0 right on the built-in IDE bus. Those dongles can't be much more than ~Eu15 I would guess - that is how much they are in Can/US $.

----------

## preacher

I've followed the guide to get a system and trying to deploy it on a CF-card, but having some troubles with the grub-install.

You see, I'm trying to deploy it onto a card-reader attached to the computer I used to build the system, and thereafter moving the CF-card to the IDE-dongle.

Just using: 

```
grub-install --root-directory=${BOOT_MOUNT} /dev/sde
```

 won't work, since grub complains that there is no corresponding bios-drive.

If I run it with: 

```
grub-install --root-directory=${BOOT_MOUNT} --recheck --no-floppy /dev/sde
```

 it finds my reader as (hd3) and /dev/sde, and says it completed successfully.

But on boot grub is horribly slow on appearing, and never boots correctly even if I wait.

Could this be because my CF is now (hd0) and /dev/hda, instead of /dev/sde?

Even though I of course configured grub.conf to use (hd0,0) and /dev/hda ?

----------

## mci_nano

 *preacher wrote:*   

> I've followed the guide to get a system and trying to deploy it on a CF-card, but having some troubles with the grub-install.
> 
> You see, I'm trying to deploy it onto a card-reader attached to the computer I used to build the system, and thereafter moving the CF-card to the IDE-dongle.
> 
> Just using: 
> ...

 

I think this will help you.

I'm trying to build a qemu image to try the build in a vm. So i had to install grub into the image and i got the same bios-device error. I asked qemu geeks from IRC and here is my solution:

```
# start grub

grub

# promote the "fake" device

grub> device (hd0) /path/to/image

device (hd0) /path/to/image

grub> root (hd0,0)  

root (hd0,0)

 Filesystem type is ext2fs, partition type 0x83

grub> setup (hd0)

setup (hd0)

 Checking if "/boot/grub/stage1" exists... yes

 Checking if "/boot/grub/stage2" exists... yes

 Checking if "/boot/grub/e2fs_stage1_5" exists... yes

 Running "embed /boot/grub/e2fs_stage1_5 (hd0)"...  15 sectors are embedded.

succeeded

 Running "install /boot/grub/stage1 (hd0) (hd0)1+15 p (hd0,0)/boot/grub/stage2 /boot/grub/menu.lst"... succeeded

Done.

grub> quit

quit
```

My problem actualy is that the linux stops with a kernel panic at boot time... it says it woun't find a /linuxrc wether /bin/sh as init option... any suggiestion?

----------

## preacher

Thanks, I´ve read about the device-command but haven´t had time to try it out, will do. Was your grub also very very slow?

About not being able to load either linuxrc nor /bin/sh, I had that problem too. Did you follow this guide?

My problem was that not all libraries needed were being detected by the script from JeffW.

I used the original command:

```

cd /mnt/initrd/bin

ls | xargs ldd | grep '/' | cut -d '(' -f 1 | sort -n | uniq   

cp /lib/libc.so.6 /mnt/initrd/lib/

cp /lib/ld-linux.so.2 /mnt/initrd/lib/

... (do this for all libraries shown) 

```

Which found one more library, ld-linux.so-something (I´m not able to check it now, sorry).

A good way to make sure your initrd will work before rebooting is just mounting it with -o loop, and chroot to that diretory (chroot /mnt/initrd /bin/sh). Are you able to run /bin/sh? If so, you should be fine.

Good luck!

----------

## mci_nano

 *preacher wrote:*   

> Thanks, I´ve read about the device-command but haven´t had time to try it out, will do. Was your grub also very very slow?
> 
> 

 

No it wasnt. I only wanst able to install grub on a image.

 *preacher wrote:*   

> 
> 
> About not being able to load either linuxrc nor /bin/sh, I had that problem too. Did you follow this guide?
> 
> My problem was that not all libraries needed were being detected by the script from JeffW.
> ...

 

Thats it... thx, you made my day.

There is a lib that wount get recognizes by the awk command, because its not a link like the others...

```

DRevil bin # ls | xargs ldd | grep '/' | cut -d '(' -f 1 | sort -n | uniq 

        libblkid.so.1 => /lib/libblkid.so.1 

        libc.so.6 => /lib/libc.so.6 

        libdl.so.2 => /lib/libdl.so.2 

        /lib/ld-linux.so.2 

        libncurses.so.5 => /lib/libncurses.so.5 

        libpthread.so.0 => /lib/libpthread.so.0 

        librt.so.1 => /lib/librt.so.1 

        libuuid.so.1 => /lib/libuuid.so.1

```

Thx to you... Now I can step forward to the next problem  :Wink: 

----------

## mrdevis

Great, the missing lib finally got me to find out why I could not get his past the point of not being able to read from linuxrc...

Quoting mci_nano: getting on to the next problem... This is where I got quite soon: the script wouldn't mount the root file-system...

Also if I try to mount it manually, I get some remarks about /dev/hda1 not being a valid block device. 

The CF card is prepared in my laptop, being /dev/hdc1&2, then put into an cf_ide socket, and booted on an epia board. It boots allright, but just up to this point mentioned..

Any ideas??

Cheers, Jeroen

----------

## mci_nano

 *mrdevis wrote:*   

> 
> 
> Also if I try to mount it manually, I get some remarks about /dev/hda1 not being a valid block device. 

 

what nodes did you create? show us a ls -al of your /dev/hd* nodes. maybe you did wrong node creation in initrd?

if this is the case maybe you wish to have a look at Documentation/devices.txt of your kernel sources.

----------

## mrdevis

Hi,

Thanks for reacting, here is the devnode list. As the cf card is mounted on ide0 and 

is seen (it boots) I suppose this should work, unless I miss something trivial (apparently  :Smile: ). 

crw-r--r-- 1 root root  5,  1 Jan 27 17:35 console

brw-r--r-- 1 root root  3,  0 Jan 27 17:35 hda

brw-r--r-- 1 root root  3,  1 Jan 27 17:35 hda1

brw-r--r-- 1 root root  3,  2 Jan 27 17:35 hda2

brw-r--r-- 1 root root  3, 64 Jan 27 17:35 hdb

brw-r--r-- 1 root root 22, 64 Jan 27 17:35 hdd

brw-r--r-- 1 root root  7,  0 Jan 27 17:35 loop0

crw-r--r-- 1 root root  1,  3 Jan 27 17:35 null

crw-r--r-- 1 root root  4,  0 Jan 27 17:35 tty

hdb and hdd are not used (well at least not until now...)

Did I read somewhere that dma mode is not supported for CF cards on an ide adapter??

Cheers, Jeroen

----------

## mci_nano

Of course you missing hdc but if you never use it, thats nothing to worry about.

I dont realy get it... You have CF card mounted on your laptop as hdc* and at the destination computer it should be hda*... are you sure about this?

did you get the correct ide driver into your kernel?

maybe it would help too post some more information.

and check for the drivers

----------

## mrdevis

dooh, tx for the tip, I had the wrong driver in the kernel. Working like a charm now!

Yes, hdc in the host, now driving a Epia Nano Itx as a solid state board, as hda1&2.

Now what shall I use this for...

Cheers, and tx again,

Jeroen

----------

## preacher

Ok, I managed to get grub working (see my earlier post). The problem was in the bios, once I disabled the SATA-controller it worked like a charm. I will try some different SATA-settings to see if I can't get it to work with both IDE and SATA, but that's a later problem.

My problem right now is that I feel that the boot is too slow! What takes a lot of time (over one minute) is deploying boot.tgz to the CF-card.

Compressed, my image is 97mb which I feel is pretty good since it houses a mythtv-install complete with some emulators and other stuff.

What, if anything, can I do to decrease this bootup-time? I think I got my system pretty trimmed down to size already.

My CF-card is TwinMOS Compact Flash Card 512MB, 140X, Type I, Ultra-X, 16.2/21MB Write/read

----------

## mrdevis

Hi, while I got the card booting fine with this method, I ran into a problem with alsa sound. 

As alsaconf detects the built in card allright (I think: it detects an via82xx, where the nano-itx board documentation 

says it has put a VIA VT1617A 6 channel AC'97 on it)  it gives an

*updating modules.dep ...

FATAL: Could not open '/System.map': No such file or directory

but loads the driver afterwards without a problem..

If I want to open alsamixer I get a:

 "ALSA lib control.c:910:(snd_ctl_open_failed for default: No such file or directory)"

I'd be very happy with some help,

Thanks, Jeroen

----------

## awhisp

Hello.  

When I tried this,  I got to the part where you make 'build' and 'geninc'.  When I attempted to issue build, I get this error:

linuxlaptop base # ./build

[ >> ]   generating include-list...

[ >> ]   building root.tgz...

./build: line 26: 28691 Segmentation fault      tar czpf ../target/root.tgz -T $INCLUDES

[ >> ]   building exportable tarballs...

tar: root.tgz: Cannot stat: No such file or directory

tar: Error exit delayed from previous errors

[ ok ]   /etc built!

Any clue as to what I may have done wrong to cause this? I tried going back through the steps and still had no clue.

----------

## mrdevis

Ok, found the trouble, apparently alsa needs /usr/share/alsa with a couple files in them (alsa.conf etc). With these included in the image, I can easily start alsamixer etc. A very low level sound is leaving the sound card though. There seems to be some coherence with some soft like orpheus playing, (there is a difference between it playing and not playing on headphones), but I didn-t manage to get some meaningful sound out of the onboard soundchip.

Luckily I had a M-Audio USB Quattro lying around, and was able to get sound out of that! A sound producing mobo without moving parts. I like it!!

Anybody any experience with sound chips (via82xx) on a Nano Itx board??

Cheers, Jeroen

----------

## denudar

I've read this thread with much interest because it seems to be the best solution for me.

I will try to do what is says.. I need a minimal linux system capable of running a python app, made with pygame.

I tried using puppy linux, a very strange distro but with some great ideas on compacting things up, it didn't work for me, it seems that pup is allergic to snakes  :Very Happy: .

So now i have to build a custom/uClib gentoo with X, python, and pygame... (+psycho?) and a little room for my app. (not much).. and it needs to be done fast, really fast.

The SBC guest for this os is an ARBOR EmCORE n-511. with about 160 RAM and a 128MB CF.

Is this possible?

Could somebody give me a little help on this matter or an estimation of the final size with the things I mentioned before installed?

 I thank you nice people in anticipation  :Smile: 

----------

## hoyanf

I was wondering why cant we just emerge baselayout and busybox to it ??

Can we do this :-

USE="-* make-symlinks" \

 FEATURES="nodoc noinfo noman" \

 CFLAGS="-Os -march=i586 -fomit-frame-pointer -pipe" \

 CXXFLAGS="-Os -march=i586 -fomit-frame-pointer -pipe" \

 ROOT="/mnt/initrd" \

 emerge baselayout busybox --nodeps

rm -fr var/lib/portage var/cache/edb /var/db/pkg

Using only mere 1.6M

Can it be used ??

Thanks

----------

## KShots

Hi! I just found this today, and I'm trying to do something similar. In my case, my kernel won't find my CF card until the root FS is mounted... but the root FS is on my CF card. I can get an operable system by network booting (and then I can see my CF card), but I can't go straight from the kernel to the root. A bit of this is covered in this other thread.

In my case, I have a 20 MB IDE flash module on /dev/hda1 (for booting purposes), and my CF card's root partition is on /dev/hde3. I have /dev/hde1 set up as a 1G swap partition for hibernation purposes (not to be used as standard swap), and a 512M swap partition for similar on my video card (though I'm not sure that video hibernation is supportable). The kernel loads fine, and I have an initrd that begins working... but /dev/hde doesn't exist. If I network boot with a different root partition (same kernel), /dev/hde exists again. Not sure what the issue here is...  :Sad: 

Also, have you considered doing a unionfs rather than moving a whole image to tmpfs? You can keep /etc writable, then union mount the rest on tmpfs. That way, all reads will be from flash rather than RAM, and writes will go to RAM (and can be read back). Doesn't use up all your RAM either. I'm looking at a similar setup for my system.

----------

## korvend

I'm also very interested in this subject. I have a low power 45W Sempron EE 1100 with two 500 Gb HD and a CF reader with the corresponding CF card (Sandisk with 22 m/s speed   :Laughing:  )  and I'm trying to use it in this manner, a little striped - only binary - gentoo squashfs root on the CF with the corresponding extlinux or syslinux to boot. The system will boot from the CF to a ramdisk and then use the hard disks as a storage medium, like a NAS with RAID. I'm trying a scratch build now, but I've read about GNAP and catalyst too.(In fact I have a liveCF-stage1.spec and liveCF-stage2.spec file that generate a liveCF-amd64.iso), but I want to learn how-to do it on my way.   :Wink: 

I'm not very sure about how-to set boot parameters to the kernel I've compiled, has anyone tried something similar? or booting from a usb pendrive? I say this because I'm missing something. If the root fs is on the USB or CF, how does the kernel mount it?... I'm thinking of some rootdelay=20... but I'm not sure... ¿any suggestion? tonight I'm going to try the rootdelay stuff...

Sorry my poor english from Barcelona

----------

## Ulrar

Hi !

I'm very interesting by this !

Oh, sorry for my English, I'm French ^^ .

I have a via EPIA pico ITX motherboard, and a CF -> IDE adapter.

I followed this tutorial and all steps are OK.

But now, i put my CF on adapter, booting ...

"NO SYSTEM DISK FOUND. INSERT A SYSTEM DISK AND PRESS ENTER".

Grub install problem ?

I just replace hdc by sdb in scripts, and the cart have all install on.

Don't understand where is the problem  :Sad:  .

Anyone can help me ?

PS : three weeks ago, i've tried to install, on an other CF a gentoo with the graphic installer on the livecd.

It work but grub was veryyyyyyy slowwwwwwwww.

After this, i try with a CF hight speed, but livecd don't detect it.

But the BIOS detect a SONY CF with no problem.

Thanks for possible helper !

EDIT :

i think is a grub install problem, so, i tried :

grub-install --root-directory=/mnt/base/boot /dev/sdb

and it say :

/sbin/grub-install: line 355:  2289 Floating point exception$grub_shell --batch $no_floppy --device-map=$device_map  > $log_file <<EOF

quit

EOF

sed: can't read /mnt/base/boot/boot/grub/device.map: No such file or directory

grep: /mnt/base/boot/boot/grub/device.map: No such file or directory

/dev/sdb does not have any corresponding BIOS drive.

----------

## thegid

Hi

Hope some folks are still active on this thread.

This guide has been very helpful to me.  I'm a newbie on setting up embedded linux systems, and its gotten me far....but not quite all the way.

I'm having problems with /sbin/init.  

I've got a gentoo 2007.0 distribution, installed OK on the intel MB, running out of sata harddrive.  I have a 64MB flash basically booting (split as two 32MB partitions.  The kernel comes up, and hands off to the /linuxrc script OK. 

In the linuxrc script I've modified it a bit, so I can check the environment before it crashes.

I've modified it so that after the cd /new, I just drop to the /bin/sh, so I can ls, cd etc.

....

# pivot root and start real init 

cd /new 

pivot_root . oldroot 

exec chroot . /bin/sh <<- EOF >dev/console 2>&1 

umount /oldroot/cf 

umount /oldroot 

exec /sbin/init ${CMDLINE} 

EOF 

.....

after I checked to make sure bin & sbin & etc looks fine, I did the rest of the commands manually.

At first I got a bunch of "agetty" issues (respawing too fast).  I went ahead and modified the /etc/iniitab to comment out the tty1...tty6 configurations.  This helped, and now I get further.

The init script gives me the following message:

INIT: version 2.86 booting

INIT: cannot execute "/sbin/rc"

INIT: cannot execute "/sbin/rc"

INIT: Entering runlevel: 3

INIT: cannot execute "/sbin/rc"

INIT: no more processes left at this runlevel

then the system just sits there.   

I did a bunch of searching on the Internet, but couldnt find any reference that seems relevant. Hopefull one you you all has faced this during your trials and tribulations.

PLEASE HELP...I'm at my wits end.

Thanks in advance....

TheGid

I've followed the guide to the point

----------

## jamapii

 *Quote:*   

> EDIT :
> 
> i think is a grub install problem, so, i tried :
> 
> grub-install --root-directory=/mnt/base/boot /dev/sdb
> ...

 

I guess grub is miscompiled or not adapted to the CPU. The grub ebuild doesn't use CFLAGS, and some VIA CPUs aren't completely i686 and need -march=c3 or something like that. You can try the USE flag "custom-cflags".

You can also try to reinstall with CHOST="i386-pc-linux-gnu".

Please be aware that my diagnosis may be wrong, and the solutions may not work and be a waste of time.

----------

## jamapii

 *thegid wrote:*   

> 
> 
> INIT: version 2.86 booting
> 
> INIT: cannot execute "/sbin/rc"
> ...

 

the next step is to find out what's wrong with /sbin/rc, is it missing, not executable, what does it do?

```
ls -l /sbin/rc
```

----------

## thegid

Thanks jamapii for your response.

I've gotten a lot further now....As I recall the previous issue was related to a /lib file.  I can't quite recall what it was at this time.  Anyhow I've got the flash booting now and logging in.

The new problem I have is with getting network services up. Basically once the flash give the login prompt, and I type in the user & password, everything looks fine, except that net.eth0 hasn't run.

If I manually type in "/etc/runlevels/boot/net.eth0 start" it brings up eth0 and assigns it the right static ip address and everything.  

If I add the above line to the bashrc file at /etc/bash/bashrc, it brings up the ethernet interface when I log in.

What I need is that even if I haven't logged in at the embedded box, the network is up so I can do a remote login from the network to work with the equipment.

I also need various processes starting up so the equipment can continue operation even though I haven't logged in.

Hope someone can shed some light.

Thanks.... theGid

----------

## jamapii

 *thegid wrote:*   

> ...
> 
> I also need various processes starting up so the equipment can continue operation even though I haven't logged in.

 

It looks like the boot runlevel is not coming up correctly, the default runlevel not at all I guess. I didn't read about the details of how to eliminate CF card writes, maybe it's a side effect.

I think /etc/inittab should point a way into the boot scripts, then you can find a place for the commands to run your services.

I'm just setting up a CF card based box with a standard gentoo, no special tweaks, no swap, tmpfs where possible, see also from my /etc/conf.d/rc

```
svcmount="yes"

svcfstype="tmpfs"

```

rsyslog logs to another box, but I don't try to eliminate writes completely.

----------

## MageSlayer

Quite interesting HOWTO.

But I have a question - what if I want to "build" flash system, using (copying) my current system files and not building (using gcc and others) anything?

AFAIK, emerge and paludis know very well where the emerged/built files are, so why rebuilding? Just make a list of packages needed and query your package manager to give you the list files. I think plain bash script will be doing well.

Am I right? Are there any difficulties with this approach? Can "host machine" use-flags be a stopping issue?

Do we have any profiles to building on gentoo? 

make.conf is global, so I'd like to have to "local" build profiles.

P.S. You see I'm not trying to get the least size possible, but to be enable to build customized live-cd as quickly as possible.

Thanks.

----------

## thegid

jamapii et. al.

I was able to get the eth0 initializing up by modifying the /etc/bash/bashrc file and adding the "/etc/runlevels/default/net.eth0 start" command in the script.

Now it gets ethernet up and running ok, but unfortunately only once I log in.

I'd like to use it for remote work, and simply just turn on the machine and then log in from another machine remotely.  So unfortunateily I need the box to comeup by default as soon as you power it up (ie boot level).  I've got the net.eth0 file in the /etc/runlevels/boot directory (softlink), but it doesn't start it up during a bootup.   

When I go to check my runlevel it comes back with "unknown".  If I type in "telinit 3" it seems to take it and doesn't give me a message, but the runlevel still remains at "unknown".  If I type in "telinit 5" it comes back with "INIT: Switching to Runlevel: 5".  If I type in runlevel, it still gives me "unknown".

For some reason is looks like it doesn't run the scripts in the /etc/runlevels/boot or .../default directories.

Everything else seems to be working fine.  Anybody have any ideas on how I can chase this ?

Thanks for your time and help.....

...TheGid

----------

## jamapii

Looks weird, your default runlevel doesn't seem to come up.

What's in your /etc/inittab?

As a workaround, if all else fails, you can put all the services you need in the boot runlevel.

----------

