ARM kernel compilation process

From Crashcourse Wiki

Jump to: navigation, search

Contents

[edit] Overview

A walkthrough of the configuration and compilation process of the current Linux kernel source for my LogicPD AM3517 experimenter kit, eventually covering aspects of the device tree and multiplatform support. To start with:

$ export ARCH=arm
$ export CROSS_COMPILE=arm-arago-linux-gnueabi-
$ export KBUILD_OUTPUT=../am3517

This page will concentrate on using the new multiplatform support in the kernel, rather than selecting a specific machine. At the moment, I still have no idea where this page is going...

[edit] The default configuration with multiplatform support

With multiplatform support, the proper configuration will be:

$ make omap2plus_defconfig

and here are some of the relevant CONFIG variables (broken across the .config file):

#
# Automatically generated file; DO NOT EDIT.
# Linux/arm 3.9.0-rc4 Kernel Configuration
#
CONFIG_ARM=y
#
# System Type
#
CONFIG_MMU=y
CONFIG_ARCH_MULTIPLATFORM=y
#
# CPU Core family selection
#
# CONFIG_ARCH_MULTI_V6 is not set
CONFIG_ARCH_MULTI_V7=y
CONFIG_ARCH_MULTI_V6_V7=y
#
# OMAP Feature Selections
#
...
CONFIG_MACH_OMAP_GENERIC=y
CONFIG_ARCH_OMAP=y
CONFIG_ARCH_OMAP2PLUS=y
#
# TI OMAP2/3/4 Specific Features
#
CONFIG_ARCH_OMAP2PLUS_TYPICAL=y
CONFIG_SOC_HAS_OMAP2_SDRC=y
CONFIG_SOC_HAS_REALTIME_COUNTER=y
CONFIG_ARCH_OMAP2=y
CONFIG_ARCH_OMAP3=y
CONFIG_ARCH_OMAP4=y
CONFIG_SOC_OMAP5=y
#
# OMAP Core Type
#
CONFIG_SOC_OMAP2420=y
CONFIG_SOC_OMAP2430=y
CONFIG_SOC_OMAP3430=y
CONFIG_SOC_TI81XX=y
CONFIG_SOC_AM33XX=y
...
#
# OMAP Board Type
#
...
CONFIG_MACH_OMAP3517EVM=y   [among many others]
#
# Processor Type
#
CONFIG_CPU_V6=y
CONFIG_CPU_V7=y
... and lots more ...
#
# Boot options
#
CONFIG_USE_OF=y
CONFIG_ATAGS=y
# CONFIG_DEPRECATED_PARAM_STRUCT is not set
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
# CONFIG_ARM_APPENDED_DTB is not set
CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO2,115200"
CONFIG_CMDLINE_FROM_BOOTLOADER=y
# CONFIG_CMDLINE_EXTEND is not set
# CONFIG_CMDLINE_FORCE is not set
CONFIG_KEXEC=y
CONFIG_ATAGS_PROC=y
# CONFIG_CRASH_DUMP is not set
CONFIG_AUTO_ZRELADDR=y
#
# Device Tree and Open Firmware support
#
CONFIG_PROC_DEVICETREE=y
# CONFIG_OF_SELFTEST is not set
CONFIG_OF_FLATTREE=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_IRQ=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_NET=y
CONFIG_OF_MDIO=y
CONFIG_OF_MTD=y

That should be enough for now; might add more later as it becomes necessary.

[edit] Building base vmlinux (not zImage yet)

[edit] The top-level Makefile

SRCARCH         := $(ARCH)
include $(srctree)/arch/$(SRCARCH)/Makefile
# Objects we will link into vmlinux / subdirs we need to visit
init-y          := init/
drivers-y       := drivers/ sound/ firmware/
net-y           := net/
libs-y          := lib/
core-y          := usr/
core-y          += kernel/ mm/ fs/ ipc/ security/ crypto/ block/

vmlinux-dirs    := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
                     $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
                     $(net-y) $(net-m) $(libs-y) $(libs-m)))

vmlinux-alldirs := $(sort $(vmlinux-dirs) $(patsubst %/,%,$(filter %/, \
                     $(init-n) $(init-) \
                     $(core-n) $(core-) $(drivers-n) $(drivers-) \
                     $(net-n)  $(net-)  $(libs-n)    $(libs-))))

