This is especially true when working towards creating a new subarchitecture since lots of little places have to be touched, kernels usually have to be tweaked, and all other sorts of odds and ins. This post isn't a comprehensive guide to what's necessary, but just little tidbits of what I did, just some random odds and ends.
The first step of any enablement is to have something you can run and boot. The netboot images, as well as the alternate kernel and ramdisk are built out of the debian-installer package. In the debian-installer package, several config files for driving the process are located in build/config/$arch/$subarch. For omap4, we have the following files:
boot/arm/generate-partitioned-filesystem is a shell script that takes a VFAT blob, and spits out a proper MBR and partition table.
build/config/armel.cfg simply is a list subarchitectures to build, and some sane-ish kernel defaults for armel.
build/config/armel/omap4.cfg is also a simple config file which specifies the type of images we're building, and the kernel to use in d-i. This file looks like this:
MEDIUM_SUPPORTED = netboot cdrom # The version of the kernel to use. KERNELVERSION := 2.6.38-1309-omap4 # we use non-versioned filenames in the omap kernel udeb KERNELNAME = vmlinuz VERSIONED_SYSTEM_MAP =
As a point of clarification, 'cdrom' is a bit of a misdemeanor; it refers to the alternate installer kernel and ramdisk used by alternate images, and not the type of media. Other types of images exist such as 'floppy' and 'hd-install', but these are specialized images, and out of scope for this blog post.
Each file in build/config/armel/omap4/* is a makefile thats called in turn for each image that created. The most interesting of this is the netboot.cfg
MEDIA_TYPE = netboot image SUBARCH = omap4 TARGET = $(TEMP_INITRD) $(TEMP_KERNEL) omap4 EXTRANAME = $(MEDIUM) INITRD_FS = initramfs MANIFEST-INITRD = "netboot initrd" MANIFEST-KERNEL = "kernel image to netboot" INSTALL_PATH = $(SOME_DEST)/$(EXTRANAME) omap4: # Make sure our build envrionment is clean rm -rf $(INSTALL_PATH) mkdir -p $(INSTALL_PATH) # Generate uImage/uInitrd mkimage -A arm -O linux -T kernel -C none -a 0x80008000 -e 0x80008000 -n "Ubuntu kernel" -d $(TEMP_KERNEL) $(INSTALL_PATH)/uImage mkimage -A arm -O linux -T ramdisk -C none -a 0x0 -e 0x0 -n "debian-installer ramdisk" -d $(TEMP_INITRD) $(INSTALL_PATH)/uInitrd # Generate boot.scrs mkimage -A arm -T script -C none -n "Ubuntu boot script (serial)" -d boot/arm/boot.script-omap4-serial $(INSTALL_PATH)/boot.scr-serial mkimage -A arm -T script -C none -n "Ubuntu boot script (framebuffer)" -d boot/arm/boot.script-omap4-fb $(INSTALL_PATH)/boot.scr-fb # Create DD'able filesystems mkdosfs -C $(INSTALL_PATH)/boot.img-fat-serial 10240 mcopy -i $(INSTALL_PATH)/boot.img-fat-serial $(INSTALL_PATH)/uImage ::uImage mcopy -i $(INSTALL_PATH)/boot.img-fat-serial $(INSTALL_PATH)/uInitrd ::uInitrd mcopy -i $(INSTALL_PATH)/boot.img-fat-serial /usr/lib/x-loader/omap4430panda/MLO ::MLO mcopy -i $(INSTALL_PATH)/boot.img-fat-serial /usr/lib/u-boot/omap4_panda/u-boot.bin ::u-boot.bin cp $(INSTALL_PATH)/boot.img-fat-serial $(INSTALL_PATH)/boot.img-fat-fb mcopy -i $(INSTALL_PATH)/boot.img-fat-serial $(INSTALL_PATH)/boot.scr-serial ::boot.scr mcopy -i $(INSTALL_PATH)/boot.img-fat-fb $(INSTALL_PATH)/boot.scr-fb ::boot.scr boot/arm/generate-partitioned-filesystem $(INSTALL_PATH)/boot.img-fat-fb $(INSTALL_PATH)/boot.img-fb boot/arm/generate-partitioned-filesystem $(INSTALL_PATH)/boot.img-fat-serial $(INSTALL_PATH)/boot.img-serial # Generate manifests update-manifest $(INSTALL_PATH)/uImage "Linux kernel for OMAP Boards" update-manifest $(INSTALL_PATH)/uInitrd "initrd for OMAP Boards" update-manifest $(INSTALL_PATH)/boot.scr-fb "Boot script for booting OMAP netinstall initrd and kernel from SD card. Uses framebuffer display" update-manifest $(INSTALL_PATH)/boot.scr-serial "Boot script for booting OMAP netinstall initrd and kernel from SD card. Uses serial output" update-manifest $(INSTALL_PATH)/boot.img-serial "Boot image for booting OMAP netinstall. Uses serial output" update-manifest $(INSTALL_PATH)/boot.img-fb "Boot image for booting OMAP netinstall. Uses framebuffer output"
The vast majority of this is fairly straightforward. TARGET represents the targets called by make. There are tasks for creating a vmlinuz and initrd that must be included. The omap4 target then handles specialized handling for the omap4/netboot image.
omap4 requires a VFAT boot partition on the SD card with a proper filesystem and MBR. The contents of the filesystem are straightforward:
MLO - also known as x-loader, a first stage bootloader
u-boot.bin - u-boot binary, second stage bootloader, used to book the kernel
uImage - linux kernel with special uboot header (created with mkimage)
uInitrd - d-i ramdisk with special uboot header
boot.scr - special boot script for u-boot for commands to execute at startup.
MLO and u-boot.bin are copied in from x-loader-omap4-panda and u-boot-linaro-omap4-panda which are listed as build-deps in the control file for d-i. boot.scr is generated from a plain-text file:
fatload mmc 0:1 0x80000000 uImage fatload mmc 0:1 0x81600000 uInitrd setenv bootargs vram=32M mem=456M@0x80000000 mem=512M@0xA0000000 fixrtc quiet debian-installer/framebuffer=false console=ttyO2,115200n8 bootm 0x80000000 0x81600000
These are u-boot commands that simply load the uImage/uInitrd into RAM, set the command line, and then boot into it.
When porting the installer, it is mostly a task of putting your subarchitecture name in the right places, then adding the necessary logic in places to spit out an image that boots. This provides a sane base to start working on porting other bits of the installer. When d-i is uploaded to Launchpad, these files end up in http://ports.ubuntu.com/ubuntu-ports/dists/oneiric/main/installer-armel/current/images/
My next blog post will go a bit into udebs, and understanding how d-i does architecture detection, and introducing flash-kernel.