* 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:
Maurus Cuelenaere 2008-08-27 20:32:12 +00:00
parent 109a867742
commit 944c33403c
9 changed files with 1414 additions and 5 deletions

View file

@ -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
View 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);
}

View file

@ -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

View file

@ -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

View file

@ -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 = .;

View file

@ -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, &sector);
hdr = (struct main_header*)&sector;
/* 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);
}

View file

@ -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

View file

@ -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

File diff suppressed because it is too large Load diff