Re: [問題] Samsung 2442 Porting linux 的問題
我也遇到了類似的問題~
我的板子是AT2440EVB-II使用s3c2440的soc~
bootloader是我自己寫的~(第一次寫bootloader...@@)
我已經可以boot到如下的畫面了~ 可是在booting the kernel的時候~就卡住了
我的console顯示如下:
Uncompressing Linux................................. done, booting the kernel.
到此處就永遠停住不動了~
請問各位大大~這有可能是什麼原因呢?
我附上我的程式碼給大家參考好了~
問題是出在初始化DRAM controller的參數不對嗎?
還是我copy memory超出範圍?
還是其他CPU的參數設定不對?
我是將boot loader燒到0x0的位址~ Linux kernel燒到0x10000的位址~
kernel的大小約為1.4Mb~ boot loader會將之拷貝到0x30030000的位址執行~
板子的規格書上寫NOR flash是2Mb~SDRAM是64Mb~
我找了很久找不出原因..非常感謝各位大大的幫忙!....@@
========================================================================
檔名: start_vector.S
# define pWTCON 0x53000000
# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */
# define INTSUBMSK 0x4A00001C
# define CLKDIVN 0x4C000014 /* clock divisor register */
.global _start
_start: b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
_undefined_instruction:
b _undefined_instruction
_software_interrupt:
b _software_interrupt
_prefetch_abort:
b _prefetch_abort
_data_abort:
b _data_abort
_not_used:
b _not_used
_irq:
b _irq
_fiq:
b _fiq
reset:
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0xd3
msr cpsr,r0
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]
turn_off_interrupt:
mov r1, #0xffffffff
ldr r0, =INTMSK
str r1, [r0]
ldr r1, =0x7fff
ldr r0, =INTSUBMSK
str r1, [r0]
setup_clock:
ldr r0, =CLKDIVN
mov r1, #0x7
str r1, [r0]
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #(1<<31 | 1<<30)
mcr p15, 0, r0, c1, c0, 0
sdram_init:
ldr r0, =0x48000000
ldr r1, =(0x2 << 28 | 0x2 << 24 | 0x1 << 1)
str r1,[r0]
ldr r0, =0x48000004
mov r1, #0x00000700
str r1,[r0]
ldr r0, =0x48000008
mov r1, #0x00000700
str r1,[r0]
ldr r0, =0x4800000C
mov r1, #0x00000700
str r1,[r0]
ldr r0, =0x48000010
mov r1, #0x00000700
str r1,[r0]
ldr r0, =0x48000014
mov r1, #0x00000700
str r1,[r0]
ldr r0, =0x48000018
mov r1, #0x00000700
str r1,[r0]
ldr r0, =0x4800001c
ldr r1, =(0x3 <<15 | 1<<2 |1)
str r1, [r0]
ldr r0, =0x48000020
ldr r1, =(0x3 <<15 | 1<<2 |1)
str r1,[r0]
ldr r0, =0x48000024
mov r1, #(1<<23 | 3 <<18)
str r1, [r0]
ldr r0, =0x48000028
mov r1, #(1<<5 | 1 <<4 | 1)
str r1, [r0]
ldr r0, =0x4800002c
mov r1, #0x30
str r1, [r0]
ldr r0, =0x48000030
mov r1, #0x30
str r1, [r0]
ldr sp,=0x33ff0000
ldr pc,_start_armboot
_start_armboot: .word start_armboot
============================================================
檔名: main.c
#define GPBCON ((volatile unsigned *)0x56000010)
#define GPBDAT ((volatile unsigned *)0x56000014)
#define GPBUP ((volatile unsigned *)0x56000018)
#define GPHCON ((volatile unsigned *)0x56000070)
#define GPHDAT ((volatile unsigned *)0x56000074)
#define GPHUP ((volatile unsigned *)0x56000078)
#define UPLLCON ((volatile unsigned *)0x4C000008)
#define MPLLCON ((volatile unsigned *)0x4C000004)
#define CLKDIVN ((volatile unsigned *)0x4C000014)
#define CAMDIVN ((volatile unsigned *)0x4C000018)
#define LED1_ON() (*GPBDAT &= ~(0x1))
#define LED2_ON() (*GPBDAT &= ~(0x2))
#define LED1_OFF() (*GPBDAT |= (0x1))
#define LED2_OFF() (*GPBDAT |= (0x2))
void delay(int time) {
int i;
for( i = 0; i < time; i ++);
}
void __div0() {
while(1);
}
#define MDIV 0x6e
#define PDIV 0x3
#define SDIV 0x1
#define CONFIG_SYS_CLK_FREQ 16934400 /* AT2440-II uses a 16.9344MHz oscillator.*/
void setup_clock() {
*MPLLCON = (MDIV<<12)+(PDIV<<4)+(SDIV);
}
void setup_serial() {
unsigned volatile long *ULCON,*UCON,*UFCON,*UMCON,*UBRDIV;
unsigned int Fin;
unsigned int MPLL;
unsigned int reg;
Fin=CONFIG_SYS_CLK_FREQ;
MPLL=2*(Fin)*(MDIV+8)/(PDIV+2)/(2);
reg = (MPLL/6) / (16* 115200) -1;
UFCON=(unsigned long *)0x50000008;
*(UFCON)=0x7; /*enble FIFO*/
UMCON=(unsigned long *)0x5000000C;
*(UMCON)=0x0;
ULCON=(unsigned long *)0x50000000;
*(ULCON)=(( 0<<3)|(0)<<2|3); /* 8-n-1 */
UCON=(unsigned long *)0x50000004;
*(UCON)=0x5;
UBRDIV=(unsigned long *)0x50000028;
*(UBRDIV)=reg;
/* gpio UART0 init */
*GPHCON=0xAA;
*GPHUP=0x7ff;
delay(0xffff);
}
void putc(const char c) {
unsigned volatile long *UTRSTAT;
unsigned volatile char *UTXH;
UTRSTAT=(unsigned long*)0x50000010;
while( !(*UTRSTAT & 0x2));
UTXH=(unsigned char *)0x50000020;
*UTXH=c;
}
int getc (void)
{
unsigned volatile long *UTRSTAT;
unsigned volatile char *URXH;
UTRSTAT=(unsigned long*)0x50000010;
URXH=(unsigned char*)0x50000024;
while (!(*UTRSTAT & 0x1));
return (*URXH) & 0xff;
}
void putstr(char *p) {
while(*p!=0) {
putc(*p);
p++;
}
putc('\r');
}
/* See also ARM920T Technical reference Manual */
#define C1_MMU (1<<0) /* mmu off/on */
#define C1_ALIGN (1<<1) /* alignment faults off/on */
#define C1_DC (1<<2) /* dcache off/on */
#define C1_BIG_ENDIAN (1<<7) /* big endian off/on */
#define C1_SYS_PROT (1<<8) /* system protection */
#define C1_ROM_PROT (1<<9) /* ROM protection */
#define C1_IC (1<<12) /* icache off/on */
#define C1_HIGH_VECTORS (1<<13) /* location of vectors: low/high addresses */
int cleanup_before_linux (void)
{
/*
* this function is called just before we call linux
* it prepares the processor for linux
*
* we turn off caches etc ...
*/
unsigned long i;
/* turn off I/D-cache */
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
i &= ~(C1_DC | C1_IC);
asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
/* flush I/D-cache */
i = 0;
asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i));
return (0);
}
void cp_mem()
{
unsigned long *dst;
unsigned long *src;
int (*f)(void *);
dst=(unsigned long *)0x30030000;
src=(unsigned long *)0x10000;
while (src < (unsigned long *)0x200000) {
*dst = *src;
dst++;
src++;
}
cleanup_before_linux();
putstr("image ready, any key continue\n");
getc();
f=(int *)0x30030000;
f(1);
}
void start_armboot (void)
{
setup_clock();
setup_serial();
putstr("Hello\n");
putstr("Any key to continue\n");
getc();
putstr("Yes\n");
cp_mem();
}
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 218.160.188.71
※ 編輯: BlueAlaska 來自: 218.160.188.71 (03/03 01:19)
※ 編輯: BlueAlaska 來自: 218.160.188.71 (03/03 01:20)
→
03/03 23:44, , 1F
03/03 23:44, 1F
討論串 (同標題文章)
完整討論串 (本文為第 2 之 3 篇):
LinuxDev 近期熱門文章
PTT數位生活區 即時熱門文章