The organization of the BBC's contents -------------------------------------- Version 0.339 (for BBC 1.618) by Seth Schoen Introduction ------------ This is intended to be useful to you if you want to understand or modify the LNX-BBC Bootable Business Card -- for example, to create an updated or custom version. If you just want to use the BBC as it exists, without trying to customize it or develop your own bootable CD, then this document is not intended for you. Someone soon will write a document on "How to use the BBC" (the text version of CREDITS-README.txt is the best current approximation); we would welcome contributions of documentation by BBC users. It is my intention to produce an "Illustrious Compendium of BBC Lore" document which explains obscure facts about individual pieces of the system and about the configuration of software included here. That will take longer and has not even been begun yet. I hope that this file is useful in the meantime for would-be BBC modifiers and contributors. Modifying the BBC ----------------- We should note that there is no single unified source tree for the BBC (unfortunately). Of course, we will provide source code for any component of the BBC -- upstream maintainers' sources, and our modifications, if we have made any. However, current BBC development proceeds by having a binary tree into which packages are copied after they are compiled. This is the "preferred form" for BBC development as a whole (from the point of view of the GNU GPL's legal language, not from the point of view of engineering). That is to say that, if you want to modify the BBC, the binary tree (not like a "binary tree" in computer science, just a directory tree full of binary executables) is the most useful thing for you to have. One interesting consequence of this is that you can test a lot of things on the BBC using the chroot(8) command: chroot /cloop /bin/sh -i where "/cloop" is the path to the cloop tree on your development system. This doesn't provide an _exact_ facsimile of the BBC run-time environment (for example, all of /dev is missing, as is /proc, and /etc will be different from the run-time version!), but it will be pretty close. Beware of possible differences. Unfortunately, you generally can't compile inside of the BBC environment; you'll have to compile things outside and then copy them into the BBC tree -- making sure that you link against dynamic libraries which are the same as or compatible with those included in your BBC tree's /usr/lib. CD layout --------- Key: "DEV" means where something exists in our development environment; our "loopback mounts" are standard configurations by which a filesystem can be loopback mounted if we need to access or change its contents (but these mounts are not performed by default in the development environment). "BOOT" describes the location or function of something when the Bootable Business Card is actually booted on a system. Our development environment has a "/mnt/loop1" directory where lnx.img is mounted, and a "/mnt/loop2" where root.bin is mounted. There is a script to mount these two files and a script to unmount them. (Doing that is not quite trivial because the "real" root.bin is actually a gzipped file _inside of_ lnx.img -- as you can see below. Therefore, we need to mount /mnt/loop1, decompress root.bin.gz, save the resulting root.bin somewhere, and then loopback mount it on /mnt/loop2. When we're all done, we need to unmount /mnt/loop2, compress root.bin to get a new root.bin.gz, copy that into /mnt/loop1, and then unmount /mnt/loop1.) Here's how the CD is laid out: CD-R \_ iso9660 fs ("lnx-n.iso") -- DEV: contents of "/cdrom"; BOOT: mounted as /mnt/cdrom-real \_ El Torito boot image ("lnx.img") \_ msdos filesystem -- DEV: contents of lnx.img loopback mount; BOOT: El Torito-compliant BIOS boots and transfers control to SYSLINUX \_ SYSLINUX boot loader and configuration files \_ compressed Linux kernel image ("linux") \_ compressed initial ramdisk image ("root.bin", really "root.bin.gz") \_ ext2 filesystem -- DEV: contents of root.bin loopback mount; BOOT: mounted on / as RAM disk and remains mounted indefinitely \_ init shell script ("/sbin/init"), a Bourne shell script which runs as PID 1 and handles finding and mounting CD-R, finding and mounting CD filesystem via cloop.o, renaming some directories, spawning getty processes, etc. \_ minimal system boot libraries, binaries (BusyBox), devices, and mount points (originally based on Debian slink boot floppy) -- BOOT: used and then renamed to /lib (entirely unused except ld-linux.so.2), /sbin.defunct, and /bin.defunct once /mnt/cdrom is mounted \_ compressed block device image ("singularity") \_ ext2 filesystem -- DEV: contents of "/cloop"; BOOT: mounted on "/mnt/cdrom" and a symlink points from /usr to /mnt/cdrom \_ all run-time libraries, binaries, kernel modules, configuration files, etc. \_ insmod (static binary) -- BOOT: used by init script to load cloop.o \_ cloop.o (kernel module) -- BOOT: used by init script; allows kernel to read compressed contents of "singularity" \_ other files (not used after boot; mainly for Windows users), e.g. RAWRITE2, GZIP, and LOADLIN DOS executables, and some documentation Guide to init script -------------------- In the BBC, /sbin/init is a Bourne shell script on the RAM disk (inside of root.bin) which is run with a copy of ash which is also inside the RAM disk. During normal use, this shell script never exits. (Having init be a shell script is different from normal Unix practice, where init is generally a C program, which is configured via /etc/inittab. The BBC system has nothing corresponding to /etc/inittab; configuration changes are made directly inside the script. This also implies that the BBC has nothing corresponding to runlevels; while it is running, it is _always_ in the equivalent of single-user mode, even though it may start gettys, networking, and X11.) init's main task is to find and mount the CD-ROM and then mount the compressed filesystem image within the CD-ROM. All of the most essential parts of the script are dedicated to this task. init tries to find an IDE or SCSI device which can be mounted as a CD-ROM (as an iso9660 filesystem); when one is found and recognized as a BBC, it is mounted on /mnt/cdrom-real. (This indicates that the filesystem mounted there is the actual iso9660 filesystem physically stored on the CD-ROM.) Then the singularity is run, which results in a short shell script at the beginning of singularity loading the cloop module and telling it to take the singularity as its compressed block device image. Next, init mounts /dev/cloop (the uncompressed version of singularity, as provided by the cloop kernel module) as an ext2fs on /mnt/cdrom. This directory is the same as /usr, so that /usr/bin and /usr/lib are actually /mnt/cdrom/bin and /mnt/cdrom/lib, respectively. Once /mnt/cdrom is mounted, many more programs are available, and init will perform a few clean-up tasks to cause libraries and programs to be taken from /usr/lib and /usr/bin by default, instead of from the old /lib and /bin, which are in the RAM disk, and which contain the BusyBox utilities and libraries. After performing a few more system initialization tasks (including an attempt to mount read-only any partition mentioned in /proc/partitions which contains an ext2fs), init runs a few gettys and enters a loop by which these gettys will be respawned. init stays in this loop for as long as the system is running. init does not take any part in system shutdown, which is entirely handled by the "reboot" command. How a BBC is built ------------------ We have a script called "create_iso" (formerly "burn") which creates a new "singularity" file from the contents of /cloop, then copies that new singularity into /cdrom. A current lnx.img is already inside of /cdrom, so we then call mkisofs with appropriate options to create an ISO image from the /cdrom tree. The singularity creation is probably the most obscure part of this process. It's handled by first creating a large empty file, then doing an mke2fs to create a filesystem therein, then copying all of the files in /cloop into that filesystem, and then running create_compressed_fs to compress the entire filesystem into a cloop image which can be read by Rusty's kernel module cloop.o (now maintained by Klaus). The build process is actually very simple (although the various checks and details involved may appear confusing). It's trickier to keep track of all the of the loopback mounts that are involved if you want to modify lnx.img or (more typically) root.bin. This is because root.bin is a compressed filesystem inside a filesystem inside a filesystem. So we have to loopback mount lnx.img, find root.bin inside, zcat root.bin, mount the uncompressed version, make changes, unmount root.bin, gzip it, and unmount lnx.img. See how much more involved that is than actually building a BBC? How the old Debian installer worked ----------------------------------- This section is not here yet. (I don't think you really want to know, anyway. It was an awful hack -- I should know because I did it. It involves an exec, chroot, and exec again within init, after loopback mounting a floppy image in a fake root filesystem!) How the new Debian installer works ---------------------------------- We have a compressed image of (essentially) the filesystem from a Debian installer floppy. (The compressed image is /usr/share/dbootstrap/root.bin.) The installer script (called "dbootstrap.sh") decompresses this and then does a loopback mount of the floppy filesystem on /mnt/tmp2. Next, it does a chroot into /mnt/tmp2 and runs a script which will do a few setup steps before running "dbootstrap", the standard Debian installer. The old Debian installer could install the base system from our CD-ROM; the new installer requires a network connection (which is supposed to be set up _beforehand_, with our trivial-net-setup program) and downloads the Debian base system from servers on the Internet. Proposed changes to boot sequence --------------------------------- (Just to keep you informed, so you don't get confused in the future if we decide to do any of these things. Or, if you want an interesting project to experiment with. We welcome your contributions, and of course you are also free to create your own bootable CD project.) If you don't need cloop, you can modify init to mount the whole CD on /mnt/cdrom-real or to use a standard loopback mount of an uncompressed filesystem with "mount -o loop". We will never do this because we need compression to fit everything on a 50 MB CD-R blank. We might replace cloop with one of its friendly rivals such as cramfs or cbd, depending on performance and portability. Probably we will use a cloop-compressed romfs instead of a cloop-compressed ext2fs, because we can't write to cloop-compressed filesystems anyway, and romfs compresses better. We might use devfs, or at least take the device nodes out of the root filesystem image on the disk and instead create them at boot time with a makedev script run from init. (The size of the filesystem inside lnx.img cannot exceed 1.44 MB, per El Torito requirements. Space is therefore a premium within the root filesystem, because it, gzipped, together with the kernel and SYSLINUX, may not exceed this limit.) We might use monte and (to make things even more complicated) boot a tiny kernel with only IDE and SCSI support, which mounts the CD, locates a suitable kernel from among several provided there, and then reboots the system using that particular kernel. (monte is capable of rebooting a running system into an arbitrary kernel image, very much like LOADLIN for DOS.) That kernel would then mount the CD, locate appropriate kernel modules to match system hardware, and load them. This scheme would also facilitate network booting, which is something we would very much like to add. We will probably put / on a ramfs when we go to 2.4. How to modify the BBC in small ways ----------------------------------- (1) For a burn onto a full-size CD, you can add uncompressed data in a new subdirectory of /cdrom, and then that data will be available in the corresponding directory under /mnt/cdrom-real when the system boots. (2) You can modify /sbin/init inside the lnx.img loopback mount to change how the system behaves when it boots. (3) To add new software to the regular BBC, copy binaries into /cloop/bin, making sure that they work with the shared libraries in /cloop/lib. (These become /usr/bin and /usr/lib on the running system, respectively; the running system's original /bin and /lib are only used during boot.) (4) To change the kernel image, replace "linux" in the lnx.img loopback mount. You will also have to worry about the modules under /cloop/lib/modules. Module autoprobing mostly does not work right, so you might want to fix that bug or make the init script probe for modules. (5) If you want things to happen at boot time but don't have space inside lnx.img, just create a script or other program in /cloop/bin with the files you need, and call that from within /sbin/init once /mnt/cdrom has been mounted. There's _tons_ of space within /cloop compared to the amount of space available within lnx.img! (The RAM disk is supposedly 1000 KB, but of course you can't actually use all of that because we want to leave some free space on / at boot time, and because only free space compresses well enough to fit that much inside a 1.44 MB lnx.img.) In addition, you can now create things in /auto on the CD-ROM which will run at boot time. See the README in that directory for more information.