2장에서 분석한 것과 같이 ARM 리눅스의 Makefile도 i386의 것과 비슷하다. 그러나 부팅하는 과정 등의 일부가 PC가 아닌 다른 시스템이기 때문에 많이 다르다. 그럼에도 불구하고 대부분 비슷한 방법으로 만들어지고 실행된다.
arch/arm 이하의 것만 제외한다면 나머지는 i386의 것과 동일하므로 2장을 참조하고 나머지 ARM 리눅스에 관련된 부분만 다룬다.
Assabet 보드용 기본 설정에 해당하는 .Config file의 내용은 아래와 같다. 이를 참조해 아래 Makefile 분석을 좇아가기 바란다. 세팅된 것만 추리고 나머지는 버렸다.
# # Automatically generated by make menuconfig: don't edit # CONFIG_ARM=y CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y # # Code maturity level options # CONFIG_EXPERIMENTAL=y # # Loadable module support # CONFIG_MODULES=y # # System Type # CONFIG_ARCH_SA1100=y # # SA11x0 Implementations # CONFIG_SA1100_ASSABET=y CONFIG_SA1100_USB=m CONFIG_SA1100_USB_NETLINK=m CONFIG_CPU_32=y CONFIG_CPU_32v4=y CONFIG_CPU_SA1100=y CONFIG_DISCONTIGMEM=y # # General setup # # CONFIG_PCI is not set CONFIG_ISA=y CONFIG_CPU_FREQ=y CONFIG_HOTPLUG=y # # PCMCIA/CardBus support # CONFIG_PCMCIA=y CONFIG_PCMCIA_PROBE=y CONFIG_PCMCIA_SA1100=y CONFIG_NET=y CONFIG_SYSVIPC=y CONFIG_SYSCTL=y CONFIG_FPE_NWFPE=y CONFIG_KCORE_ELF=y CONFIG_BINFMT_ELF=y CONFIG_PM=y CONFIG_CMDLINE="root=1f04 mem=32M" CONFIG_LEDS=y CONFIG_LEDS_TIMER=y CONFIG_LEDS_CPU=y CONFIG_ALIGNMENT_TRAP=y # # Memory Technology Devices (MTD) # CONFIG_MTD=y CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y # # RAM/ROM/Flash chip drivers # CONFIG_MTD_CFI=y CONFIG_MTD_GEN_PROBE=y CONFIG_MTD_CFI_ADV_OPTIONS=y CONFIG_MTD_CFI_NOSWAP=y CONFIG_MTD_CFI_GEOMETRY=y CONFIG_MTD_CFI_B4=y CONFIG_MTD_CFI_I2=y CONFIG_MTD_CFI_INTELEXT=y # # Mapping drivers for chip access # CONFIG_MTD_SA1100=y # # Block devices # CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y # # Networking options # CONFIG_UNIX=y CONFIG_INET=y # # Network device support # CONFIG_NETDEVICES=y # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y # # PCMCIA network device support # CONFIG_NET_PCMCIA=y CONFIG_PCMCIA_PCNET=y # # IrDA (infrared) support # CONFIG_IRDA=m CONFIG_IRLAN=m # # Infrared-port device drivers # CONFIG_SA1100_FIR=m # # ATA/IDE/MFM/RLL support # CONFIG_IDE=y # # IDE, ATA and ATAPI Block devices # CONFIG_BLK_DEV_IDE=y CONFIG_BLK_DEV_IDEDISK=y CONFIG_BLK_DEV_IDECS=y # # Character devices # CONFIG_VT=y # # Serial drivers # CONFIG_SERIAL_SA1100=y CONFIG_SERIAL_SA1100_CONSOLE=y CONFIG_SA1100_DEFAULT_BAUDRATE=38400 CONFIG_SERIAL_8250=m CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=32 # # L3 serial bus support # CONFIG_L3=y CONFIG_L3_ALGOBIT=y CONFIG_L3_BIT_SA1100_GPIO=y CONFIG_BIT_SA1100_GPIO=y # # Watchdog Cards # CONFIG_SA1100_RTC=y # # PCMCIA character devices # CONFIG_PCMCIA_SERIAL_CS=m # # File systems # CONFIG_FAT_FS=y CONFIG_MSDOS_FS=y CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 CONFIG_TMPFS=y CONFIG_PROC_FS=y CONFIG_DEVPTS_FS=y CONFIG_EXT2_FS=y # # Network File Systems # CONFIG_NFS_FS=y CONFIG_SUNRPC=y CONFIG_LOCKD=y # # Partition Types # CONFIG_PARTITION_ADVANCED=y CONFIG_MSDOS_PARTITION=y CONFIG_NLS=y # # Native Language Support # CONFIG_NLS_DEFAULT="iso8859-1" CONFIG_NLS_CODEPAGE_437=y # # Console drivers # CONFIG_PC_KEYMAP=y # # Frame-buffer support # CONFIG_FB=y CONFIG_DUMMY_CONSOLE=y CONFIG_FB_SA1100=y CONFIG_FBCON_CFB2=y CONFIG_FBCON_CFB4=y CONFIG_FBCON_CFB8=y CONFIG_FBCON_CFB16=y CONFIG_FBCON_FONTWIDTH8_ONLY=y CONFIG_FBCON_FONTS=y CONFIG_FONT_8x8=y # # Sound # CONFIG_SOUND=y CONFIG_SOUND_SA1100=y CONFIG_SOUND_UDA1341=y CONFIG_SOUND_ASSABET_UDA1341=y # # Multimedia Capabilities Port drivers # CONFIG_MCP=y CONFIG_MCP_SA1100=y CONFIG_MCP_UCB1200=y CONFIG_MCP_UCB1200_AUDIO=m CONFIG_MCP_UCB1200_TS=y # # Kernel hacking # CONFIG_DEBUG_USER=y |
# # arch/arm/Makefile # # This file is subject to the terms and conditions of the GNU General Public # License. See the file "COPYING" in the main directory of this archive # for more details. # # Copyright (C) 1995-2001 by Russell King LINKFLAGS :=-p -X -T arch/arm/vmlinux.lds GZFLAGS :=-9 CFLAGS +=-fno-common -pipe ifneq ($(CONFIG_NO_FRAME_POINTER),y) CFLAGS :=$(CFLAGS:-fomit-frame-pointer=) endif ifeq ($(CONFIG_DEBUG_INFO),y) CFLAGS +=-g endif # Select CPU dependent flags. Note that order of declaration is important; # the options further down the list override previous items. # # Note! For APCS-26 YOU MUST HAVE AN APCS-26 LIBGCC.A # apcs-y :=-mapcs-32 apcs-$(CONFIG_CPU_26) :=-mapcs-26 -mcpu=arm3 -Os (1) # This selects which instruction set is used. arch-y := arch-$(CONFIG_CPU_32v3) :=-march=armv3 arch-$(CONFIG_CPU_32v4) :=-march=armv4 arch-$(CONFIG_CPU_32v5) :=-march=armv5 (2) # This selects how we optimise for the processor. tune-y := tune-$(CONFIG_CPU_ARM610) :=-mtune=arm610 tune-$(CONFIG_CPU_ARM710) :=-mtune=arm710 tune-$(CONFIG_CPU_ARM720T) :=-mtune=arm7tdmi tune-$(CONFIG_CPU_ARM920T) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM922T) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110 tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100 CFLAGS_BOOT :=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float CFLAGS +=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float AFLAGS +=$(apcs-y) $(arch-y) -mno-fpu -msoft-float ifeq ($(CONFIG_CPU_26),y) PROCESSOR = armo ifeq ($(CONFIG_ROM_KERNEL),y) DATAADDR = 0x02080000 TEXTADDR = 0x03800000 LDSCRIPT = arch/arm/vmlinux-armo-rom.lds.in else TEXTADDR = 0x02080000 LDSCRIPT = arch/arm/vmlinux-armo.lds.in endif endif (3) ifeq ($(CONFIG_CPU_32),y) PROCESSOR = armv TEXTADDR = 0xC0008000 LDSCRIPT = arch/arm/vmlinux-armv.lds.in endif ifeq ($(CONFIG_ARCH_ARCA5K),y) MACHINE = arc endif ifeq ($(CONFIG_ARCH_RPC),y) MACHINE = rpc endif ifeq ($(CONFIG_ARCH_EBSA110),y) MACHINE = ebsa110 endif ifeq ($(CONFIG_ARCH_CLPS7500),y) MACHINE = clps7500 INCDIR = cl7500 endif ifeq ($(CONFIG_FOOTBRIDGE),y) MACHINE = footbridge INCDIR = ebsa285 endif ifeq ($(CONFIG_ARCH_CO285),y) TEXTADDR = 0x60008000 MACHINE = footbridge INCDIR = ebsa285 endif ifeq ($(CONFIG_ARCH_FTVPCI),y) MACHINE = ftvpci INCDIR = nexuspci endif ifeq ($(CONFIG_ARCH_TBOX),y) MACHINE = tbox endif ifeq ($(CONFIG_ARCH_SHARK),y) MACHINE = shark endif (4) ifeq ($(CONFIG_ARCH_SA1100),y) ifeq ($(CONFIG_SA1111),y) # SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memory TEXTADDR = 0xc0208000 endif MACHINE = sa1100 endif ifeq ($(CONFIG_ARCH_L7200),y) MACHINE = l7200 endif ifeq ($(CONFIG_ARCH_INTEGRATOR),y) MACHINE = integrator endif ifeq ($(CONFIG_ARCH_CAMELOT),y) MACHINE = epxa10db endif ifeq ($(CONFIG_ARCH_CLPS711X),y) TEXTADDR = 0xc0028000 MACHINE = clps711x endif ifeq ($(CONFIG_ARCH_FORTUNET),y) TEXTADDR = 0xc0008000 endif ifeq ($(CONFIG_ARCH_ANAKIN),y) MACHINE = anakin endif export MACHINE PROCESSOR TEXTADDR GZFLAGS CFLAGS_BOOT # Only set INCDIR if its not already defined above # Grr, ?= doesn't work as all the other assignment operators do. Make bug? ifeq ($(origin INCDIR), undefined) INCDIR := $(MACHINE) endif ifeq ($(origin DATAADDR), undefined) DATAADDR := . endif (5) # If we have a machine-specific directory, then include it in the build. MACHDIR := arch/arm/mach-$(MACHINE) ifeq ($(MACHDIR),$(wildcard $(MACHDIR))) SUBDIRS += $(MACHDIR) CORE_FILES := $(MACHDIR)/$(MACHINE).o $(CORE_FILES) endif (6) HEAD := arch/arm/kernel/head-$(PROCESSOR).o \ arch/arm/kernel/init_task.o SUBDIRS += arch/arm/kernel arch/arm/mm arch/arm/lib arch/arm/nwfpe CORE_FILES := arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES) LIBS := arch/arm/lib/lib.a $(LIBS) ifeq ($(CONFIG_FPE_NWFPE),y) LIBS := arch/arm/nwfpe/math-emu.o $(LIBS) endif # Only include fastfpe if it is part of the kernel tree. FASTFPE := arch/arm/fastfpe ifeq ($(FASTFPE),$(wildcard $(FASTFPE))) SUBDIRS += $(FASTFPE) ifeq ($(CONFIG_FPE_FASTFPE),y) LIBS := arch/arm/fastfpe/fast-math-emu.o $(LIBS) endif endif ifeq ($(findstring y,$(CONFIG_ARCH_CLPS7500) $(CONFIG_ARCH_L7200)),y) SUBDIRS += drivers/acorn/char DRIVERS += drivers/acorn/char/acorn-char.o endif MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot MAKETOOLS = $(MAKE) -C arch/$(ARCH)/tools # The following is a hack to get 'constants.h' up # to date before starting compilation $(patsubst %,_dir_%, $(SUBDIRS)): maketools $(patsubst %,_modsubdir_%,$(MOD_DIRS)): maketools symlinks: archsymlinks archsymlinks: $(RM) include/asm-arm/arch include/asm-arm/proc (cd include/asm-arm; ln -sf arch-$(INCDIR) arch; ln -sf proc-$(PROCESSOR) proc) vmlinux: arch/arm/vmlinux.lds (7) arch/arm/vmlinux.lds: $(LDSCRIPT) dummy @sed 's/TEXTADDR/$(TEXTADDR)/;s/DATAADDR/$(DATAADDR)/' $(LDSCRIPT) >$@ arch/arm/kernel arch/arm/mm arch/arm/lib: dummy $(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" $(subst $@, _dir_$@, $@) bzImage zImage zinstall Image bootpImage install: vmlinux @$(MAKEBOOT) $@ CLEAN_FILES += \ arch/arm/vmlinux.lds MRPROPER_FILES += \ include/asm-arm/arch \ include/asm-arm/proc \ include/asm-arm/constants.h* \ include/asm-arm/mach-types.h # We use MRPROPER_FILES and CLEAN_FILES now archmrproper: @/bin/true archclean: @$(MAKEBOOT) clean archdep: scripts/mkdep archsymlinks @$(MAKETOOLS) dep @$(MAKEBOOT) dep # we need version.h maketools: checkbin include/linux/version.h @$(MAKETOOLS) all # Ensure this is ld "2.9.4" or later NEW_LINKER := $(shell $(LD) --gc-sections --version >/dev/null 2>&1; echo $$?) ifneq ($(NEW_LINKER),0) checkbin: @echo '*** ${VERSION}.${PATCHLEVEL} kernels no longer build correctly with old versions of binutils.' @echo '*** Please upgrade your binutils to 2.9.5.' @false else checkbin: @true endif # My testing targets (that short circuit a few dependencies) zImg:; @$(MAKEBOOT) zImage Img:; @$(MAKEBOOT) Image i:; @$(MAKEBOOT) install zi:; @$(MAKEBOOT) zinstall bp:; @$(MAKEBOOT) bootpImage (8) # # Configuration targets. Use these to select a # configuration for your architecture %_config: @( \ CFG=$(@:_config=); \ if [ -f arch/arm/def-configs/$$CFG ]; then \ [ -f .config ] && mv -f .config .config.old; \ cp arch/arm/def-configs/$$CFG .config; \ echo "*** Default configuration for $$CFG installed"; \ echo "*** Next, you may run 'make oldconfig'"; \ else \ echo "$$CFG does not exist"; \ fi; \ ) |
ARM 아키텍쳐에서 아키텍쳐에(v6포함) 대한 자세한 정보를 얻기 바란다. 간단히 정리하면 다음과 같다.
v3
32 비트 어드레싱 시작, 아래와 같은 종류가 있다.
T
Thumb 코드 실행
M
long multiply 지원, 이것은 v4에서 기본이 됐다.
v4
halfword load, store 지원
v5
개선된 ARM, Thumb 동작. CLZ 명령 지원. 종류는
E
개선된 DSP 명령
J
JAVA 지원
arch/arm/def-config에 가능한 모든 정보가 들어있다.
ARM 프로세서 커널의 링크에 사용되는 링크 스크립트 vmlinux.lds를 분석해보자. 4.3.1절에서 본 것 처럼 vmlinux.lds는 설정된 아키텍쳐에따라 만들어진 것이다.
/* ld script to make ARM Linux kernel * taken from the i386 version by Russell King * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> */ (1) OUTPUT_ARCH(arm) (2) ENTRY(stext) SECTIONS { (3) . = 0xC0008000; (4) .init : { /* Init code and data */ _stext = .; __init_begin = .; *(.text.init) __proc_info_begin = .; *(.proc.info) __proc_info_end = .; __arch_info_begin = .; *(.arch.info) __arch_info_end = .; __tagtable_begin = .; *(.taglist) __tagtable_end = .; *(.data.init) . = ALIGN(16); __setup_start = .; *(.setup.init) __setup_end = .; __initcall_start = .; *(.initcall.init) __initcall_end = .; . = ALIGN(4096); __init_end = .; } (5) /DISCARD/ : { /* Exit code and data */ *(.text.exit) *(.data.exit) *(.exitcall.exit) } (6) .text : { /* Real text segment */ _text = .; /* Text and read-only data */ *(.text) *(.fixup) *(.gnu.warning) *(.rodata) *(.rodata.*) *(.glue_7) *(.glue_7t) *(.got) /* Global offset table */ _etext = .; /* End of text section */ } .kstrtab : { *(.kstrtab) } . = ALIGN(16); __ex_table : { /* Exception table */ __start___ex_table = .; *(__ex_table) __stop___ex_table = .; } __ksymtab : { /* Kernel symbol table */ __start___ksymtab = .; *(__ksymtab) __stop___ksymtab = .; } (7) . = ALIGN(8192); .data : { /* * first, the init task union, aligned * to an 8192 byte boundary. */ *(.init.task) /* * then the cacheline aligned data */ . = ALIGN(32); *(.data.cacheline_aligned) /* * and the usual data section */ *(.data) CONSTRUCTORS _edata = .; } .bss : { __bss_start = .; /* BSS */ *(.bss) *(COMMON) _end = . ; } /* Stabs debugging sections. */ .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) } .stab.excl 0 : { *(.stab.excl) } .stab.exclstr 0 : { *(.stab.exclstr) } .stab.index 0 : { *(.stab.index) } .stab.indexstr 0 : { *(.stab.indexstr) } .comment 0 : { *(.comment) } } |
union task_union { struct task_struct task; unsigned long stack[INIT_TASK_SIZE/sizeof(long)]; }; |
/* * linux/arch/arm/boot/compressed/vmlinux.lds.in * * Copyright (C) 2000 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ OUTPUT_ARCH(arm) (1) ENTRY(_start) SECTIONS { (2) . = 0xc0008000; _load_addr = .; . = 0xc0008000; _text = .; (3) .text : { _start = .; *(.start) *(.text) *(.fixup) *(.gnu.warning) *(.rodata) *(.rodata.*) *(.glue_7) *(.glue_7t) input_data = .; piggy.o input_data_end = .; . = ALIGN(4); } _etext = .; .data : { *(.data) } _edata = .; . = ALIGN(4); __bss_start = .; .bss : { *(.bss) } _end = .; (4) .stack : { *(.stack) } .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) } .stab.excl 0 : { *(.stab.excl) } .stab.exclstr 0 : { *(.stab.exclstr) } .stab.index 0 : { *(.stab.index) } .stab.indexstr 0 : { *(.stab.indexstr) } .comment 0 : { *(.comment) } } |
아래 Log는 vmlinux가 만들어지는 과정을 생략하고 vmlinux의 ld가 실행되는 것과 그 이후의 과정만을 실었다. i386에서 추적했던 것과 비슷하게 만들어진다.
... (1) /usr/local/arm/bin/arm-linux-ld -p -X -T arch/arm/vmlinux.lds arch/arm/kernel/head-armv.o arch/arm/kernel/init-task.o init/main.o init/version.o \ --start-group \ arch/arm/kernel/kernel.o arch/arm/mm/mm.o arch/arm/mach-sa1100/sa1100.o kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o \ drivers/l3/l3.o drivers/serial/serial.o drivers/char/char.o drivers/block/block.o drivers/misc/misc.o drivers/net/net.o drivers/media/media.o drivers/ide/idedriver.o drivers/sound/sounddrivers.o drivers/mtd/mtdlink.o drivers/pcmcia/pcmcia.o drivers/net/pcmcia/pcmcia-net.o drivers/video/video.o \ net/network.o \ arch/arm/nwfpe/math-emu.o arch/arm/lib/lib.a /devel/arm/assabet/linux-2.4.17/lib/lib.a \ --end-group \ -o vmlinux /usr/local/arm/bin/arm-linux-nm vmlinux | grep -v '\(compiled\)\|\(\.o$\)\|\( [aUw] \)\|\(\.\.ng$\)\|\(LASH[RL]DI\)' | sort > System.map make[1]: 들어감 `/devel/arm/assabet/linux-2.4.17/arch/arm/boot' 디렉토리 make[2]: 들어감 `/devel/arm/assabet/linux-2.4.17/arch/arm/boot/compressed' 디렉토리 (2) /usr/local/arm/bin/arm-linux-gcc -D--ASSEMBLY-- -D--KERNEL-- -I/devel/arm/assabet/linux-2.4.17/include -mapcs-32 -march=armv4 -mno-fpu -msoft-float -traditional -c head.S /usr/local/arm/bin/arm-linux-gcc -D--KERNEL-- -I/devel/arm/assabet/linux-2.4.17/include -O2 -DSTDC-HEADERS -mapcs-32 -march=armv4 -mtune=strongarm1100 -mshort-load-bytes -msoft-float -D--KERNEL-- -I/devel/arm/assabet/linux-2.4.17/include -c -o misc.o misc.c (3) /usr/local/arm/bin/arm-linux-gcc -D--ASSEMBLY-- -D--KERNEL-- -I/devel/arm/assabet/linux-2.4.17/include -mapcs-32 -march=armv4 -mno-fpu -msoft-float -c -o head-sa1100.o head-sa1100.S (4) /usr/local/arm/bin/arm-linux-objcopy -O binary -R .note -R .comment -S /devel/arm/assabet/linux-2.4.17/vmlinux piggy gzip -9 < piggy > piggy.gz /usr/local/arm/bin/arm-linux-ld -r -o piggy.o -b binary piggy.gz rm -f piggy piggy.gz (5) /usr/local/arm/bin/arm-linux-ld -p -X -T vmlinux.lds head.o misc.o head-sa1100.o piggy.o /usr/local/arm/lib/gcc-lib/arm-linux/2.95.3/libgcc.a -o vmlinux make[2]: 나감 `/devel/arm/assabet/linux-2.4.17/arch/arm/boot/compressed' 디렉토리 (6) /usr/local/arm/bin/arm-linux-objcopy -O binary -R .note -R .comment -S compressed/vmlinux zImage make[1]: 나감 `/devel/arm/assabet/linux-2.4.17/arch/arm/boot' 디렉토리 |