Stefan wrote:
> I've never seen such a source file. pre-processor instructions mixed
> with assembler code, yes - this are the *.S files, but mixed with linker
> instructions... no. Can you give an example?
>
> Stefan
Here it is : there are linker instruction in this source file whereas
usually I've seen them in a linker script. thanks for your help.
/*
* 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
*
* added S3C4510 code by Mac Wang
* added S3C4530 code by Arcturus Networks Inc.
* added S3C2500 code by Arcturus Networks Inc.
* added TI TMS320DM270 code by Chee Tim Loh
<cheetim_loh@innomedia.com.sg>.
*
*/
#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.
*/
/*
* 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.
*/
.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_L7200)
/*
* FIXME - No bootloader, so manually set 'r1' with our architecture
number.
*/
mov r1, #MACH_TYPE_L7200
#elif defined(CONFIG_ARCH_INTEGRATOR)
mov r1, #MACH_TYPE_INTEGRATOR
#elif defined(CONFIG_ARCH_P52)
mov r1, #MACH_TYPE_P52
#elif defined(CONFIG_ARCH_CX821XX)
mov r1, #MACH_TYPE_CX821XX
#elif defined(CONFIG_ARCH_SWARM)
mov r1, #MACH_TYPE_SWARM
#elif defined(CONFIG_BOARD_SNDS100)
mov r1, #MACH_TYPE_SNDS100
#elif defined (CONFIG_BOARD_SMDK40100)
mov r1, #MACH_TYPE_S3C3410
#elif defined (CONFIG_BOARD_MBA44)
mov r1, #MACH_TYPE_S3C44B0X
#elif defined(CONFIG_BOARD_SMDK2500)
mov r1, #MACH_TYPE_SMDK2500
#elif defined(CONFIG_BOARD_S3C2500REFRGP)
mov r1, #MACH_TYPE_S3C2500REFRGP
#elif defined(CONFIG_ARCH_LPC)
mov r1, #MACH_TYPE_LPC22XX & 0xff
orr r1, r1, #MACH_TYPE_LPC22XX & 0xff00
#endif
mov r0, #F_BIT | I_BIT | MODE_SVC @ make sure svc mode
msr cpsr_c, r0 @ and all irqs disabled
#if defined(CONFIG_ARCH_ATMEL)
adr r5, LC0
ldmia r5, {r5, r6, r8, r9, sp} @ Setup stack
/* Copy data sections to their new home. */
/* Clear BSS */
mov r4, #0
1: cmp r5, r8
strcc r4, [r5],#4
bcc 1b
/* FIXME */
#if 0
/* Put initial values into stack. This would normally be done
by sched_init() in kernel/sched.c, but that would overwrite the
stack we're already using. That would be bad.
*/
mov r5, sp
sub r5, r5, #0x2000
ldr r4, L_STACK_MAGIC
str r4, [r5], #4
ldr r4, L_STACK_UNTOUCHED_MAGIC
1: cmp r5, sp
strcc r4, [r5], #4
bcc 1b
#endif
/* Pretend we know what our processor code is (for arm_id) */
@@@ ldr r2, =0x41000000
@@@ orr r2, r2, #0x7000 @ FIXME --> 0x41007000
ldr r2, L_AT91_SF_CIDR
ldr r2, [r2] @ read processor id
str r2, [r6]
mov r2, #MACH_TYPE_ATMEL
str r2, [r9]
mov fp, #0
b start_kernel
LC0: .long __bss_start
.long processor_id
.long _end
.long __machine_arch_type
.long init_task_union+8192
#endif
adr lr, __ret @ return address
add pc, r10, #12 @ initialise processor
@ (return control reg)
__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
__ret: ldr lr, __switch_data
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]
#ifdef CONFIG_RAM_ATTACHED_ROMFS
# ifdef CONFIG_ARCH_DM270
/*
* Move ROM filesystem above bss :-)
*/
ldr r3, L_DM270_ROMFS @ Get end of data
ldr r10, [r3, #8] @ Get size of ROMFS (big-endian)
#ifndef CONFIG_CPU_BIG_ENDIAN
mov r2, #0 @ Convert to little-endian
and fp, r10, #0x000000ff
orr r2, r2, fp, lsl #24
and fp, r10, #0x0000ff00
orr r2, r2, fp, lsl #8
and fp, r10, #0x00ff0000
orr r2, r2, fp, lsr #8
and fp, r10, #0xff000000
orr r2, r2, fp, lsr #24
mov r10, r2
#endif
add r10, r10, #8 @ Allow for rounding
bic r10, r10, #3 @ Whole words
ldr fp, L_DM270_ROMFS + 4 @ Set up destination
mov r2, r3 @ Copy of _edata
add r3, r3, r10 @ Copy from end
add fp, fp, r10
ldr r10, L_DM270_RAMSTART
str fp, [r10]
_copy_romfs:
ldr r10, [r3, #-4]! @ Copy dword
str r10, [fp, #-4]!
cmp r3, r2 @ Check if at end
bne _copy_romfs
# endif
#endif
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
b SYMBOL_NAME(start_kernel)
/*
* 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
/*
* 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
ldmia r5, {r7, r9, r10}
sub r5, r5, r10 @ convert addresses
add r7, r7, r5 @ to our address space
add r10, r9, r5
#ifdef CONFIG_CPU_WITH_MCR_INSTRUCTION
mrc p15, 0, r9, c0, c0 @ get processor id
#else
# warning "FIXME: Get Processor ID without MCR Instruction"
@ A possible code
@ldr r9, PROCESSOR_ID_MEM_LOCATION
@ldr r9, [r9]
#ifdef CONFIG_ARCH_DM270
ldr r9, L_DM270_PID
#endif
#endif
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
/*
* 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
/*
* 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 r7, r7, lsr #18 @ pagetable byte offset
mov pc, lr
L_AT91_SF_CIDR: .long 0xfff00000
#ifdef CONFIG_ARCH_DM270
L_DM270_PID: .long 0xd2700000
# ifdef CONFIG_RAM_ATTACHED_ROMFS
.global _ramstart
_ramstart: .long 0
L_DM270_ROMFS: .long _edata
.long _ebss
L_DM270_RAMSTART:
.long _ramstart
# endif
#endif