diff --git a/qiboot/Makefile b/qiboot/Makefile index b49ee49..4d7bb46 100644 --- a/qiboot/Makefile +++ b/qiboot/Makefile @@ -14,8 +14,6 @@ # MA 02111-1307 USA # -include ./config.mk - all : cd src ; make all diff --git a/qiboot/README b/qiboot/README index ab9cad4..e69de29 100644 --- a/qiboot/README +++ b/qiboot/README @@ -1,6 +0,0 @@ -use follow command to run this program -start OpenOCD,then do this - - > reset halt - > load_image /path/to/led_on 0 - > resume diff --git a/qiboot/src/Makefile b/qiboot/src/Makefile index e092d01..27d4458 100644 --- a/qiboot/src/Makefile +++ b/qiboot/src/Makefile @@ -14,20 +14,32 @@ # MA 02111-1307 USA # -LDS =kboot-stage1.lds -INCLUDE =../include -IMAGE =../image -CFLAGS =-Wall -I $(INCLUDE) -g -c -o +include ../config.mk -all:start.S blink_led.c lowlevel_init.S +LDS = kboot-stage1.lds +INCLUDE = ../include +IMAGE = ../image +CFLAGS = -Wall -I $(INCLUDE) -g -c -o + +START = start.o lowlevel_init.o +COBJS = start_kboot.o nand_read.o + +SRCS := $(START: .o=.S) $(COBJS: .o=.c) + +all:start.S lowlevel_init.S nand_read.c start_kboot.c $(CC) $(CFLAGS) start.o start.S - $(CC) $(CFLAGS) blink_led.o blink_led.c $(CC) $(CFLAGS) lowlevel_init.o lowlevel_init.S - $(LD) -T$(LDS) -g start.o blink_led.o lowlevel_init.o -o led.o - $(OBJCOPY) -O binary -S led.o $(IMAGE)/led_on + $(CC) $(CFLAGS) nand_read.o nand_read.c + $(CC) $(CFLAGS) start_kboot.o start_kboot.c + $(LD) -T$(LDS) -g $(START) $(COBJS) -o start_kboot_all.o + $(OBJCOPY) -O binary -S start_kboot_all.o $(IMAGE)/start + +blink_led:led_on.S + $(CC) $(CFLAGS) led_on.o led_on.S + $(LD) -g led_on.o -o led_on_temp.o + $(OBJCOPY) -O binary -S led_on_temp.o $(IMAGE)/led_on clean: rm -f *.o - rm -f led_on rm -f $(IMAGE)/* diff --git a/qiboot/src/blink_led.c b/qiboot/src/blink_led.c index f5abb74..92c8211 100644 --- a/qiboot/src/blink_led.c +++ b/qiboot/src/blink_led.c @@ -52,9 +52,3 @@ int blink_led() } return 0; } - -int start_armboot() -{ - blink_led(); - return 0; -} diff --git a/qiboot/src/kboot-stage1.lds b/qiboot/src/kboot-stage1.lds index a1c9529..6393fdb 100644 --- a/qiboot/src/kboot-stage1.lds +++ b/qiboot/src/kboot-stage1.lds @@ -34,7 +34,7 @@ SECTIONS { start.o (.text) lowlevel_init.o(.text) - blink_led.o (.text) + start_kboot.o (.text) *(.text) } diff --git a/qiboot/src/led_on.S b/qiboot/src/led_on.S new file mode 100644 index 0000000..1ebcaa9 --- /dev/null +++ b/qiboot/src/led_on.S @@ -0,0 +1,37 @@ +_start: + mov ip, sp + stmfd sp!, {fp, ip, lr, pc} + sub fp, ip, #4 + ldr r2, .L4 + mov r3, #5 + str r3, [r2, #0] + ldr r2, .L4+4 + ldr r3, .L4+8 + str r3, [r2, #0] +.L2: + ldr r2, .L4+12 + ldr r3, .L4+12 + ldr r3, [r3, #0] + bic r3, r3, #1 + str r3, [r2, #0] + ldr r0, .L4+8 + bl delay + ldr r2, .L4+12 + ldr r3, .L4+12 + ldr r3, [r3, #0] + orr r3, r3, #1 + str r3, [r2, #0] + ldr r0, .L4+8 + bl delay + b .L2 +.L5: + .align 2 +.L4: + .word 1442840592 + .word 1442840600 + .word 65535 + .word 1442840596 + delay: + subs r0,r0,#0x1 + bne delay + mov pc,lr diff --git a/qiboot/src/nand_read.c b/qiboot/src/nand_read.c new file mode 100644 index 0000000..2ae0cbe --- /dev/null +++ b/qiboot/src/nand_read.c @@ -0,0 +1,124 @@ +/* + * nand_read.c: Simple NAND read functions for booting from NAND + * + * This is used by cpu/arm920/start.S assembler code, + * and the board-specific linker script must make sure this + * file is linked within the first 4kB of NAND flash. + * + * Taken from GPLv2 licensed vivi bootloader, + * Copyright (C) 2002 MIZI Research, Inc. + * + * Author: Hwang, Chideok + * Date : $Date: 2004/02/04 10:37:37 $ + * + * u-boot integration and bad-block skipping (C) 2006 by OpenMoko, Inc. + * Author: Harald Welte + */ + + +#define NAND_CMD_READ0 0 +#define NAND_CMD_READ1 1 +/* Extended commands for large page devices */ +#define NAND_CMD_READSTART 0x30 + +#define __REGb(x) (*(volatile unsigned char *)(x)) +#define __REGw(x) (*(volatile unsigned short *)(x)) +#define __REGi(x) (*(volatile unsigned int *)(x)) +#define NF_BASE 0x4e000000 +#define NFCONF __REGi(NF_BASE + 0x0) +#define NFCONT __REGi(NF_BASE + 0x4) +#define NFCMD __REGb(NF_BASE + 0x8) +#define NFADDR __REGb(NF_BASE + 0xc) +#define NFDATA __REGb(NF_BASE + 0x10) +#define NFDATA16 __REGw(NF_BASE + 0x10) +#define NFSTAT __REGb(NF_BASE + 0x20) +#define NFSTAT_BUSY 1 +#define nand_select() (NFCONT &= ~(1 << 1)) +#define nand_deselect() (NFCONT |= (1 << 1)) +#define nand_clear_RnB() (NFSTAT |= (1 << 2)) + +static inline void nand_wait(void) +{ + int i=0; + while (!(NFSTAT & NFSTAT_BUSY)) + for (i=0; i<10; i++); +} + +/* configuration for 2440 with 2048byte sized flash */ +#define NAND_5_ADDR_CYCLE +#define NAND_PAGE_SIZE 2048 +#define BAD_BLOCK_OFFSET NAND_PAGE_SIZE +#define NAND_BLOCK_MASK (NAND_PAGE_SIZE - 1) +#define NAND_BLOCK_SIZE (NAND_PAGE_SIZE * 64)#endif + +static int is_bad_block(unsigned long i) +{ + unsigned char data; + unsigned long page_num; + + nand_clear_RnB(); + page_num = i >> 11; /* addr / 2048 */ + NFCMD = NAND_CMD_READ0; + NFADDR = BAD_BLOCK_OFFSET & 0xff; + NFADDR = (BAD_BLOCK_OFFSET >> 8) & 0xff; + NFADDR = page_num & 0xff; + NFADDR = (page_num >> 8) & 0xff; + NFADDR = (page_num >> 16) & 0xff; + NFCMD = NAND_CMD_READSTART; + nand_wait(); + data = (NFDATA & 0xff); + if (data != 0xff) + return 1; + + return 0; +} + +static int nand_read_page_ll(unsigned char *buf, unsigned long addr) +{ + unsigned short *ptr16 = (unsigned short *)buf; + unsigned int i, page_num; + + nand_clear_RnB(); + + NFCMD = NAND_CMD_READ0; + page_num = addr >> 11; /* addr / 2048 */ + /* Write Address */ + NFADDR = 0; + NFADDR = 0; + NFADDR = page_num & 0xff; + NFADDR = (page_num >> 8) & 0xff; + NFADDR = (page_num >> 16) & 0xff; + NFCMD = NAND_CMD_READSTART; + nand_wait(); + + for (i = 0; i < NAND_PAGE_SIZE/2; i++) { + *ptr16 = NFDATA16; + ptr16++; + } + return NAND_PAGE_SIZE; +} + +/* low level nand read function */ + int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size) +{ + int i, j; + + if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) + return -1; /* invalid alignment */ + + /* chip Enable */ + nand_select(); + nand_clear_RnB(); + for (i=0; i<10; i++); + + for (i=start_addr; i < (start_addr + size);) { + j = nand_read_page_ll(buf, i); + i += j; + buf += j; + } + + /* chip Disable */ + nand_deselect(); + + return 0; +} diff --git a/qiboot/src/start.S b/qiboot/src/start.S index bf1a7f5..c98a55b 100644 --- a/qiboot/src/start.S +++ b/qiboot/src/start.S @@ -1,7 +1,7 @@ /* * (C) Copyright 2007 OpenMoko, Inc. * - * Configuation settings for the FIC Neo GTA02 Linux GSM phone + * Configuation settings for the OPENMOKO Neo GTA02 Linux GSM phone * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -26,10 +26,6 @@ _start: b start_code _TEXT_BASE: .word TEXT_BASE -.globl _armboot_start -_armboot_start: - .word _start - /* * These are defined in the board-specific linker script. */ @@ -159,11 +155,10 @@ clbss_l: cmp r0, r1 ble clbss_l - /* blink led */ ldr pc, _start_armboot _start_armboot: - .word start_armboot + .word start_kboot /* ************************************************************************* diff --git a/qiboot/src/start_kboot.c b/qiboot/src/start_kboot.c new file mode 100644 index 0000000..581cb6e --- /dev/null +++ b/qiboot/src/start_kboot.c @@ -0,0 +1,48 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: xiangfu liu + * + * Configuation settings for the OPENMOKO Neo GTA02 Linux GSM phone + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +unsigned char buf[]={ +0x0d,0xc0,0xa0,0xe1,0x00,0xd8,0x2d,0xe9,0x04,0xb0,0x4c,0xe2,0x4c,0x20,0x9f,0xe5, +0x05,0x30,0xa0,0xe3,0x00,0x30,0x82,0xe5,0x44,0x20,0x9f,0xe5,0x44,0x30,0x9f,0xe5, +0x00,0x30,0x82,0xe5,0x40,0x20,0x9f,0xe5,0x3c,0x30,0x9f,0xe5,0x00,0x30,0x93,0xe5, +0x01,0x30,0xc3,0xe3,0x00,0x30,0x82,0xe5,0x28,0x00,0x9f,0xe5,0x0b,0x00,0x00,0xeb, +0x24,0x20,0x9f,0xe5,0x20,0x30,0x9f,0xe5,0x00,0x30,0x93,0xe5,0x01,0x30,0x83,0xe3, +0x00,0x30,0x82,0xe5,0x0c,0x00,0x9f,0xe5,0x04,0x00,0x00,0xeb,0xf0,0xff,0xff,0xea, +0x10,0x00,0x00,0x56,0x18,0x00,0x00,0x56,0xff,0xff,0x00,0x00,0x14,0x00,0x00,0x56, +0x01,0x00,0x50,0xe2,0xfd,0xff,0xff,0x1a,0x0e,0xf0,0xa0,0xe1,0x0a}; + +#define ADDR ((volatile unsigned *)&buf) + +int start_kboot() +{ + /* nand_read_ll(buf, 0, sizeof(buf));*/ + /* + void (*fp)(void)=(void (*)(void))&buf; + (fp)(); + */ + asm volatile("mov pc, %0\n" + : /* output */ + :"r"(ADDR) /* input */ + ); + return 0; +} +