ts-7000
[Top] [All Lists]

Re: [ts-7000] Re: help in loading linux kernel from sdcard.

To:
Subject: Re: [ts-7000] Re: help in loading linux kernel from sdcard.
From: "Breton M. Saunders" <>
Date: Thu, 02 Dec 2010 10:41:43 +0000
HI Tama,

   Apologies - I started writing you a reply yesterday, but got 
distracted by work.

   First - I think you're memory setup isn't right.  The ep93xx maps 
physical memory into 8MiB pages, this is why you see several mem atag 
entries in my sample code.  The entries were for a single 32MiB chip.  
You'll need to check the ep93xx manual to work out how your chip is 
mapped, then enter the correct atag entries.  Also, specify all of the 
available ram to the kernel.  Once you have transferred control to the 
kernel, your bootstrap loader is finished - let the kernel reuse that 
memory.  The initrd and kernel itself will be handled by the kernel - 
i.e. the kernel will work out how to avoid overwriting itself and the 
ramdisk.

   A couple of other things, I would assume that your code is called 
from ARM mode (if you're using redboot to start it).  Since linux_start 
is in thumb mode, it isn't sufficient to just jump to linux_start.  What 
you will need to do is flip the processor into THUMB mode.  You can do 
this using the SWTHUMB macro I've included below.  I apologize for 
failing to include this in the initial code I sent you.

         .macro SWTHUMB
         add     r0, pc, #1
         bx      r0
         .THUMB
         .endm

         .macro SWARM
         bx      pc
         nop
         .ARM
         .endm


What you need to do is write SWTHUMB directly underneath your 
linux_start: label.  Assemble your code without specifying the thumb 
output mode - the assembler knows that after seeing a .THUMB directive 
that it is to assemble thumb instructions.  Likewise, with .ARM, it will 
expect ARM 32 bit instructions afterwards and generate the appropriate 
op-codes.

Second thing, you're going to need to do some low level debugging.  To 
do this you'll need a serial console (as expected!) and a couple of 
routines for banging data out the serial port.

Add this to your code, which is derived (or even copied) from 
serial_blaster off of the ts7000 group:

Set_UART_115200:
         ldr     r2, uartbase
         ldr     r3, syscon

         mov     r6, sp                  @ store sp - we're going to use 
sp for indirect addressing

         mov     r0, #0
         str     r0, [r2, #0x14]         @ UART1ctrl
         str     r0, [r2, #0x04]         @ UART1RXSts

         mov     r0, #3
         mov     sp, r2                  @ uartbase to sp
         str     r0, [sp, #0x100]        @ modem control

         mov     r0, #0xaa
         mov     sp, r3                  @ syscon to sp
         str     r0, [sp, #0xc0]         @ unlock syscon

         mov     r4, #0x20               @ 20 to r4, shift to position
         lsl     r4, #24
         ldr     r0, [sp, #0x04]         @PwrCnt to r0
         orr     r0, r4
         str     r0, [sp, #0x04]         @ write to set uart to 14.7456 
mhz clock


         mov     r0, #0xaa
         mov     sp, r3                  @ syscon to sp
         str     r0, [sp, #0xc0]         @ unlock syscon

         ldr     r0, [sp, #0x80]
         mov     r4, #04
         lsl     r4, #16                 @ r4 gets 0x40000
         bic     r0, r4                  @ not bit 0x40000
         str     r0, [sp, #0x80]         @ disable uart 1

         mov     r0, #3                  @ divisor 7=115200 baud, 3=230400
         str     r0, [r2, #0x10]         @ UART1LinCtrlLow

         mov     r0, #0
         str     r0, [r2, #0x0c]         @ UART1LinCtrlMid

         mov     r0, #0x60
         str     r0, [r2, #0x08]         @ UART1LinCtrlHigh

         mov     r0, #0x1
         str     r0, [r2, #0x14]         @ UART1Ctrl

         mov     r0, #0xaa
         str     r0, [sp, #0xc0]         @ unlock syscon

         ldr     r0, [sp, #0x80]         @ load syscon uart entry
         orr     r0, r4                  @ set the uart bit
         str     r0, [sp, #0x80]         @ enable UART1

         mov     sp, r6                  @ recover the stack pointer
         bx      lr                      @ return

Flush_UART:
         push    {r0, r1, r2, r3, lr}
         mov     r2, #0x08
         ldr     r0, uartbase
1:      ldr     r1, [r0, #0x18]
         tst     r1, r2
         bne     1b

         pop     {r0, r1, r2, r3, pc}    @ return !

Output_Byte:
         push    {r0, r1, lr}
         bl      Flush_UART
         ldr     r1, uartbase
         strb    r0, [r1]
         pop     {r0, r1, pc}            @ return

Output_Word:
         push    {r0, r1, lr}
         mov     r1, r0                  @ preserve r0
         lsr     r0, #24
         bl      Output_Byte
         mov     r0, r1
         lsr     r0, #16
         bl      Output_Byte
         mov     r0, r1
         lsr     r0, #8
         bl      Output_Byte
         mov     r0, r1
         bl      Output_Byte
         pop     {r0, r1, pc}



@ Output_String:
Output_String:
         push    {r0, r1, lr}
         mov     r1, r0                  @ string source to r1
1:      ldrb    r0, [r1]                @ load byte at r1
         cmp     r0, #0                  @ is it zer0?
         beq     2f
         bl      Output_Byte
         add     r1, #1
         b       1b

2:      pop     {r0, r1, pc}            @ return
         .ltorg


@ Input byte
Input_Byte:
         push    {r1, r2, r3, lr}
         ldr     r2, uartbase            @ uart base

         mov     r3, #0x10               @ bit to test
1:      ldr     r1, [r2, #0x18]         @ wait if buffer is busy
         tst     r1, r3
         bne     1b

         ldrb    r0, [r2]
         pop     {r1, r2, r3, pc}        @ and return

Input_Word:
         push    {r1, r2, lr}
         bl      Input_Byte              @ least significant byte
         mov     r1, r0

         bl      Input_Byte
         lsl     r0, #8                  @ byte 8-16
         orr     r1, r0

         bl      Input_Byte
         lsl     r0, #16
         orr     r1, r0

         bl      Input_Byte
         lsl     r0, #24
         orr     r0, r1

         pop     {r1, r2, pc}            @ and return



Then, put in your data segment:

hello: .asciz "Hello world\n\r"
           .align 4

linux_start:
     SWTHUMB
     bl Set_UART_115200
     adr r0, hello
     bl Output_String
       ...

These primitives will get you a long way.
The input routines can be used to implement a command line interface if 
you wish.

Finally, you will want to compile your kernel with low-level debugging 
enabled.  If you have specified an incorrect machine id you will get 
absolutely no information back out of the kernel unless you have low 
level debugging enabled.

Let me know how you get on!

     Cheers,

     -Brett



On 12/02/2010 08:42 AM, pritam wrote:
>             .word   4               @ size of memory tag
>                  .word   ATAG_MEM
>                  .word   0x03F7B098      @ size
>                  .word   0x00041f68      @ start
>    



------------------------------------

Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/ts-7000/

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http://groups.yahoo.com/group/ts-7000/join
    (Yahoo! ID required)

<*> To change settings via email:
     
    

<*> To unsubscribe from this group, send an email to:
    

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/

<Prev in Thread] Current Thread [Next in Thread>
Admin

Disclaimer: Neither Andrew Taylor nor the University of NSW School of Computer and Engineering take any responsibility for the contents of this archive. It is purely a compilation of material sent by many people to the birding-aus mailing list. It has not been checked for accuracy nor its content verified in any way. If you wish to get material removed from the archive or have other queries about the archive e-mail Andrew Taylor at this address: andrewt@cse.unsw.EDU.AU