From d39714555498ffaed2b4d29459d58243691b16db Mon Sep 17 00:00:00 2001 From: Linus Nielsen Feltzing Date: Fri, 28 Jan 2005 12:51:10 +0000 Subject: iRiver Boot loader git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5694 a1c6a512-1295-4272-9138-f99709370657 --- bootloader/Makefile | 78 ++++++++++++++++++ bootloader/SOURCES | 1 + bootloader/main.c | 233 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 312 insertions(+) create mode 100644 bootloader/Makefile create mode 100644 bootloader/SOURCES create mode 100644 bootloader/main.c (limited to 'bootloader') diff --git a/bootloader/Makefile b/bootloader/Makefile new file mode 100644 index 0000000000..8daa23f041 --- /dev/null +++ b/bootloader/Makefile @@ -0,0 +1,78 @@ +# __________ __ ___. +# Open \______ \ ____ ____ | | _\_ |__ _______ ___ +# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +# \/ \/ \/ \/ \/ +# $Id$ +# + +INCLUDES= -I$(FIRMDIR)/include -I$(FIRMDIR)/export -I. -I$(OBJDIR) + +DEPFILE = $(OBJDIR)/dep-apps +LDS := $(FIRMDIR)/boot.lds + +ifdef DEBUG + DEFINES := -DDEBUG + CFLAGS += -g +endif + +SRC := $(shell cat SOURCES | $(CC) -DMEMORYSIZE=$(MEMORYSIZE) $(INCLUDES) $(TARGET) $(DEFINES) -E -P -include "config.h" - ) +DIRS = . + +ifdef APPEXTRA + DIRS += $(APPEXTRA) + INCLUDES += -I$(APPEXTRA) +endif + +CFLAGS = $(GCCOPTS) $(INCLUDES) $(TARGET) $(DEFINES) \ + -DAPPSVERSION=\"$(VERSION)\" $(EXTRA_DEFINES) -DMEM=${MEMORYSIZE} + +OBJS := $(SRC:%.c=$(OBJDIR)/%.o) +SOURCES = $(SRC) +LINKFILE = $(OBJDIR)/linkage.lds +MAXINFILE = $(OBJDIR)/romstart.temp +MAXOUTFILE = $(OBJDIR)/romstart + +ifdef DEBUG +all: $(OBJDIR)/bootloader.elf +else +all: $(OBJDIR)/$(BINARY) $(FLASHFILE) +endif + +dep: $(DEPFILE) + +$(LINKFILE): $(LDS) + @echo "Build LDS file" + @cat $< | $(CC) -DMEMORYSIZE=$(MEMORYSIZE) $(INCLUDES) $(TARGET) $(DEFINES) -E -P $(ROMBUILD) - >$@ + +$(MAXOUTFILE): + @echo '#include "config.h"' > $(MAXINFILE) + @echo "ROM_START" >> $(MAXINFILE) + @cat $(MAXINFILE) | $(CC) -DMEMORYSIZE=$(MEMORYSIZE) $(INCLUDES) $(TARGET) $(DEFINES) -E -P $(ROMBUILD) - > $(MAXOUTFILE) + @rm $(MAXINFILE) + +$(OBJDIR)/bootloader.elf : $(OBJS) $(LINKFILE) $(OBJDIR)/librockbox.a $(DEPFILE) + @echo "LD bootloader.elf" + $(CC) $(GCCOPTS) -Os -nostdlib -o $@ $(OBJS) -L$(OBJDIR) -lrockbox -lgcc -L$(FIRMDIR) -T$(LINKFILE) -Wl,-Map,$(OBJDIR)/bootloader.map + +$(OBJDIR)/bootloader.bin : $(OBJDIR)/bootloader.elf + @echo "OBJCOPY $<" + @$(OC) -O binary $< $@ + +$(OBJDIR)/bootloader.asm: $(OBJDIR)/bootloader.bin + $(TOOLSDIR)/sh2d -sh1 $< > $@ + +$(OBJDIR)/$(BINARY) : $(OBJDIR)/bootloader.bin + @echo "Build bootloader file" + @$(MKFIRMWARE) $< $@ + +include $(TOOLSDIR)/make.inc + +clean: + @echo "cleaning bootloader" + @-rm -f $(OBJS) $(OBJDIR)/$(BINARY) $(OBJDIR)/bootloader.asm \ + $(OBJDIR)/bootloader.bin $(OBJDIR)/bootloader.elf $(OBJDIR)/*.map \ + $(LINKFILE) $(MAXOUTFILE) $(DEPFILE) + +-include $(DEPFILE) diff --git a/bootloader/SOURCES b/bootloader/SOURCES new file mode 100644 index 0000000000..e241137f99 --- /dev/null +++ b/bootloader/SOURCES @@ -0,0 +1 @@ +main.c diff --git a/bootloader/main.c b/bootloader/main.c new file mode 100644 index 0000000000..5cc2edad2e --- /dev/null +++ b/bootloader/main.c @@ -0,0 +1,233 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2005 by Linus Nielsen Feltzing + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "config.h" + +#include +#include +#include "cpu.h" +#include "system.h" +#include "lcd.h" +#include "kernel.h" +#include "thread.h" +#include "ata.h" +#include "disk.h" +#include "font.h" +#include "adc.h" +#include "backlight.h" +#include "button.h" +#include "panic.h" +#include "power.h" +#include "file.h" + +int line = 0; + +int usb_screen(void) +{ + return 0; +} + +void start_iriver_fw(void) +{ + asm(" move.w #0x2700,%sr"); + asm(" move.l #0,%d0"); + asm(" movec.l %d0,%vbr"); + asm(" move.l 0,%sp"); + asm(" lea.l 8,%a0"); + asm(" jmp (%a0)"); +} + +int load_firmware(void) +{ + int fd; + int rc; + int len; + unsigned long chksum; + unsigned long sum; + int i; + unsigned char *buf = (unsigned char *)0x30000000; + char str[80]; + + fd = open("/rockbox.bin", O_RDONLY); + if(fd < 0) + return -1; + + len = lseek(fd, 0, SEEK_END) - 8; + + snprintf(str, 80, "Length: %x", len); + lcd_puts(0, line++, str); + lcd_update(); + + lseek(fd, 0, SEEK_SET); + + rc = read(fd, &chksum, 4); + if(rc < 4) + return -2; + + snprintf(str, 80, "Checksum: %x", chksum); + lcd_puts(0, line++, str); + lcd_update(); + + lseek(fd, 4, SEEK_CUR); + + rc = read(fd, buf, len); + if(rc < len) + return -4; + + close(fd); + + sum = 0; + + for(i = 0;i < len;i++) { + sum += buf[i]; + } + + snprintf(str, 80, "Sum: %x", sum); + lcd_puts(0, line++, str); + lcd_update(); + + if(sum != chksum) + return -5; + + return 0; +} + +void start_firmware(void) +{ + asm(" move.w #0x2700,%sr"); + asm(" move.l #0x30000000,%d0"); + asm(" movec.l %d0,%vbr"); + asm(" move.l 0x30000000,%sp"); + asm(" move.l 0x30000004,%a0"); + asm(" jmp (%a0)"); +} + +int main(void) +{ + int i; + int rc; + int button; + char buf[256]; + + power_init(); + system_init(); + kernel_init(); + backlight_init(); + set_irq_level(0); + lcd_init(); + font_init(); + adc_init(); + button_init(); + + lcd_setfont(FONT_SYSFIXED); + + sleep(HZ/10); /* Allow the button driver to check the buttons */ + + if(button_status() & BUTTON_REC) { + lcd_puts(0, 8, "Ninjax"); + lcd_update(); + sleep(HZ); + start_iriver_fw(); + } + + GPIO_FUNCTION |= 0x40000040; + GPIO1_FUNCTION |= 0x00000062; + + GPIO1_ENABLE |= 0x00000000; + + IDECONFIG1 = 0x00107000; + IDECONFIG2 = 0x00040000; + + /* Hard drive power */ + GPIO_OUT &= ~0x00000040; + GPIO_ENABLE |= 0x00040240; + GPIO_FUNCTION |= 0x00040200; + + rc = ata_init(); + if(rc) + { +#ifdef HAVE_LCD_BITMAP + char str[32]; + lcd_clear_display(); + snprintf(str, 31, "ATA error: %d", rc); + lcd_puts(0, 1, str); + lcd_puts(0, 3, "Press ON to debug"); + lcd_update(); + while(!(button_get(true) & BUTTON_REL)); +#endif + panicf("ata: %d", rc); + } + + disk_init(); + + /* FixMe: the same kind of mounting happens in usb.c, share the code. */ + rc = disk_mount_all(); + if (rc<=0) + { + lcd_clear_display(); + lcd_puts(0, 0, "No partition"); + lcd_puts(0, 1, "found."); + while(button_get(true) != SYS_USB_CONNECTED) {}; + } + + lcd_puts(0, line++, "Loading firmware"); + i = load_firmware(); + snprintf(buf, 256, "Result: %d", i); + lcd_puts(0, line++, buf); + lcd_update(); + + if(i == 0) + start_firmware(); + + while(1) { + button = button_get_w_tmo(HZ/2); + if(button) + { + if(button == (BUTTON_OFF | BUTTON_REPEAT)) + power_off(); + } + } +} + +/* These functions are present in the firmware library, but we reimplement + them here because the originals do a lot more than we want */ + +void reset_poweroff_timer(void) +{ +} + +void screen_dump(void) +{ +} + +int dbg_ports(void) +{ + return 0; +} + +void mpeg_stop(void) +{ +} + +void usb_acknowledge(void) +{ +} + +void usb_wait_for_disconnect(void) +{ +} -- cgit v1.2.3