4.4. ¼Ò½º ºÐ¼®

$(TOPDIR)/vmlinux°¡ ½ÇÇàµÇ±â Àü ±îÁöÀÇ ¼Ò½º Äڵ带 ºÐ¼®ÇÑ´Ù.

4.4.1. arch/arm/boot/compressed/head.S

Ä¿³Î À̹ÌÁöÀÇ Á¦ÀÏ Ã³À½ ½ÇÇàµÇ´Â ºÎºÐÀ¸·Î head.S, misc.S, head-sa1100.S°¡ °°ÀÌ ½ÇÇàµÈ´Ù. ÀÌ Áß head.S´Â ¸Þ¸ð¸® ÃʱâÈ­¿¡ ÇØ´çÇÏ´Â Áß¿äÇÑ ¿ªÇÒÀ» ´ã´çÇÑ´Ù. ¾Æ·¡ ¼Ò½º Äڵ带 º¸°í ºÐ¼®Çغ¸ÀÚ.

Ä¿³Î À̹ÌÁö°¡ ¸Þ¸ð¸®¿¡ ¾î¶² À§Ä¡¿¡ ¿Ã·ÁÁö°í ¾ÐÃà Ç®¸° °ÍÀÌ ¾îµð¿¡ À§Ä¡ÇÏ°í ´Ù½Ã ¾îµð·Î ¿Å°ÜÁö´ÂÁö µî¿¡ °üÇØ µµ½ÄÀûÀ¸·Î ³ªÅ¸³»ºÃ´Ù. ±×¸² 4-9À» ÂüÁ¶Çϸ鼭 head.S¸¦ ºÐ¼®ÇÑ´Ù.

±×¸² 4-9. ARM ¸®´ª½º Ä¿³Î À̹ÌÁö ¸Þ¸ð¸® ¸Ê

/*
 *  linux/arch/arm/boot/compressed/head.S
 *
 *  Copyright (C) 1996-1999 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.
 */
#include <linux/config.h>
#include <linux/linkage.h>

/*
 * Debugging stuff
 *
 * Note that these macros must not contain any code which is not
 * 100% relocatable.  Any attempt to do so will result in a crash.
 * Please select one of the following when turning on debugging.
 */
#ifdef DEBUG
#if defined(CONFIG_DEBUG_DC21285_PORT)
		.macro	loadsp,	rb
		mov	\rb, #0x7c000000
		.endm
		.macro	writeb,	rb
		strb	\rb, [r3, #0x3f8]
		.endm
#elif defined(CONFIG_ARCH_RPC)
		.macro	loadsp,	rb
		mov	\rb, #0x03000000
		orr	\rb, \rb, #0x00010000
		.endm
		.macro	writeb,	rb
		strb	\rb, [r3, #0x3f8 << 2]
		.endm
#elif defined(CONFIG_ARCH_INTEGRATOR)
		.macro	loadsp, rb
		mov	\rb, #0x16000000
		.endm
		.macro	writeb, rb
		strb	\rb, [r3, #0]
		.endm
#elif defined(CONFIG_ARCH_SA1100)
		.macro	loadsp, rb
		mov	\rb, #0x80000000	@ physical base address
#  if defined(CONFIG_DEBUG_LL_SER3)
		add	\rb, \rb, #0x00050000	@ Ser3
#  else
		add	\rb, \rb, #0x00010000	@ Ser1
#  endif
		.endm
		.macro	writeb, rb
		str	\rb, [r3, #0x14]	@ UTDR
		.endm
#else
#error no serial architecture defined
#endif
#endif

		.macro	kputc,val
		mov	r0, \val
		bl	putc
		.endm

		.macro	kphex,val,len
		mov	r0, \val
		mov	r1, #\len
		bl	phex
		.endm

		.macro	debug_reloc_start
#ifdef DEBUG
		kputc	#'\n'
		kphex	r6, 8		/* processor id */
		kputc	#':'
		kphex	r7, 8		/* architecture id */
		kputc	#':'
		mrc	p15, 0, r0, c1, c0
		kphex	r0, 8		/* control reg */
		kputc	#'\n'
		kphex	r5, 8		/* decompressed kernel start */
		kputc	#'-'
		kphex	r8, 8		/* decompressed kernel end  */
		kputc	#'>'
		kphex	r4, 8		/* kernel execution address */
		kputc	#'\n'
#endif
		.endm

		.macro	debug_reloc_end
#ifdef DEBUG
		kphex	r5, 8		/* end of kernel */
		kputc	#'\n'
		mov	r0, r4
		bl	memdump		/* dump 256 bytes at start of kernel */
#endif
		.endm

(1)
		.section ".start", #alloc, #execinstr
/*
 * sort out different calling conventions
 */
		.align
start:
(2)
		.type	start,#function
		.rept	8
		mov	r0, r0
		.endr

(3)
		b	1f
		.word	0x016f2818		@ Magic numbers to help the loader
		.word	start			@ absolute load/run zImage address
		.word	_edata			@ zImage end address
1:		mov	r7, r1			@ save architecture ID
		mov	r8, #0			@ save r0

#ifndef __ARM_ARCH_2__
		/*
		 * Booting from Angel - need to enter SVC mode and disable
		 * FIQs/IRQs (numeric definitions from angel arm.h source).
		 * We only do this if we were in user mode on entry.
		 */
		mrs	r2, cpsr		@ get current mode
		tst	r2, #3			@ not user?
		bne	not_angel
		mov	r0, #0x17		@ angel_SWIreason_EnterSVC
		swi	0x123456		@ angel_SWI_ARM
not_angel:
		mrs	r2, cpsr		@ turn off interrupts to
		orr	r2, r2, #0xc0		@ prevent angel from running
		msr	cpsr_c, r2
#else
		teqp	pc, #0x0c000003		@ turn off interrupts
#endif

		/*
		 * Note that some cache flushing and other stuff may
		 * be needed here - is there an Angel SWI call for this?
		 */

		/*
		 * some architecture specific code can be inserted
		 * by the linker here, but it should preserve r7 and r8.
		 */

		/*
		 * ldmia¿¡ ÀÇÇØ ÀÐÇôÁö´Â °ªÀº ´ÙÀ½°ú °°´Ù.
		 * r2 : __bss_start
		 * r3 : __end
		 * r4 : _load_addr
		 * r5 : _start
		 * r6 : _usr_stack+4096
		 */

		.text
1:		adr	r2, LC0
		ldmia	r2, {r2, r3, r4, r5, sp}

		mov	r0, #0
1:		str	r0, [r2], #4		@ clear bss
		str	r0, [r2], #4
		str	r0, [r2], #4
		str	r0, [r2], #4
		cmp	r2, r3
		blt	1b

		mrc	p15, 0, r6, c0, c0	@ get processor ID
		bl	cache_on

(4)
		mov	r1, sp			@ malloc space above stack
		add	r2, sp, #0x10000	@ 64k max

(5)
		teq	r4, r5			@ will we overwrite ourselves?
		moveq	r5, r2			@ decompress after image
		movne	r5, r4			@ decompress to final location

(6)
		mov	r0, r5
		mov	r3, r7
		bl	SYMBOL_NAME(decompress_kernel)

(7)
		teq	r4, r5			@ do we need to relocate
		beq	call_kernel		@ the kernel?

(8)
		add	r0, r0, #127
		bic	r0, r0, #127		@ align the kernel length
/*
 * r0     = decompressed kernel length
 * r1-r3  = unused
 * r4     = kernel execution address
 * r5     = decompressed kernel start
 * r6     = processor ID
 * r7     = architecture ID
 * r8-r14 = unused
 */
		add	r1, r5, r0		@ end of decompressed kernel
		adr	r2, reloc_start
		adr	r3, reloc_end
1:		ldmia	r2!, {r8 - r13}		@ copy relocation code
		stmia	r1!, {r8 - r13}
		ldmia	r2!, {r8 - r13}
		stmia	r1!, {r8 - r13}
		cmp	r2, r3
		blt	1b

(9)
		bl	cache_clean_flush
		add	pc, r5, r0		@ call relocation code


/*
 * _load_addr		: 0xc0008000
 * _start		: 0xc0008000
 * _user_stack+4096	: ÃÑ 4KB ¸¸Å­À» stackÀ¸·Î ÇÒ´çÇÏ°Ô µÈ´Ù.
 */
		.type	LC0, #object
LC0:		.word	__bss_start
		.word	_end
		.word	_load_addr
		.word	_start
		.word	user_stack+4096
		.size	LC0, . - LC0

/*
 * Turn on the cache.  We need to setup some page tables so that we
 * can have both the I and D caches on.
 *
 * We place the page tables 16k down from the kernel execution address,
 * and we hope that nothing else is using it.  If we're using it, we
 * will go pop!
 *
 * On entry,
 *  r4 = kernel execution address
 *  r6 = processor ID
 *  r7 = architecture number
 *  r8 = run-time address of "start"
 * On exit,
 *  r0, r1, r2, r3, r8, r9 corrupted
 * This routine must preserve:
 *  r4, r5, r6, r7
 */
(10)
		.align	5
cache_on:	ldr	r1, proc_sa110_type
		eor	r1, r1, r6
		movs	r1, r1, lsr #5		@ catch SA110 and SA1100
		beq	1f
		ldr     r1, proc_sa1110_type
		eor	r1, r1, r6
		movs	r1, r1, lsr #4
@		movne	pc, lr
		bne	cache_off
(11)
1:
		sub	r3, r4, #16384		@ Page directory size
		bic	r3, r3, #0xff		@ Align the pointer
		bic	r3, r3, #0x3f00
(12)
/*
 * Initialise the page tables, turning on the cacheable and bufferable
 * bits for the RAM area only.
 */
		mov	r0, r3
		mov	r8, r0, lsr #18
		mov	r8, r8, lsl #18		@ start of RAM
		add	r9, r8, #0x10000000	@ a reasonable RAM size
		mov	r1, #0x12
		orr	r1, r1, #3 << 10
		add	r2, r3, #16384
1:		cmp	r1, r8			@ if virt > start of RAM
		orrge	r1, r1, #0x0c		@ set cacheable, bufferable
		cmp	r1, r9			@ if virt > end of RAM
		bicge	r1, r1, #0x0c		@ clear cacheable, bufferable
		str	r1, [r0], #4		@ 1:1 mapping
		add	r1, r1, #1048576
		teq	r0, r2
		bne	1b
/*
 * If ever we are running from Flash, then we surely want the cache
 * to be enabled also for our execution instance...  We map 2MB of it
 * so there is no map overlap problem for up to 1 MB compressed kernel.
 * If the execution is in RAM then we would only be duplicating the above.
 */
		mov	r1, #0x1e
		orr	r1, r1, #3 << 10
		mov	r2, pc, lsr #20
		orr	r1, r1, r2, lsl #20
		add	r0, r3, r2, lsl #2
		str	r1, [r0], #4
		add	r1, r1, #1048576
		str	r1, [r0]

		mov	r0, #0
		mcr	p15, 0, r0, c7, c10, 4	@ drain write buffer
		mcr	p15, 0, r0, c8, c7	@ flush I,D TLBs
		mcr	p15, 0, r3, c2, c0	@ load page table pointer
		mov	r0, #-1
		mcr	p15, 0, r0, c3, c0	@ load domain access register
		mrc	p15, 0, r0, c1, c0
		orr	r0, r0, #0x1000		@ I-cache enable
#ifndef DEBUG
		orr	r0, r0, #0x003d		@ Write buffer, mmu
#endif
		mcr	p15, 0, r0, c1, c0
		mov	pc, lr


/*
 * This code is relocatable.  It is relocated by the above code to the end
 * of the kernel and executed there.  During this time, we have no stacks.
 *
 * r0     = decompressed kernel length
 * r1-r3  = unused
 * r4     = kernel execution address
 * r5     = decompressed kernel start
 * r6     = processor ID
 * r7     = architecture ID
 * r8-r14 = unused
 */
		.align	5
reloc_start:	add	r8, r5, r0
		debug_reloc_start
		mov	r1, r4
1:
		.rept	4
		ldmia	r5!, {r0, r2, r3, r9 - r13}	@ relocate kernel
		stmia	r1!, {r0, r2, r3, r9 - r13}
		.endr

		cmp	r5, r8
		blt	1b
		debug_reloc_end

call_kernel:	bl	cache_clean_flush
		bl	cache_off
		mov	r0, #0
		mov	r1, r7			@ restore architecture number
		mov	pc, r4			@ call kernel

/*
 * Here follow the relocatable cache support functions for
 * the various processors.
 */

		.type	proc_sa110_type,#object
proc_sa110_type:
		.word	0x4401a100
		.size	proc_sa110_type, . - proc_sa110_type

		.type	proc_sa1110_type,#object
proc_sa1110_type:
		.word	0x6901b110
		.size	proc_sa1110_type, . - proc_sa1110_type

/*
 * Turn off the Cache and MMU.  ARMv3 does not support
 * reading the control register, but ARMv4 does.
 *
 * On entry,  r6 = processor ID
 * On exit,   r0, r1 corrupted
 * This routine must preserve: r4, r6, r7
 */
		.align	5
cache_off:
#ifdef CONFIG_CPU_ARM610
		eor	r1, r6, #0x41000000
		eor	r1, r1, #0x00560000
		bic	r1, r1, #0x0000001f
		teq	r1, #0x00000600
		mov	r0, #0x00000060		@ ARM6 control reg.
		beq	__armv3_cache_off
#endif
#ifdef CONFIG_CPU_ARM710
		eor	r1, r6, #0x41000000
		bic	r1, r1, #0x00070000
		bic	r1, r1, #0x000000ff
		teq	r1, #0x00007000		@ ARM7
		teqne	r1, #0x00007100		@ ARM710
		mov	r0, #0x00000070		@ ARM7 control reg.
		beq	__armv3_cache_off
#endif
		mrc	p15, 0, r0, c1, c0
		bic	r0, r0, #0x000d
		mcr	p15, 0, r0, c1, c0	@ turn MMU and cache off
		mov	r0, #0
		mcr	p15, 0, r0, c7, c7	@ invalidate whole cache v4
		mcr	p15, 0, r0, c8, c7	@ invalidate whole TLB v4
		mov	pc, lr

__armv3_cache_off:
		mcr	p15, 0, r0, c1, c0	@ turn MMU and cache off
		mov	r0, #0
		mcr	p15, 0, r0, c7, c0	@ invalidate whole cache v3
		mcr	p15, 0, r0, c5, c0	@ invalidate whole TLB v3
		mov	pc, lr

/*
 * Clean and flush the cache to maintain consistency.
 *
 * On entry,
 *  r6 = processor ID
 * On exit,
 *  r1, r2, r12 corrupted
 * This routine must preserve:
 *  r4, r6, r7
 */
		.align	5
cache_clean_flush:
		ldr	r1, proc_sa110_type
		eor	r1, r1, r6
		movs	r1, r1, lsr #5		@ catch SA110 and SA1100
		beq	1f
		ldr	r1, proc_sa1110_type
		eor	r1, r1, r6
		movs	r1, r1, lsr #4
		movne	pc, lr
1:
		bic	r1, pc, #31
		add	r2, r1, #32768
1:		ldr	r12, [r1], #32		@ s/w flush D cache
		teq	r1, r2
		bne	1b

		mcr	p15, 0, r1, c7, c7, 0	@ flush I cache
		mcr	p15, 0, r1, c7, c10, 4	@ drain WB
		mov	pc, lr

/*
 * Various debugging routines for printing hex characters and
 * memory, which again must be relocatable.
 */
#ifdef DEBUG
		.type	phexbuf,#object
phexbuf:	.space	12
		.size	phexbuf, . - phexbuf

phex:		adr	r3, phexbuf
		mov	r2, #0
		strb	r2, [r3, r1]
1:		subs	r1, r1, #1
		movmi	r0, r3
		bmi	puts
		and	r2, r0, #15
		mov	r0, r0, lsr #4
		cmp	r2, #10
		addge	r2, r2, #7
		add	r2, r2, #'0'
		strb	r2, [r3, r1]
		b	1b

puts:		loadsp	r3
1:		ldrb	r2, [r0], #1
		teq	r2, #0
		moveq	pc, lr
2:		writeb	r2
		mov	r1, #0x00020000
3:		subs	r1, r1, #1
		bne	3b
		teq	r2, #'\n'
		moveq	r2, #'\r'
		beq	2b
		teq	r0, #0
		bne	1b
		mov	pc, lr
putc:
		mov	r2, r0
		mov	r0, #0
		loadsp	r3
		b	2b

memdump:	mov	r12, r0
		mov	r10, lr
		mov	r11, #0
2:		mov	r0, r11, lsl #2
		add	r0, r0, r12
		mov	r1, #8
		bl	phex
		mov	r0, #':'
		bl	putc
1:		mov	r0, #' '
		bl	putc
		ldr	r0, [r12, r11, lsl #2]
		mov	r1, #8
		bl	phex
		and	r0, r11, #7
		teq	r0, #3
		moveq	r0, #' '
		bleq	putc
		and	r0, r11, #7
		add	r11, r11, #1
		teq	r0, #7
		bne	1b
		mov	r0, #'\n'
		bl	putc
		cmp	r11, #64
		blt	2b
		mov	pc, r10
#endif


reloc_end:


(13)
		.align
		.section	".stack"
user_stack:	.space	4096

(1)
.sectionÀº »õ·Î¿î sectionÀ» Á¤ÀÇÇÏ´Â °ÍÀÌ´Ù. ¾î¼Àºí·¯¿¡ °ü°èµÈ µð·ºÆ¼ºê µéÀº ¸ðµÎ 'info as'¸¦ »ç¿ëÇØ ã¾Æº¸¸é Á¤È®ÇÑ ¼³¸íÀÌ ³ª¿Í ÀÖ´Ù. #allocÀº allocatableÀ» ÀǹÌÇϰí #execinstrÀº executableÀ» ÀǹÌÇÑ´Ù.

Assabet º¸µå¿¡ ¿Ã¸° Ä¿³ÎÀº ½ÇÇàµÉ ¶§ angelboot¿¡ ÀÇÇØ ½ÇÇàµÇ´Âµ¥ angelboot·ÎºÎÅÍ r0=0, r1=0x19°¡ ³Ñ¾î¿Â´Ù. Áï r1ÀÌ ¾ÆÅ°ÅØÃÄ ³Ñ¹ö°¡ µÈ´Ù. 4.2Àý ÂüÁ¶.

(2)
start°¡ function symbol ÀÓÀ» ³ªÅ¸³½´Ù. ±×¸®°í .rept 8Àº .rept ºÎÅÍ .endr »çÀÌÀÇ ¹®ÀåÀ» 8¹ø ¹Ýº¹Ç϶õ ¼Ò¸®´Ù. Áï mov r0, r0¸¦ 8¹ø ¹Ýº¹ÇÑ´Ù.
(3)
b 1f°¡ ÀǹÌÇÏ´Â °ÍÀº 1À̶õ ½Éº¼·Î Á¡ÇÁÇÏ´Â °ÍÀ» ÀǹÌÇϰí f´Â forward¸¦ ÀǹÌÇØ ÇöÀç À§Ä¡¿¡¼­ ¾ÕÀ¸·Î 1À̶õ ½Éº¼À» ã¾Æ Á¡ÇÁÇÑ´Ù. ¹Ý´ë ¹æÇâÀÎ °æ¿ì´Â b¸¦ »ç¿ëÇÑ´Ù.
(4)
stack À§ÀÇ ¸Þ¸ð¸®¿¡ 64KB¸¦ ÇÒ´çÇϴµ¥ stackÀº 4.3.3Àý¿¡¼­ ÁöÁ¤µÈ °Í ó·³ Ä¿³Î À̹ÌÁöÀÇ ¸¶Áö¸·¿¡ À§Ä¡ÇÑ´Ù. Áï, stackÀ¸·Î ÇÒ´çÇѰ÷ µÚÀÇ ¸Þ¸ð¸®´Â »ç¿ëÇÏÁö ¾Ê´Â ¿µ¿ªÀ̹ǷΠ¿©±â¸¦ ÇÒ´çÇØ »ç¿ëÇÑ´Ù. »õ·Î ÇÒ´çÇÑ ¿µ¿ªÀº ¾ÐÃàÀ» Ç® ¶§ »ç¿ëÇÏ´Â ¿µ¿ªÀÌ´Ù.
(5)
_load_addr°ú _startÀÇ À§Ä¡°¡ °°´Ù¸é ¾ÐÃàÀ» Ǫ´Â ½ÃÀÛÀ§Ä¡¸¦ ¹Ù·Î À§¿¡¼­ ÇÒ´çÇÑ 64KB ÀÌÈÄ¿¡¼­ ºÎÅÍ ½ÃÀÛÇÏ°í °°Áö ¾Ê´Ù¸é _load_addr¿¡ ¾ÐÃàÀ» Ç®¾î ³õ´Â´Ù.
(6)
decompress_kernel()Àº misc.c¿¡ Á¤ÀǵǾî ÀÖ´Ù. ÇÁ·ÎÅä ŸÀÔÀº

ulg decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p, int arch_id);

head.S¿¡¼­ r0¿¡ ³Ñ±ä °ªÀÌ output_start°¡ r1Àº free_mem_ptr_p, r2´Â free_mem_ptr_end_p ±×¸®°í r3ÀÌ arch_id°¡ µÈ´Ù.

(7)
_load_addr°ú _start°¡ ¼­·Î ´Ù¸¥ °æ¿ì´Â call_kernelÀ» ÅëÇØ Ä¿³ÎÀ» ½ÇÇàÇÏ°í °°Àº °æ¿ì´Â ¾ÐÃà Ç®¸° Ä¿³ÎÀ» _load_addr·Î ¿Å±ä´Ù.
(8)
¾ÐÃà Ç®¸° Ä¿³ÎÀ» _load_addr·Î ¿Å±â±â À§ÇØ ¸®·ÎÄÉÀÌ¼Ç ÇÏ´Â Äڵ带 ¾ÐÃà Ç®¸° Ä¿³ÎÀÇ µÚ¿¡ º¹»çÇÑ´Ù. ´Ù½Ã ¸»ÇØ ¾ÐÃà Ç®¸° Ä¿³ÎÀ» ±×´ë·Î _load_addr·Î ¿Å±â¸é ÇöÀç ½ÇÇàµÇ°í ÀÖ´Â head.S¸¦ ¾þ¾î ¾²±â ¶§¹®¿¡ °è¼ÓÇØ¼­ Á¦´ë·Î ½ÇÇàµÇÁö ¾Ê´Â´Ù. ±×·¯¹Ç·Î Àç¹èÄ¡ ÇØÁÖ´Â Äڵ带 ¸ÕÀú ´ëÇÇÇØ ³õ°í ±× Äڵ带 ½ÇÇàÇØ ¾ÐÃà Ç®¸° Ä¿³ÎÀ» ¿Å±ä´Ù.
(9)
ÃÖÁ¾ÀûÀ¸·Î Àç¹èÄ¡ Äڵ带 ½ÇÇàÇÑ´Ù.
(10)
Á¤·ÄÀº 25=32 ¹ÙÀÌÆ®·Î ÇÑ´Ù.
(11)
1·¹º§ ÆäÀÌÁö Å×À̺íÀº ¹Ýµå½Ã 16KB ´ÜÀ§·Î Á¤·ÄµÇ¾ßÇÑ´Ù. 4.1.3ÀýÀ» ÂüÁ¶.
(12)
ÆäÀÌÁö µ¥ÀÌºí ³»¿ëÀ» ä¿ö ³Ö´Â´Ù. ·¥ÀÇ ½ÃÀÛ Á¡Àº 0xc0000000ÀÌÁö¸¸ ½ÇÁ¦ Ä¿³ÎÀÌ ¿Ã·ÁÁö´Â À§Ä¡°¡ 0xc0008000À̹ǷΠ0xc0000000 ~ 0xc0008000 »çÀÌ¿¡ ÆäÀÌÁö Å×À̺íÀ» ¸¸µé°í ¼½¼Ç µð½ºÅ©¸³ÅͷΠä¿ö ³Ö´Â´Ù.

°¢ ¼½¼Ç µð½ºÅ©¸³ÅÍ´Â AP=11, IMP=1, Domain=00À̶õ ¼Ó¼ºÀ» °®´Â´Ù. Assabet º¸µåÀÇ °æ¿ì 0xc0004000 ~ 0xc0008000¿¡ ÆäÀÌÁö Å×À̺íÀÌ ¸¸µé¾îÁø´Ù.

4.4.2. arch/arm/kernel/head-armv.S

4.3.2Àý¿Í 4.4.1Àý¿¡¼­ »ìÆìº» °Í ó·³ Ä¿³Î À̹ÌÁöÀÇ ¾ÐÃàÀÌ Ç®¸®°í Àç¹èÄ¡ ÈÄ¿¡ ½ÇÇàµÇ´Â ÄÚµå´Â stext·Î $(TOPDIR)/arch/arm/kernel/head-armv.S¿¡ Á¤ÀǵǾî ÀÖ´Ù.

/*
 *  linux/arch/arm/kernel/head-armv.S
 *
 *  Copyright (C) 1994-1999 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.
 *
 *  32-bit kernel startup code for all architectures
 */
#include <linux/config.h>
#include <linux/linkage.h>

#include <asm/assembler.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>

#define K(a,b,c)	((a) << 24 | (b) << 12 | (c))

/*
 * We place the page tables 16K below TEXTADDR.  Therefore, we must make sure
 * that TEXTADDR is correctly set.  Currently, we expect the least significant
 * "short" to be 0x8000, but we could probably relax this restriction to
 * TEXTADDR > PAGE_OFFSET + 0x4000
 *
 * Note that swapper_pg_dir is the virtual address of the page tables, and
 * pgtbl gives us a position-independent reference to these tables.  We can
 * do this because stext == TEXTADDR
 *
 * swapper_pg_dir, pgtbl and krnladr are all closely related.
 */
#if (TEXTADDR & 0xffff) != 0x8000
#error TEXTADDR must start at 0xXXXX8000
#endif

		.globl	SYMBOL_NAME(swapper_pg_dir)
		.equ	SYMBOL_NAME(swapper_pg_dir), TEXTADDR - 0x4000

		.macro	pgtbl, reg, rambase
		adr	\reg, stext
		sub	\reg, \reg, #0x4000
		.endm

/*
 * Since the page table is closely related to the kernel start address, we
 * can convert the page table base address to the base address of the section
 * containing both.
 */
		.macro	krnladr, rd, pgtable, rambase
		bic	\rd, \pgtable, #0x000ff000
		.endm

/*
 *  Kernel startup entry point.
 *
 * The rules are:
 *  r0      - should be 0
 *  r1      - unique architecture number
 *  MMU     - off
 *  I-cache - on or off
 *  D-cache - off
 *
 * See linux/arch/arm/tools/mach-types for the complete list of numbers
 * for r1.
 */
(1)
		.section ".text.init",#alloc,#execinstr
		.type	stext, #function
ENTRY(stext)
		mov	r12, r0
/*
 * NOTE!  Any code which is placed here should be done for one of
 * the following reasons:
 *
 *  1. Compatability with old production boot firmware (ie, users
 *     actually have and are booting the kernel with the old firmware)
 *     and therefore will be eventually removed.
 *  2. Cover the case when there is no boot firmware.  This is not
 *     ideal, but in this case, it should ONLY set r0 and r1 to the
 *     appropriate value.
 */
#if defined(CONFIG_ARCH_NETWINDER)
/*
 * Compatability cruft for old NetWinder NeTTroms.  This
 * code is currently scheduled for destruction in 2.5.xx
 */
		.rept	8
		mov	r0, r0
		.endr

		adr	r2, 1f
		ldmdb	r2, {r7, r8}
		and	r3, r2, #0xc000
		teq	r3, #0x8000
		beq	__entry
		bic	r3, r2, #0xc000
		orr	r3, r3, #0x8000
		mov	r0, r3
		mov	r4, #64
		sub	r5, r8, r7
		b	1f

		.word	_stext
		.word	__bss_start

1:
		.rept	4
		ldmia	r2!, {r6, r7, r8, r9}
		stmia	r3!, {r6, r7, r8, r9}
		.endr
		subs	r4, r4, #64
		bcs	1b
		movs	r4, r5
		mov	r5, #0
		movne	pc, r0

		mov	r1, #MACH_TYPE_NETWINDER	@ (will go in 2.5)
		mov	r12, #2 << 24			@ scheduled for removal in 2.5.xx
		orr	r12, r12, #5 << 12
__entry:
#endif
#if defined(CONFIG_ARCH_L7200)
/*
 * FIXME - No bootloader, so manually set 'r1' with our architecture number.
 */
		mov	r1, #MACH_TYPE_L7200
#endif

(2)
		mov	r0, #F_BIT | I_BIT | MODE_SVC	@ make sure svc mode
		msr	cpsr_c, r0			@ and all irqs disabled
		bl	__lookup_processor_type
		teq	r10, #0				@ invalid processor?
		moveq	r0, #'p'			@ yes, error 'p'
		beq	__error
		bl	__lookup_architecture_type
		teq	r7, #0				@ invalid architecture?
		moveq	r0, #'a'			@ yes, error 'a'
		beq	__error
		bl	__create_page_tables
(3)
		adr	lr, __ret			@ return address
		add	pc, r10, #12			@ initialise processor
							@ (return control reg)

		.type	__switch_data, %object
__switch_data:	.long	__mmap_switched
		.long	SYMBOL_NAME(compat)
		.long	SYMBOL_NAME(__bss_start)
		.long	SYMBOL_NAME(_end)
		.long	SYMBOL_NAME(processor_id)
		.long	SYMBOL_NAME(__machine_arch_type)
		.long	SYMBOL_NAME(cr_alignment)
		.long	SYMBOL_NAME(init_task_union)+8192

(4)
		.type	__ret, %function
__ret:		ldr	lr, __switch_data
		mcr	p15, 0, r0, c1, c0
		mov	r0, r0
		mov	r0, r0
		mov	r0, r0
		mov	pc, lr

		/*
		 * This code follows on after the page
		 * table switch and jump above.
		 *
		 * r0  = processor control register
		 * r1  = machine ID
		 * r9  = processor ID
		 */
		.align	5
__mmap_switched:
		adr	r3, __switch_data + 4
		ldmia	r3, {r2, r4, r5, r6, r7, r8, sp}@ r2 = compat
							@ sp = stack pointer
		str	r12, [r2]

		mov	fp, #0				@ Clear BSS (and zero fp)
1:		cmp	r4, r5
		strcc	fp, [r4],#4
		bcc	1b

		str	r9, [r6]			@ Save processor ID
		str	r1, [r7]			@ Save machine type
#ifdef CONFIG_ALIGNMENT_TRAP
		orr	r0, r0, #2			@ ...........A.
#endif
		bic	r2, r0, #2			@ Clear 'A' bit
		stmia	r8, {r0, r2}			@ Save control register values
(5)
		b	SYMBOL_NAME(start_kernel)



(6)
/*
 * Setup the initial page tables.  We only setup the barest
 * amount which are required to get the kernel running, which
 * generally means mapping in the kernel code.
 *
 * We only map in 4MB of RAM, which should be sufficient in
 * all cases.
 *
 * r5 = physical address of start of RAM
 * r6 = physical IO address
 * r7 = byte offset into page tables for IO
 * r8 = page table flags
 */
__create_page_tables:
(7)
		pgtbl	r4, r5				@ page table address

(8)
		/*
		 * Clear the 16K level 1 swapper page table
		 */
		mov	r0, r4
		mov	r3, #0
		add	r2, r0, #0x4000
1:		str	r3, [r0], #4
		str	r3, [r0], #4
		str	r3, [r0], #4
		str	r3, [r0], #4
		teq	r0, r2
		bne	1b

(9)
		/*
		 * Create identity mapping for first MB of kernel to
		 * cater for the MMU enable.  This identity mapping
		 * will be removed by paging_init()
		 */
		krnladr	r2, r4, r5			@ start of kernel
		add	r3, r8, r2			@ flags + kernel base
		str	r3, [r4, r2, lsr #18]		@ identity mapping

(10)
		/*
		 * Now setup the pagetables for our kernel direct
		 * mapped region.  We round TEXTADDR down to the
		 * nearest megabyte boundary.
		 */
		add	r0, r4, #(TEXTADDR & 0xff000000) >> 18 @ start of kernel
		bic	r2, r3, #0x00f00000
		str	r2, [r0]			@ PAGE_OFFSET + 0MB
		add	r0, r0, #(TEXTADDR & 0x00f00000) >> 18
		str	r3, [r0], #4			@ KERNEL + 0MB
		add	r3, r3, #1 << 20
		str	r3, [r0], #4			@ KERNEL + 1MB
		add	r3, r3, #1 << 20
		str	r3, [r0], #4			@ KERNEL + 2MB
		add	r3, r3, #1 << 20
		str	r3, [r0], #4			@ KERNEL + 3MB

(11)
		/*
		 * Ensure that the first section of RAM is present.
		 * we assume that:
		 *  1. the RAM is aligned to a 32MB boundary
		 *  2. the kernel is executing in the same 32MB chunk
		 *     as the start of RAM.
		 */
		bic	r0, r0, #0x01f00000 >> 18	@ round down
		and	r2, r5, #0xfe000000		@ round down
		add	r3, r8, r2			@ flags + rambase
		str	r3, [r0]

		bic	r8, r8, #0x0c			@ turn off cacheable
							@ and bufferable bits
#ifdef CONFIG_DEBUG_LL
		/*
		 * Map in IO space for serial debugging.
		 * This allows debug messages to be output
		 * via a serial console before paging_init.
		 */
		add	r0, r4, r7
		rsb	r3, r7, #0x4000	@ PTRS_PER_PGD*sizeof(long)
		cmp	r3, #0x0800
		addge	r2, r0, #0x0800
		addlt	r2, r0, r3
		orr	r3, r6, r8
1:		str	r3, [r0], #4
		add	r3, r3, #1 << 20
		teq	r0, r2
		bne	1b
#if defined(CONFIG_ARCH_NETWINDER) || defined(CONFIG_ARCH_CATS)
		/*
		 * If we're using the NetWinder, we need to map in
		 * the 16550-type serial port for the debug messages
		 */
		teq	r1, #MACH_TYPE_NETWINDER
		teqne	r1, #MACH_TYPE_CATS
		bne	1f
		add	r0, r4, #0x3fc0
		mov	r3, #0x7c000000
		orr	r3, r3, r8
		str	r3, [r0], #4
		add	r3, r3, #1 << 20
		str	r3, [r0], #4
1:
#endif
#endif
#ifdef CONFIG_ARCH_RPC
		/*
		 * Map in screen at 0x02000000 & SCREEN2_BASE
		 * Similar reasons here - for debug.  This is
		 * only for Acorn RiscPC architectures.
		 */
		add	r0, r4, #0x80			@ 02000000
		mov	r3, #0x02000000
		orr	r3, r3, r8
		str	r3, [r0]
		add	r0, r4, #0x3600			@ d8000000
		str	r3, [r0]
#endif
(12)
		mov	pc, lr



/*
 * Exception handling.  Something went wrong and we can't
 * proceed.  We ought to tell the user, but since we
 * don't have any guarantee that we're even running on
 * the right architecture, we do virtually nothing.
 * r0 = ascii error character:
 *	a = invalid architecture
 *	p = invalid processor
 *	i = invalid calling convention
 *
 * Generally, only serious errors cause this.
 */
__error:
#ifdef CONFIG_DEBUG_LL
		mov	r8, r0				@ preserve r0
		adr	r0, err_str
		bl	printascii
		mov	r0, r8
		bl	printch
#endif
#ifdef CONFIG_ARCH_RPC
/*
 * Turn the screen red on a error - RiscPC only.
 */
		mov	r0, #0x02000000
		mov	r3, #0x11
		orr	r3, r3, r3, lsl #8
		orr	r3, r3, r3, lsl #16
		str	r3, [r0], #4
		str	r3, [r0], #4
		str	r3, [r0], #4
		str	r3, [r0], #4
#endif
1:		mov	r0, r0
		b	1b

#ifdef CONFIG_DEBUG_LL
err_str:	.asciz	"\nError: "
		.align
#endif

(13)
/*
 * Read processor ID register (CP#15, CR0), and look up in the linker-built
 * supported processor list.  Note that we can't use the absolute addresses
 * for the __proc_info lists since we aren't running with the MMU on
 * (and therefore, we are not in the correct address space).  We have to
 * calculate the offset.
 *
 * Returns:
 *	r5, r6, r7 corrupted
 *	r8  = page table flags
 *	r9  = processor ID
 *	r10 = pointer to processor structure
 */
__lookup_processor_type:
		adr	r5, 2f
(14)
		ldmia	r5, {r7, r9, r10}
		sub	r5, r5, r10			@ convert addresses
		add	r7, r7, r5			@ to our address space
		add	r10, r9, r5
		mrc	p15, 0, r9, c0, c0		@ get processor id
(15)
1:		ldmia	r10, {r5, r6, r8}		@ value, mask, mmuflags
		and	r6, r6, r9			@ mask wanted bits
		teq	r5, r6
		moveq	pc, lr
		add	r10, r10, #36			@ sizeof(proc_info_list)
		cmp	r10, r7
		blt	1b
		mov	r10, #0				@ unknown processor
		mov	pc, lr

(16)
/*
 * Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for
 * more information about the __proc_info and __arch_info structures.
 */
2:		.long	__proc_info_end
		.long	__proc_info_begin
		.long	2b
		.long	__arch_info_begin
		.long	__arch_info_end

(17)
/*
 * Lookup machine architecture in the linker-build list of architectures.
 * Note that we can't use the absolute addresses for the __arch_info
 * lists since we aren't running with the MMU on (and therefore, we are
 * not in the correct address space).  We have to calculate the offset.
 *
 *  r1 = machine architecture number
 * Returns:
 *  r2, r3, r4 corrupted
 *  r5 = physical start address of RAM
 *  r6 = physical address of IO
 *  r7 = byte offset into page tables for IO
 */
__lookup_architecture_type:
		adr	r4, 2b
		ldmia	r4, {r2, r3, r5, r6, r7}	@ throw away r2, r3
		sub	r5, r4, r5			@ convert addresses
		add	r4, r6, r5			@ to our address space
		add	r7, r7, r5
1:		ldr	r5, [r4]			@ get machine type
		teq	r5, r1
		beq	2f
		add	r4, r4, #SIZEOF_MACHINE_DESC
		cmp	r4, r7
		blt	1b
		mov	r7, #0				@ unknown architecture
		mov	pc, lr
2:		ldmib	r4, {r5, r6, r7}		@ found, get results
		mov	pc, lr

(1)
¾ÐÃà Ç®¸° Ä¿³ÎÀÇ ½ÇÇà ½ÃÀÛ À§Ä¡·Î 0xc0008000ÀÌ µÈ´Ù. ¹Ù·Î ¹ØÀÇ #if defineÀ¸·Î µÈ µÎ ºÎºÐÀº Assabet º¸µåÀÇ °æ¿ì¿£ ÇØ´ç »çÇ× ¾ø±â ¶§¹®¿¡ ¹«½ÃµÇ°í ³Ñ¾î°£´Ù.
(2)
Assabet º¸µåÀÇ ½ÇÁ¦ ½ÇÇà ÄÚµå ½ÃÀÛÁ¡À¸·Î ÀÎÅÍ·´Æ®¸¦ ºÒ°¡´ÉÀ¸·Î ¸¸µé°í ÇÁ·Î¼¼¼­ ŸÀÔ ¾ÆÅ°ÅØÁ® ŸÀÔÀ» ¾Ë¾Æ³½ ÈÄ ÇÊ¿äÇÑ ÆäÀÌÁö Å×À̺íÀ» ¸¸µé°í ÇÁ·Î¼¼¼­¸¦ ¼³Á¤ÇÑ´Ù.
(3)
ÆäÀÌÁö Å×À̺íÀ» ¸¸µç ÈÄ ¹«¾ð°¡¸¦ ½ÇÇàÇϴµ¥ µ¹¾Æ¿À´Â À§Ä¡´Â __ret°¡ µÇµµ·Ï ÇÑ´Ù. ½ÇÇàµÇ´Â ±× ¹«¾ùÀº r10 + #12·Î Assabetº¸µåÀÇ °æ¿ì __sa1100_setup À̶õ °÷À̵ȴÙ. ÀÌ °÷Àº $(TOPDIR)/arch/arm/mm/proc-sa110.S¿¡ Á¤ÀǵǾî ÀÖ´Ù.
(4)
__sa1100_setupÀÌ ½ÇÇàµÈ ÈÄ µ¹¾Æ¿À´Â °÷ÀÌ À̰÷Àε¥ ´Ù½Ã __switch_data¶õ °÷À¸·Î ºÐ±âÇÒ Áغñ¸¦ ÇÑ´Ù. Áï __mmap_switched¸¦ ½ÇÇàÇÏ°Ô µÈ´Ù.
(5)
ÀÌÁ¦ ¸ðµç Áغñ°¡ ³¡³µ´Ù. ¸®´ª½º Ä¿³ÎÀ» ½ÃÀÛÇÑ´Ù. start_kernelÀº $(TOPDIR)/init/main.c¿¡ Á¤ÀǵǾî ÀÖ´Ù.
(6)
ÃÊ±â ÆäÀÌÁö Å×À̺íÀ» ¼³Á¤ÇÑ´Ù. ¿©±â¼­´Â Ä¿³ÎÀÌ ½ÇÇàµÉ ¸¸Å­¸¸ ¼³Á¤Çϰí Ä¿³ÎÀÌ ÃʱâÈ­ µÇ¸é¼­ ¼³Á¤µÈ´Ù. 4MB Á¤µµ¸é Ä¿³ÎÀÌ ½ÇÇàµÇ´Âµ§ ÃæºÐÇϹǷΠÀÌÁ¤µµ¸¸ ¼³Á¤ÇÑ´Ù.
(7)
ÆäÀÌÁö Å×À̺íÀÇ ½ÃÀÛ ¾îµå·¹½º¸¦ °è»êÇÑ´Ù. r4=0xc0004000ÀÌ µÈ´Ù.
(8)
ÀÌ¹Ì ¼³Á¤µÇ¾î ÀÖ´ø ÆäÀÌÁö Å×À̺íÀ» ¸ðµÎ Áö¿î´Ù.
(9)
ÆäÀÌÁö Å×ÀÌºí¿¡ µé¾î°¥ µð½ºÅ©¸³ÅÍ °ªÀ» ¼³Á¤ÇÑ´Ù. krnladrÀº Ä¿³ÎÀÇ ½ÃÀÛÀÌ À§Ä¡ÇÑ °÷À» 1MB ´ÜÀ§·Î ²÷¾îÁØ °ªÀÌ´Ù. ¿©±â¼± ÆäÀÌÁö Å×À̺íÀ» ¼½¼Ç µð½ºÅ©¸³ÅͷΠä¿ì±â ¶§¹®¿¡ 1MB ´ÜÀ§·Î ²÷À» Çʿ䰡 ÀÖ´Â °ÍÀÌ´Ù. r2=0xc0000000ÀÌ µÈ´Ù(·¥ÀÇ ½ÃÀÛÁ¡).

¼½¼Ç µð½ºÅ©¸³ÅÍÀÇ °ªÀº AP=11, Domain=0, IMP=0, C=1, B=1ÀÇ ¼Ó¼ºÀ» °®´Â´Ù(0xC0E).

[r4, r2, lsr #18]ÀÌ ÀǹÌÇÏ´Â °ÍÀº r2¸¦ 18bit Left ShiftÇϰí r4¿¡ ´õÇÑ´Ù´Â ¶æÀ¸·Î, ÃÖÁ¾ °ªÀº 0xc0007000ÀÌ µÈ´Ù.

ÀÌ °ªÀÌ ÀǹÌÇÏ´Â °ÍÀº ÆäÀÌÁö Å×ÀÌºí ³»ÀÇ Ä¿³Î ½ÃÀÛ ¾îµå·¹½º¸¦ °¡¸®Å°´Â À§Ä¡°¡ µÈ´Ù. ¼½¼Ç µð½ºÅ©¸³ÅÍ´Â 1MB´ÜÀ§·Î ¸Þ¸ð¸®¸¦ °ü¸®Çϰí 32bit ARM ÇÁ·Î¼¼¼­ÀÇ ÃÖ´ë °¡´É ¿ë·®ÀÎ 4GB¸¦ ´Ù·ç±â À§Çؼ± 4G/1M=4K ¸¸Å­ÀÇ µð½ºÅ©¸³ÅͰ¡ ÇÊ¿äÇÏ´Ù. ¶Ç °¢ µð½ºÅ©¸³ÅÍ´Â 4Bytes·Î ±¸¼ºµÇ¹Ç·Î ÆäÀÌÁö Å×À̺íÀº 4K*4Bytes=16KB ¸¸Å­ÀÇ Å©±â°¡ ÇÊ¿äÇÏ´Ù.

±×·¸´Ù¸é Ä¿³ÎÀÌ ½ÃÀÛÇÏ´Â °÷ÀÇ µð½ºÅ©¸³ÅÍ´Â 16KB³»ÀÇ ¾îµð¿¡ À§Ä¡ÇÏ´Â °ÍÀϱî? Ä¿³ÎÀÇ ½ÃÀÛÀÌ Æ÷ÇÔµÈ 1MB ´ÜÀ§ÀÇ ·¥ ½ÃÀÛÁ¡ÀÌ 0xc0000000 À̹ǷΠ0xc0000000/1M*4=0x3000ÀÌ µÈ´Ù. ÆäÀÌÁö Å×À̺íÀÇ ½ÃÀÛÀÌ 0xc0004000À̹ǷΠ¿©±â¿¡ 0x3000À» ´õÇÑ 0xc0007000¿¡ À§Ä¡ÇÑ µð½ºÅ©¸³ÅͰ¡ ¹Ù·Î Ä¿³ÎÀÇ ½ÃÀÛ À§Ä¡¸¦ °¡¸®Å°´Â µð½ºÅ©¸³ÅͰ¡ µÈ´Ù.

(10)
À§¿¡¼­ ¸»ÇÑ´ë·Î ÇÊ¿äÇÑ 4MB ¸¸À» À§ÇÑ µð½ºÅ©¸³Å͸¦ ¼³Á¤ÇÑ´Ù.
(11)
·¥ÀÌ 32MB ·Î Á¤·ÄµÆ°í Ä¿³ÎÀÌ °°Àº 32MB ³»¿¡¼­ ½ÇÇàµÈ´Ù°í °¡Á¤Çϰí ÀÌ¿¡ ÇØ´çÇÏ´Â µð½ºÅ©¸³Å͸¦ Á¶Á¤ÇÑ´Ù.
(12)
¸ðµç ÆäÀÌÁö Å×ÀÌºí ¼³Á¤À» ¸¶Ä¡°í µÇµ¹¾Æ°£´Ù.
(13)
ÇÁ·Î¼¼¼­ ŸÀÔÀ» ¾Ë¾Æ³½´Ù.
(14)
ù ºÎºÐ¿¡ ldmia·Î °ªÀ» ÀÐ¾î ³»´Âµ¥ r7=__proc_info_end, r9=__proc_info_begin, r10=2fÀÇ ¾îµå·¹½º°¡ µÈ´Ù.
(15)
ÇÁ·Î¼¼¼­¿¡ ´ëÇÑ Á¤º¸´Â SA-110, SA-1100, SA-1110ÀÇ Á¤º¸°¡ ¿¬¼ÓÇØ Á¸ÀçÇϹǷΠSA-110 ºÎÅÍ ½ÃÀÛÇØ ÇöÀç ½ÇÇàµÇ°í ÀÖ´Â ÇÁ·Î¼¼¼­¿Í ºñ±³ÇØ ¸Â´Â °ÍÀ» °ñ¶ó Á¤º¸¸¦ ¾ò´Â´Ù.
(16)
__proc_info_end µîÀº $(TOPDIR)/arch/arm/vmlinux.lds¿¡ Á¤ÀǵǾî ÀÖ´Ù.

±×¸®°í ÀÌ °ªÀº $(TOPDIR)/arch/arm/mm/proc-sa110.S¿¡ ´ÙÀ½°ú °°ÀÌ Á¤ÀÇ µÇ¾î ÀÖ´Ù.
__sa1110_proc_info:
	.long	0x6901b110
	.long	0xfffffff0
	.long	0x00000c0e
	b	__sa1100_setup
	.long	cpu_arch_name
	.long	cpu_elf_name
	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT
	.long	cpu_sa1110_info
	.long	sa1100_processor_functions
	.size	__sa1110_proc_info, . - __sa1110_proc_info

(17)
¾ÆÅ°ÅØÃÄ Å¸ÀÔ¿¡ ´ëÇÑ Á¤º¸¸¦ ¾ò¾î³½´Ù. $(TOPDIR)/arch/arm/mach-sa1100/assabet.c¿¡ ´ÙÀ½°ú °°ÀÌ Á¤ÀÇ µÇ¾î ÀÖ´Ù.
MACHINE_START(ASSABET, "Intel-Assabet")
	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
	BOOT_PARAMS(0xc0000100)
	FIXUP(fixup_assabet)
	MAPIO(assabet_map_io)
	INITIRQ(sa1100_init_irq)
MACHINE_END

À§ Á¤ÀÇ¿¡ ´ëÇÑ ¸ÅÅ©·Î´Â $(TOPDIR)/include/asm-arm/mach/arch.h¿¡ ´ÙÀ½°ú °°ÀÌ Á¤ÀÇ µÇ¾î ÀÖ´Ù.
/*
 * Set of macros to define architecture features.  This is built into
 * a table by the linker.
 */
#define MACHINE_START(_type,_name)		\
const struct machine_desc __mach_desc_##_type	\
 __attribute__((__section__(".arch.info"))) = {	\
	nr:		MACH_TYPE_##_type,	\
	name:		_name,

#define MAINTAINER(n)

#define BOOT_MEM(_pram,_pio,_vio)		\
	phys_ram:	_pram,	                \
	phys_io:	_pio,  	                \
	io_pg_offst:	((_vio)>>18)&0xfffc,

#define BOOT_PARAMS(_params)			\
	param_offset:	_params,

#define VIDEO(_start,_end)			\
	video_start:	_start,			\
	video_end:	_end,

#define DISABLE_PARPORT(_n)			\
	reserve_lp##_n:	1,

#define BROKEN_HLT /* unused */

#define SOFT_REBOOT				\
	soft_reboot:	1,

#define FIXUP(_func)				\
	fixup:		_func,

#define MAPIO(_func)				\
	map_io:		_func,

#define INITIRQ(_func)				\
	init_irq:	_func,

#define MACHINE_END				\
};