All pastes #993030 Raw Edit

Someone

public text v1 · immutable
#993030 ·published 2008-04-22 09:12 UTC
rendered paste body
/* Embedded OS Loader
 *
 *   Copyright 2005 Vivien Chappelier <vivien.chappelier@free.fr>
 *
 *	initialization code and linux entry code
 *
 * the bootloader is loaded at 	 0x8c080000 (virtual, cached)
 *				 0x10080000 (physical) = start of SDRAM
 * it is relocated at 0x8d000000 (virtual, cached) to leave room for the kernel
 */
	
.text
.align

_start:
.type   _start,#function
.globl  _start
	
	/* relocate */
	mov r0,   #0x8c000000  /* load address */
	orr r0, r0, #0x080000
	mov r1,   #0x8d000000  /* run address */
	ldr r2, end
	ldr r3, start
	sub r3, r2, r3
	mov r2, r3, lsr #2
	add r2, r2, #1
1:                             /* copy */
	ldr r3, [r0]
	add r0, r0, #4
	str r3, [r1]
	add r1, r1, #4
	subs r2, r2, #1
	bhi 1b

	ldr r0, p_enter_reloc  /* position independent load */
	mov pc, r0	       /* jump to relocated code */
enter_reloc:
	
	/* call main bootloader */
	bl	main

	/* die in endless loop */
2:
	b 2b

irq_disable:
.type   irq_disable, #function
.globl  irq_disable
	
	/* disable interrupts */
	mov	r0, #0xd3                             /* set SVC mode and   */
	msr	cpsr_c, r0			      /* disable irqs       */
	mov	pc, lr
	
/*****************************************************************************/
/* Prepare the CPU for the linux kernel and execute it
 * r0 = address r1 = machine type r2 = boot parameters tag list
 *
 * This code is position independent
 *	
 * The requirements for linux are:
 * MMU = off, D-cache = off, I-cache = dont care, r0 = 0, r1 = machine nr.
 *
 * Memory at 0x10000000 (physical) is mapped at 0x10000000 (virtual, uncached).
 * The linux kernel is expected to be at 0x10008000 (physical).
 */
enter_linux:
.type   enter_linux, #function
.globl  enter_linux

	/* save address and machine type for later */
	mov r4, r0
	mov r5, r1
	mov r6, r2
	
	/* jump to common physical/virtual address space (uncached) */
	ldr r0, p_enter_physical
	bic r0, r0, #0x8c000000
	orr r0, r0, #0x10000000 /* common physical/virtual uncached base */
	mov pc, r0
enter_physical:

	/* disable interrupts */
	mov	r0, #0xd3                             /* set SVC mode and   */
	msr	cpsr_c, r0			      /* disable irqs       */
	
	/* get rid of any locked down entries in the TLB by setting the 8  */
	/* entries to the first 8 kB of physical memory and clearing them. */
	mrc p15, 0, r0, c10, c0, 0 /* set the preserve bit */
	orr r0, r0, #1
	mcr p15, 0, r0, c10, c0, 0

	mov r1, #0
	mov r2, #8
flush_tlb_locked_set:
	mcr p15, 0, r1, c8, c7, 1 /* invalidate single entry           */
	ldr r3, [r1]		  /* TLB miss to load the locked entry */
	add r1, r1, #1024	  /* increase modified virtual address */
	subs r2, r2, #1
	bhi flush_tlb_locked_set

	mov r1, #0
	mov r2, #8
flush_tlb_locked_clear:
	mcr p15, 0, r1, c8, c7, 1 /* invalidate single entry           */
	add r1, r1, #1024	  /* increase modified virtual address */
	subs r2, r2, #1
	bhi flush_tlb_locked_clear

	mrc p15, 0, r0, c10, c0, 0 /* clear the preserve bit */
	bic r0, r0, #1
	mcr p15, 0, r0, c10, c0, 0 
	
	/* flush the D-cache */
flush_cache:
	mrc p15, 0, r0, c7, c14, 3 /* test clean and invalidate */
	bne flush_cache

	/* deactivate the D-cache and MMU */
	mrc p15, 0, r0, c1, c0, 0  /* read control register */
	bic r0, r0, #5		   /* clear MMU and D-cache bits */
	mcr p15, 0, r0, c1, c0, 0  /* write control register  */
	
	/* invalidate the TLB */
	mcr p15, 0, r0, c8, c7	   /* flush the unlocked entries */

	/* set r0 to zero and r1 to machine type and r2 to boot params */
	mov r0, #0   
	mov r1, r5
	mov r2, r6

	/* jump to linux */
	mov pc, r4  /* linux load address */

/*****************************************************************************/
/* In case something went wrong during loading, fill the screen with red
   and enter an endless loop.
*/

dead_start:
.type   dead_end,#function
.globl  dead_start

	mov r0, #0x20000000  /* framebuffer address */
	add r0, r0, #0x1000
	add r0, r0,   #0x20
	mov r1, #0xf800      /* red color */
	mov r2, #0x9700      /* framebuffer size */
	add r2, r2, #0x40
1:
	strh r1, [r0]
	add  r0, r0, #2
	subs r2, r2, #1
	bhi 1b
	
	/* die in endless loop */
2:
	b 2b
dead_end:
.globl  dead_end

.align
p_enter_physical:	.word	enter_physical
p_enter_reloc:		.word	enter_reloc
start:			.word	_start
end:			.word	_end
malloc_base:		.word	_malloc_base
.globl  start
.globl  end
.globl  malloc_base