init-y          := $(patsubst %/, %/built-in.o, $(init-y))
core-y          := $(patsubst %/, %/built-in.o, $(core-y))
drivers-y       := $(patsubst %/, %/built-in.o, $(drivers-y))
net-y           := $(patsubst %/, %/built-in.o, $(net-y))
libs-y1         := $(patsubst %/, %/lib.a, $(libs-y))
libs-y2         := $(patsubst %/, %/built-in.o, $(libs-y))
libs-y          := $(libs-y1) $(libs-y2)

# Externally visible symbols (used by link-vmlinux.sh)
export KBUILD_VMLINUX_INIT := $(head-y) $(init-y)
export KBUILD_VMLINUX_MAIN := $(core-y) $(libs-y) $(drivers-y) $(net-y)
export KBUILD_LDS          := arch/$(SRCARCH)/kernel/vmlinux.lds
export LDFLAGS_vmlinux

vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_INIT) $(KBUILD_VMLINUX_MAIN)
...
vmlinux: scripts/link-vmlinux.sh $(vmlinux-deps) FORCE

Note the inclusion of $(head-y), which is architecture-specific as you'll see below.

[edit] arch/arm/Makefile

Remember that, for the following,

CONFIG_ARCH_MULTIPLATFORM=y

The Makefile snippets (MMUEXT is empty):

head-y          := arch/arm/kernel/head$(MMUEXT).o
plat-$(CONFIG_ARCH_OMAP)        += omap
# If we have a machine-specific directory, then include it in the build.
core-y                          += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
core-y                          += arch/arm/net/
core-y                          += arch/arm/crypto/
core-y                          += $(machdirs) $(platdirs)

drivers-$(CONFIG_OPROFILE)      += arch/arm/oprofile/

libs-y                          := arch/arm/lib/ $(libs-y)

Default target, just in case:

# Default target when executing plain make
ifeq ($(CONFIG_XIP_KERNEL),y)
KBUILD_IMAGE := xipImage
else
KBUILD_IMAGE := zImage
endif

[edit] arch/arm/kernel/head.o

  • arch/arm/kernel/head.S
  • arch/arm/kernel/head-common.S

[edit] The final linking for vmlinux

[edit] arch/arm/kernel/vmlinux.lds.S

[edit] include/asm-generic/vmlinux.lds.h

More stuff here?

[edit] The issue with uImage and ARM multiplatform builds

A uImage format is not compatible with the new ARM multiplatform builds. I may write more on this later.

[edit] Building a zImage

[edit] The build output

  ... snip ...
  OBJCOPY arch/arm/boot/Image
  Kernel: arch/arm/boot/Image is ready
  AS      arch/arm/boot/compressed/head.o
  GZIP    arch/arm/boot/compressed/piggy.gzip
  AS      arch/arm/boot/compressed/piggy.gzip.o
  CC      arch/arm/boot/compressed/misc.o
  CC      arch/arm/boot/compressed/decompress.o
  CC      arch/arm/boot/compressed/string.o
  AS      arch/arm/boot/compressed/hyp-stub.o
  SHIPPED arch/arm/boot/compressed/lib1funcs.S
  AS      arch/arm/boot/compressed/lib1funcs.o
  SHIPPED arch/arm/boot/compressed/ashldi3.S
  AS      arch/arm/boot/compressed/ashldi3.o
  LD      arch/arm/boot/compressed/vmlinux
  OBJCOPY arch/arm/boot/zImage
  Kernel: arch/arm/boot/zImage is ready

[edit] arch/arm/Makefile

boot := arch/arm/boot
...
zImage Image xipImage bootpImage uImage: vmlinux
        $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@

[edit] arch/arm/boot/Makefile

$(obj)/zImage:  $(obj)/compressed/vmlinux FORCE
        $(call if_changed,objcopy)
        @$(kecho) '  Kernel: $@ is ready'

[edit] arch/arm/boot/compressed/Makefile

$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \
                $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) FORCE
        @$(check_for_multiple_zreladdr)
        $(call if_changed,ld)
        @$(check_for_bad_syms)

$(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE       <-- dependency on Image
        $(call if_changed,$(suffix_y))

$(obj)/piggy.$(suffix_y).o:  $(obj)/piggy.$(suffix_y) FORCE
Personal tools