* Commit dual-boot support for Creative ZVx family
* Add mkzenboot: makes it possible to integrate Rockbox bootloader with Creative firmwares without the need of distributing binaries * Add Tadeusz Pyś to credits, who figured out the minifs file system * Fix bootloader git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18352 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
109a867742
commit
944c33403c
9 changed files with 1414 additions and 5 deletions
|
@ -33,4 +33,6 @@ telechips.c
|
||||||
meizu_m6sl.c
|
meizu_m6sl.c
|
||||||
#elif defined(ONDA_VX747)
|
#elif defined(ONDA_VX747)
|
||||||
ondavx747.c
|
ondavx747.c
|
||||||
|
#elif defined(CREATIVE_ZVM)
|
||||||
|
creativezvm.c
|
||||||
#endif
|
#endif
|
||||||
|
|
113
bootloader/creativezvm.c
Normal file
113
bootloader/creativezvm.c
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* __________ __ ___.
|
||||||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
* \/ \/ \/ \/ \/
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 by Maurus Cuelenaere
|
||||||
|
*
|
||||||
|
* 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 "system.h"
|
||||||
|
#include "lcd.h"
|
||||||
|
#include "kernel.h"
|
||||||
|
#include "thread.h"
|
||||||
|
#include "ata.h"
|
||||||
|
#include "ata-target.h"
|
||||||
|
#include "disk.h"
|
||||||
|
#include "font.h"
|
||||||
|
#include "backlight.h"
|
||||||
|
#include "button.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void load_fw(unsigned char* ptr, unsigned int len)
|
||||||
|
{
|
||||||
|
(void)ptr;
|
||||||
|
(void)len;
|
||||||
|
asm volatile("ldr pc, =0x1EE0000");
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
unsigned char* loadbuffer;
|
||||||
|
int buffer_size;
|
||||||
|
int(*kernel_entry)(void);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Make sure interrupts are disabled */
|
||||||
|
set_irq_level(IRQ_DISABLED);
|
||||||
|
set_fiq_status(FIQ_DISABLED);
|
||||||
|
system_init();
|
||||||
|
kernel_init();
|
||||||
|
|
||||||
|
/* Now enable interrupts */
|
||||||
|
set_irq_level(IRQ_ENABLED);
|
||||||
|
set_fiq_status(FIQ_ENABLED);
|
||||||
|
backlight_init();
|
||||||
|
lcd_init();
|
||||||
|
font_init();
|
||||||
|
button_init();
|
||||||
|
|
||||||
|
lcd_enable(true);
|
||||||
|
lcd_setfont(FONT_SYSFIXED);
|
||||||
|
reset_screen();
|
||||||
|
printf("Rockbox boot loader");
|
||||||
|
printf("Version %s", APPSVERSION);
|
||||||
|
|
||||||
|
ret = ata_init();
|
||||||
|
if(ret)
|
||||||
|
printf("ATA error: %d", ret);
|
||||||
|
|
||||||
|
if(1)
|
||||||
|
{
|
||||||
|
printf("Loading Creative firmware...");
|
||||||
|
|
||||||
|
loadbuffer = (unsigned char*)0x00A00000;
|
||||||
|
ret = load_minifs_file("creativeos.jrm", loadbuffer);
|
||||||
|
if(ret != -1)
|
||||||
|
{
|
||||||
|
set_irq_level(IRQ_DISABLED);
|
||||||
|
set_fiq_status(FIQ_DISABLED);
|
||||||
|
/* Doesn't return! */
|
||||||
|
load_fw(loadbuffer, ret);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("FAILED!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
disk_init();
|
||||||
|
|
||||||
|
ret = disk_mount_all();
|
||||||
|
if (ret <= 0)
|
||||||
|
error(EDISK, ret);
|
||||||
|
|
||||||
|
printf("Loading Rockbox firmware...");
|
||||||
|
|
||||||
|
loadbuffer = (unsigned char*)0x00900000;
|
||||||
|
buffer_size = (unsigned char*)0x01900000 - loadbuffer;
|
||||||
|
|
||||||
|
ret = load_firmware(loadbuffer, BOOTFILE, buffer_size);
|
||||||
|
if(ret < 0)
|
||||||
|
error(EBOOTFILE, ret);
|
||||||
|
|
||||||
|
else if(ret == EOK)
|
||||||
|
{
|
||||||
|
kernel_entry = (void*) loadbuffer;
|
||||||
|
ret = kernel_entry();
|
||||||
|
printf("FAILED!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while(1);
|
||||||
|
}
|
|
@ -412,6 +412,7 @@ Jun Gu
|
||||||
Daniel Weck
|
Daniel Weck
|
||||||
Clément Pit-Claudel
|
Clément Pit-Claudel
|
||||||
Jelle Geerts
|
Jelle Geerts
|
||||||
|
Tadeusz Pyś
|
||||||
|
|
||||||
The libmad team
|
The libmad team
|
||||||
The wavpack team
|
The wavpack team
|
||||||
|
|
|
@ -166,11 +166,11 @@
|
||||||
#define USB_PRODUCT_ID 0x4133
|
#define USB_PRODUCT_ID 0x4133
|
||||||
|
|
||||||
/*DEBUGGING!*/
|
/*DEBUGGING!*/
|
||||||
#ifdef BOOTLOADER
|
/*
|
||||||
#define THREAD_EXTRA_CHECKS 1
|
#define THREAD_EXTRA_CHECKS 1
|
||||||
#define DEBUG 1
|
#define DEBUG 1
|
||||||
#define debug(msg) printf(msg)
|
#define debug(msg) printf(msg)
|
||||||
#define BUTTON_DEBUG
|
#define BUTTON_DEBUG
|
||||||
#endif
|
*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -7,7 +7,7 @@ STARTUP(target/arm/tms320dm320/crt0.o)
|
||||||
|
|
||||||
#define DRAMSIZE (MEMORYSIZE * 0x100000)
|
#define DRAMSIZE (MEMORYSIZE * 0x100000)
|
||||||
|
|
||||||
#define DRAMORIG 0x00900000
|
#define DRAMORIG 0x01900000 /* actually it's 0x00900000 */
|
||||||
#define IRAMORIG 0x00000000
|
#define IRAMORIG 0x00000000
|
||||||
#define IRAMSIZE 16K
|
#define IRAMSIZE 16K
|
||||||
#define FLASHORIG 0x00100000
|
#define FLASHORIG 0x00100000
|
||||||
|
@ -22,7 +22,7 @@ MEMORY
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = DRAMORIG + 0x1000000;
|
. = DRAMORIG;
|
||||||
|
|
||||||
.text : {
|
.text : {
|
||||||
loadaddress = .;
|
loadaddress = .;
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
#include "panic.h"
|
#include "panic.h"
|
||||||
#include "ata-target.h"
|
#include "ata-target.h"
|
||||||
#include "dm320.h"
|
#include "dm320.h"
|
||||||
|
#include "ata.h"
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
void sleep_ms(int ms)
|
void sleep_ms(int ms)
|
||||||
{
|
{
|
||||||
|
@ -109,3 +111,106 @@ void GIO2(void)
|
||||||
IO_INTC_IRQ1 = INTR_IRQ1_EXT2; /* Mask GIO2 interrupt */
|
IO_INTC_IRQ1 = INTR_IRQ1_EXT2; /* Mask GIO2 interrupt */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Creative File Systems parsing code
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct main_header
|
||||||
|
{
|
||||||
|
char mblk[4];
|
||||||
|
unsigned char sector_size[4];
|
||||||
|
unsigned char disk_size[8];
|
||||||
|
struct partition_header
|
||||||
|
{
|
||||||
|
unsigned char end[4];
|
||||||
|
unsigned char start[4];
|
||||||
|
char name[8];
|
||||||
|
} partitions[31];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct minifs_file
|
||||||
|
{
|
||||||
|
char name[0x10];
|
||||||
|
unsigned char unk[4];
|
||||||
|
unsigned char size[4];
|
||||||
|
unsigned char chain1[4];
|
||||||
|
unsigned char chain2[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct minifs_chain
|
||||||
|
{
|
||||||
|
unsigned char unknown[4];
|
||||||
|
unsigned char chain[2*0x27FE];
|
||||||
|
unsigned char unknown2[4];
|
||||||
|
unsigned char length[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define DIR_BITMAP_START 0x0143
|
||||||
|
#define DIR_START 0x0144
|
||||||
|
#define DATASPACE_BITMAP_START 0x0145
|
||||||
|
#define DATASPACE_START 0x0146
|
||||||
|
|
||||||
|
#define CLUSTER_CHAIN_SIZE 0x5008
|
||||||
|
#define CLUSTER_CHAIN_HEAD 0x0000
|
||||||
|
#define CLUSTER_CHAIN_BITMAP 0x0001
|
||||||
|
#define CLUSTER_CHAIN_CHAIN 0x0002
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned short le2int16(unsigned char* buf)
|
||||||
|
{
|
||||||
|
return (buf[1] << 8) | buf[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int le2int32(unsigned char* buf)
|
||||||
|
{
|
||||||
|
return (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
int load_minifs_file(char* filename, unsigned char* location)
|
||||||
|
{
|
||||||
|
struct main_header *hdr;
|
||||||
|
static struct minifs_file files[128];
|
||||||
|
struct minifs_chain *chain;
|
||||||
|
unsigned int i;
|
||||||
|
int found = -1;
|
||||||
|
unsigned char sector[512];
|
||||||
|
static unsigned char chain_data[42*512]; /* stack overflow if not static */
|
||||||
|
|
||||||
|
/* Reading MBLK */
|
||||||
|
ata_read_sectors(0, 1, §or);
|
||||||
|
hdr = (struct main_header*)§or;
|
||||||
|
|
||||||
|
/* Reading directory listing */
|
||||||
|
#define CLUSTER2SECTOR(x) ( (le2int32(hdr->partitions[0].start) + (x)*8) )
|
||||||
|
ata_read_sectors(CLUSTER2SECTOR(DIR_START), 8, &files);
|
||||||
|
|
||||||
|
for(i=0; i<127; i++)
|
||||||
|
{
|
||||||
|
if(strcmp(files[i].name, filename) == 0)
|
||||||
|
found = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(found == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
#define GET_CHAIN(x) ( CLUSTER2SECTOR(CLUSTER_CHAIN_CHAIN)*512 + (x)*CLUSTER_CHAIN_SIZE )
|
||||||
|
#define FILE2SECTOR(x) ( CLUSTER2SECTOR(DATASPACE_START + (x)) )
|
||||||
|
|
||||||
|
/* Reading chain list */
|
||||||
|
ata_read_sectors(GET_CHAIN(le2int32(files[found].chain1))/512, 41, &chain_data[0]);
|
||||||
|
|
||||||
|
chain = (struct minifs_chain*)&chain_data[GET_CHAIN(le2int32(files[found].chain1))%512];
|
||||||
|
|
||||||
|
/* Copying data */
|
||||||
|
for(i=0; i<le2int32(chain->length); i++)
|
||||||
|
{
|
||||||
|
ata_read_sectors(FILE2SECTOR(le2int16(&chain->chain[i*2])), 8, location);
|
||||||
|
location += 0x1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
return le2int32(files[found].size);
|
||||||
|
}
|
||||||
|
|
|
@ -74,5 +74,6 @@ void ata_reset(void);
|
||||||
void ata_device_init(void);
|
void ata_device_init(void);
|
||||||
bool ata_is_coldstart(void);
|
bool ata_is_coldstart(void);
|
||||||
void ide_power_enable(bool on);
|
void ide_power_enable(bool on);
|
||||||
|
int load_minifs_file(char* filename, unsigned char* location);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,7 +13,7 @@ LDFLAGS := -g
|
||||||
|
|
||||||
CLEANALL := scramble descramble iriver sh2d bmp2rb rdf2binary convbdf \
|
CLEANALL := scramble descramble iriver sh2d bmp2rb rdf2binary convbdf \
|
||||||
generate_rocklatin mkboot ipod_fw codepages uclpack mi4 gigabeat database \
|
generate_rocklatin mkboot ipod_fw codepages uclpack mi4 gigabeat database \
|
||||||
lngdump telechips gigabeats creative hmac-sha1 mktccboot mknkboot rbspeexenc
|
lngdump telechips gigabeats creative hmac-sha1 mktccboot mknkboot rbspeexenc mkzenboot
|
||||||
|
|
||||||
all:
|
all:
|
||||||
@echo "Run make in your build directory!"
|
@echo "Run make in your build directory!"
|
||||||
|
@ -51,6 +51,12 @@ mktccboot: mktccboot.c telechips.o
|
||||||
mknkboot: mknkboot.c
|
mknkboot: mknkboot.c
|
||||||
$(SILENT)$(CC) $(CFLAGS) $+ -o $@
|
$(SILENT)$(CC) $(CFLAGS) $+ -o $@
|
||||||
|
|
||||||
|
mkzenboot.o: mkzenboot.c
|
||||||
|
$(SILENT)$(CC) $(CFLAGS) -DSTANDALONE -c -o $@ $+
|
||||||
|
|
||||||
|
mkzenboot: mkzenboot.o hmac-sha1.o
|
||||||
|
$(SILENT)$(CC) $(LDFLAGS) -lz $+ -o $@
|
||||||
|
|
||||||
lngdump: lngdump.c
|
lngdump: lngdump.c
|
||||||
$(SILENT)$(CC) $(CFLAGS) $+ -o $@
|
$(SILENT)$(CC) $(CFLAGS) $+ -o $@
|
||||||
|
|
||||||
|
|
1181
tools/mkzenboot.c
Normal file
1181
tools/mkzenboot.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue