Step 3: install dpkg and apt
We are now ready to start installing packages to the empty image. As said before, we have several chicken and egg problems here:
- Several packages have no dependencies specified, but their installation scripts use commands like 'cp'. They are not yet installed on the new system and they require libc-bin to run. Therefore we will only unpack libc-bin and these other packages and tell dpkg to ignore these dependencies while installing other packages. After we have installed coreutils (which contains 'cp'), we will install libc-bin and friends normally.
- libc6 depends on libgcc1 and libgcc1 depends on libc6. This is easy to solve: we just tell dpkg to ignore this dependency for libgcc1 (which we need to do anyway, because libc6 is only unpacked at this stage).
- raspbian-archive-keyring has an installation script that uses binaries form the apt package and the apt packages requires raspbian-archive-keyring to be installed (both by the package metadata (the 'Depends' tag) and the installation script). So we will do the same trick as before; unpack raspbian-archive-keyring, install apt and ignore the dependency and then install raspbian-archive-keyring normally. And the same trick applies to sensible-utils and debianutils
But let's start at the beginning. We instruct dpkg to install packages. The --root flag indicates that the packages should not be installed to the system root (/), but to chroot to the provided path instead. I already explained what we should do, so let's just give you the commands. Note that the order of installing the packages is imported because they depend on each other. Note that I do NOT supply the full filename of the packages, because I do not know what version you have downloaded. You should complete the filename! Normally you can to this by pressing tab at the end of each line (bash will autocomplete the path you typed):
dpkg --root /target --install /root/packages/gcc-4.7-base
dpkg-deb -x /root/packages/libc-bin /target
dpkg-deb -x /root/packages/libc6 /target
dpkg --ignore-depends libc6 --root /target --install /root/packages/multiarch-support
dpkg --ignore-depends libc6 --root /target --install /root/packages/libgcc1
dpkg --ignore-depends libc6 --root /target --install /root/packages/zlib1g
dpkg --ignore-depends libc6 --root /target --install /root/packages/libbz2-1.0
dpkg --ignore-depends libc6 --root /target --install /root/packages/liblzma5
dpkg-deb -x /root/packages/libselinux1 /target
dpkg-deb -x /root/packages/tar /target
dpkg-deb -x /root/packages/dpkg /target
dpkg --ignore-depends libc6 --root /target --install /root/packages/libattr1
dpkg --ignore-depends libc6 --root /target --install /root/packages/libacl1
dpkg --ignore-depends libc6,libselinux1,dpkg --root /target --install /root/packages/coreutils
dpkg --ignore-depends libc6 --root /target --install /root/packages/libselinux1
dpkg --ignore-depends libc6 --root /target --install /root/packages/tar
dpkg --ignore-depends libc6 --root /target --install /root/packages/dpkg
dpkg --ignore-depends libc6 --root /target --install /root/packages/grep
dpkg --ignore-depends libc6 --root /target --install /root/packages/sed
We have now unpacked libc-bin and libc6 and installed all tools required to normally install these packages. So let's do that:
dpkg --root /target --install /root/packages/libc-bin
dpkg --root /target --install /root/packages/libc6
This means we have now fully installed all packages required to run dpkg. However, we want to install apt (and findutils), so we don't have to download all packages manually anymore. Note that besides listed dependencies, we also install debianutils (and its dependency sensible-utils) because it contains tools needed by one or more installation scripts. Also, I create an empty file which is used by raspbian-archive-keyring. Normally this will probably be created by the installation script, but because at first the packages is not installed, but merely unpacked, the file needs to be created manually.
It should be possible to copy all packages to the image, chroot to /target and install everything with dpkg we just installed. However, except for proving that dpkg is correctly installed, this is quite useless. So let's not and instead continue with how we were doing it before:
dpkg --root /target --install /root/packages/libstdc++6
dpkg --root /target --install /root/packages/libusb-0.1-4
dpkg --root /target --install /root/packages/gpgv
dpkg --root /target --install /root/packages/readline-common
dpkg --root /target --install /root/packages/libtinfo5
dpkg --root /target --install /root/packages/libreadline6
dpkg --root /target --install /root/packages/gnupg
dpkg-deb -x /root/packages/sensible-utils /target
dpkg --ignore-depends sensible-utils --root /target --install /root/packages/debianutils
dpkg --root /target --install /root/packages/sensible-utils
dpkg --root /target --install /root/packages/libapt-pkg4.12
dpkg-deb -x /root/packages/raspbian-archive-keyring /target
dpkg --ignore-depends=raspbian-archive-keyring --root /target --install /root/packages/apt
dpkg --root /target --install /root/packages/raspbian-archive-keyring
dpkg --root /target --install /root/packages/findutils
And now we are almost done. Apt is installed on the image, we just need to configure it to use the right repositories and add the repository keys to the keyring. I prefer to use the default raspbian repository and, for the firmware, the raspberrypi.org repository.
Also, because apt downloads packages from the internet using urls with hostnames, the resolver should be configured so it know where/how to look up hostnames.
If you know how the configuration files work, you can create and edit the files yourself. Alternatively, you could copy the files from the host system:
cp -vi /etc/apt/sources.list /target/etc/apt/sources.list
cp -vi /etc/apt/sources.list.d/raspi.list /target/etc/apt/sources.list.d/raspi.list
cp -vi /etc/resolv.conf /target/etc/resolv.conf
chroot /target apt-key add /root/raspberrypi.gpg.key
If you've set up different repositories (or the default repositories on your host system are different than mine), you might need to copy more or different files to /target/etc/apt/ and/or install more or different keys. If this is the case you should really start using google now to find out how to configure repositories, which repositories to use and where to find their keys and how to install them. Note that you need to install them in de chrooted environment (so, prepend 'chroot /target' in front of 'apt-key'), because else you will install them on your host system instead!
Now you've reached a milestone; apt is installed and configured on your image. From now on, no need to check dependencies and download packages manually any more! I think this was the hardest part.