forked from len0rd/rockbox
Added disk/partition handling
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@405 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
86a59ecdf6
commit
c7f7934e8f
8 changed files with 164 additions and 58 deletions
|
@ -35,10 +35,10 @@ archos.bin : archos.elf
|
|||
$(OC) -O binary archos.elf archos.bin
|
||||
|
||||
archos.asm: archos.bin
|
||||
sh2d -sh1 archos.bin > archos.asm
|
||||
../tools/sh2d -sh1 archos.bin > archos.asm
|
||||
|
||||
archos.mod : archos.bin
|
||||
scramble archos.bin archos.mod
|
||||
../tools/scramble archos.bin archos.mod
|
||||
|
||||
dist:
|
||||
tar czvf dist.tar.gz Makefile main.c start.s app.lds
|
||||
|
|
74
firmware/common/disk.c
Normal file
74
firmware/common/disk.c
Normal file
|
@ -0,0 +1,74 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Björn Stenberg
|
||||
*
|
||||
* 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 "ata.h"
|
||||
#include "debug.h"
|
||||
#include "disk.h"
|
||||
|
||||
/* Partition table entry layout:
|
||||
-----------------------
|
||||
0: 0x80 - active
|
||||
1: starting head
|
||||
2: starting sector
|
||||
3: starting cylinder
|
||||
4: partition type
|
||||
5: end head
|
||||
6: end sector
|
||||
7: end cylinder
|
||||
8-11: starting sector (LBA)
|
||||
12-15: nr of sectors in partition
|
||||
*/
|
||||
|
||||
#define BYTES2INT32(array,pos) \
|
||||
(array[pos] | (array[pos+1] << 8 ) | \
|
||||
(array[pos+2] << 16 ) | (array[pos+3] << 24 ))
|
||||
|
||||
struct partinfo part[8];
|
||||
|
||||
int disk_init(void)
|
||||
{
|
||||
int i;
|
||||
unsigned char sector[512];
|
||||
|
||||
ata_read_sectors(0,1,§or);
|
||||
|
||||
/* check that the boot sector is initialized */
|
||||
if ( (sector[510] != 0x55) ||
|
||||
(sector[511] != 0xaa)) {
|
||||
DEBUGF("Bad boot sector signature\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* parse partitions */
|
||||
for ( i=0; i<4; i++ ) {
|
||||
unsigned char* ptr = sector + 0x1be + 16*i;
|
||||
part[i].type = ptr[4];
|
||||
part[i].start = BYTES2INT32(ptr, 8);
|
||||
part[i].size = BYTES2INT32(ptr, 12);
|
||||
|
||||
DEBUGF("Part%d: Type %02x, start: %08x size: %08x\n",
|
||||
i,part[i].type,part[i].start,part[i].size);
|
||||
|
||||
/* extended? */
|
||||
if ( part[i].type == 5 ) {
|
||||
/* not handled yet */
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
32
firmware/common/disk.h
Normal file
32
firmware/common/disk.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Björn Stenberg
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef _DISK_H_
|
||||
#define _DISK_H_
|
||||
|
||||
struct partinfo {
|
||||
unsigned long start; /* first sector (LBA) */
|
||||
unsigned long size; /* number of sectors */
|
||||
unsigned char type;
|
||||
};
|
||||
|
||||
extern struct partinfo part[8];
|
||||
|
||||
int disk_init(void);
|
||||
|
||||
#endif
|
|
@ -133,25 +133,6 @@ static int fat_cache_dirty[256];
|
|||
static unsigned char lastsector[SECTOR_SIZE];
|
||||
static unsigned char lastsector2[SECTOR_SIZE];
|
||||
|
||||
#ifdef TEST_FAT
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct bpb bpb;
|
||||
|
||||
memset(fat_cache, 0, sizeof(fat_cache));
|
||||
memset(fat_cache_dirty, 0, sizeof(fat_cache_dirty));
|
||||
|
||||
if(ata_init())
|
||||
DEBUGF("*** Warning! The disk is uninitialized\n");
|
||||
else
|
||||
fat_mount(&bpb);
|
||||
|
||||
dbg_console(&bpb);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int sec2cluster(struct bpb *bpb, unsigned int sec)
|
||||
{
|
||||
if ( sec < bpb->firstdatasector )
|
||||
|
@ -183,7 +164,7 @@ static int first_sector_of_cluster(struct bpb *bpb, unsigned int cluster)
|
|||
return (cluster - 2) * bpb->bpb_secperclus + bpb->firstdatasector;
|
||||
}
|
||||
|
||||
int fat_mount(struct bpb *bpb)
|
||||
int fat_mount(struct bpb *bpb, int startsector)
|
||||
{
|
||||
unsigned char buf[SECTOR_SIZE];
|
||||
int err;
|
||||
|
@ -191,7 +172,7 @@ int fat_mount(struct bpb *bpb)
|
|||
int countofclusters;
|
||||
|
||||
/* Read the sector */
|
||||
err = ata_read_sectors(0,1,buf);
|
||||
err = ata_read_sectors(startsector,1,buf);
|
||||
if(err)
|
||||
{
|
||||
DEBUGF( "fat_mount() - Couldn't read BPB (error code %i)\n",
|
||||
|
@ -200,6 +181,7 @@ int fat_mount(struct bpb *bpb)
|
|||
}
|
||||
|
||||
memset(bpb, 0, sizeof(struct bpb));
|
||||
bpb->startsector = startsector;
|
||||
|
||||
strncpy(bpb->bs_oemname, &buf[BS_OEMNAME], 8);
|
||||
bpb->bs_oemname[8] = 0;
|
||||
|
@ -306,20 +288,6 @@ static int bpb_is_sane(struct bpb *bpb)
|
|||
DEBUGF( "bpb_is_sane() - Warning: RootEntCnt is not 512 (%i)\n",
|
||||
bpb->bpb_rootentcnt);
|
||||
}
|
||||
if(bpb->bpb_totsec16 < 200)
|
||||
{
|
||||
if(bpb->bpb_totsec16 == 0)
|
||||
{
|
||||
DEBUGF( "bpb_is_sane() - Error: TotSec16 is 0\n");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUGF( "bpb_is_sane() - Warning: TotSec16 "
|
||||
"is quite small (%i)\n",
|
||||
bpb->bpb_totsec16);
|
||||
}
|
||||
}
|
||||
if(bpb->bpb_media != 0xf0 && bpb->bpb_media < 0xf8)
|
||||
{
|
||||
DEBUGF( "bpb_is_sane() - Warning: Non-standard "
|
||||
|
@ -349,7 +317,7 @@ static void *cache_fat_sector(struct bpb *bpb, int secnum)
|
|||
DEBUGF( "cache_fat_sector() - Out of memory\n");
|
||||
return NULL;
|
||||
}
|
||||
if(ata_read_sectors(secnum,1,sec))
|
||||
if(ata_read_sectors(secnum+bpb->startsector,1,sec))
|
||||
{
|
||||
DEBUGF( "cache_fat_sector() - Could"
|
||||
" not read sector %d\n",
|
||||
|
@ -447,14 +415,17 @@ static int flush_fat(struct bpb *bpb)
|
|||
{
|
||||
DEBUGF("Flushing FAT sector %d\n", i);
|
||||
sec = fat_cache[i];
|
||||
err = ata_write_sectors(i + bpb->bpb_rsvdseccnt,1,sec);
|
||||
err = ata_write_sectors(i + bpb->bpb_rsvdseccnt + bpb->startsector,
|
||||
1,sec);
|
||||
if(err)
|
||||
{
|
||||
DEBUGF( "flush_fat() - Couldn't write"
|
||||
" sector (%d)\n", i + bpb->bpb_rsvdseccnt);
|
||||
return -1;
|
||||
}
|
||||
err = ata_write_sectors(i + bpb->bpb_rsvdseccnt + fatsz,1,sec);
|
||||
err = ata_write_sectors(i + bpb->bpb_rsvdseccnt + fatsz +
|
||||
bpb->startsector,
|
||||
1,sec);
|
||||
if(err)
|
||||
{
|
||||
DEBUGF( "flush_fat() - Couldn't write"
|
||||
|
@ -559,7 +530,7 @@ static int add_dir_entry(struct bpb *bpb,
|
|||
|
||||
DEBUGF("Reading sector %d...\n", sec);
|
||||
/* Read the next sector in the current dir */
|
||||
err = ata_read_sectors(sec,1,buf);
|
||||
err = ata_read_sectors(sec + bpb->startsector,1,buf);
|
||||
if(err)
|
||||
{
|
||||
DEBUGF( "add_dir_entry() - Couldn't read dir sector"
|
||||
|
@ -624,7 +595,7 @@ static int add_dir_entry(struct bpb *bpb,
|
|||
}
|
||||
}
|
||||
|
||||
err = ata_write_sectors(sec,1,buf);
|
||||
err = ata_write_sectors(sec + bpb->startsector,1,buf);
|
||||
if(err)
|
||||
{
|
||||
DEBUGF( "add_dir_entry() - "
|
||||
|
@ -821,7 +792,8 @@ int fat_read(struct bpb *bpb,
|
|||
int err, i;
|
||||
|
||||
for ( i=0; i<sectorcount; i++ ) {
|
||||
err = ata_read_sectors(sector,1,(char*)buf+(i*SECTOR_SIZE));
|
||||
err = ata_read_sectors(sector + bpb->startsector, 1,
|
||||
(char*)buf+(i*SECTOR_SIZE));
|
||||
if(err) {
|
||||
DEBUGF( "fat_read() - Couldn't read sector %d"
|
||||
" (error code %i)\n", sector,err);
|
||||
|
@ -898,7 +870,7 @@ int fat_opendir(struct bpb *bpb,
|
|||
}
|
||||
|
||||
/* Read the first sector in the current dir */
|
||||
err = ata_read_sectors(sec,1,ent->cached_buf);
|
||||
err = ata_read_sectors(sec + bpb->startsector,1,ent->cached_buf);
|
||||
if(err)
|
||||
{
|
||||
DEBUGF( "fat_getfirst() - Couldn't read dir sector"
|
||||
|
@ -1037,7 +1009,8 @@ int fat_getnext(struct bpb *bpb,
|
|||
}
|
||||
|
||||
/* Read the next sector */
|
||||
err = ata_read_sectors(ent->cached_sec,1,ent->cached_buf);
|
||||
err = ata_read_sectors(ent->cached_sec + bpb->startsector, 1,
|
||||
ent->cached_buf);
|
||||
if(err)
|
||||
{
|
||||
DEBUGF( "fat_getnext() - Couldn't read dir sector"
|
||||
|
|
|
@ -60,6 +60,7 @@ struct bpb
|
|||
int totalsectors;
|
||||
int rootdirsector;
|
||||
int firstdatasector;
|
||||
int startsector;
|
||||
};
|
||||
|
||||
struct fat_direntry
|
||||
|
@ -100,7 +101,7 @@ struct fat_fileent
|
|||
int sectornum; /* sector number in this cluster */
|
||||
};
|
||||
|
||||
extern int fat_mount(struct bpb *bpb);
|
||||
extern int fat_mount(struct bpb *bpb, int startsector);
|
||||
|
||||
#ifdef DISK_WRITE
|
||||
extern int fat_create_file(struct bpb *bpb,
|
||||
|
|
|
@ -1,18 +1,25 @@
|
|||
FIRMWARE = ../..
|
||||
DRIVERS = ../../drivers
|
||||
|
||||
CFLAGS = -g -Wall -DTEST_FAT -I$(DRIVERS) -I.
|
||||
CFLAGS = -g -Wall -DTEST_FAT -I$(DRIVERS) -I$(FIRMWARE)/common -I$(FIRMWARE) -I. -DDEBUG -DCRT_DISPLAY
|
||||
|
||||
TARGET = fat
|
||||
|
||||
$(TARGET): fat.o ata-sim.o debug.o
|
||||
$(TARGET): fat.o ata-sim.o debug.o main.o disk.o
|
||||
gcc -g -o fat $+ -lfl
|
||||
|
||||
fat.o: $(DRIVERS)/fat.c $(DRIVERS)/fat.h $(DRIVERS)/ata.h
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
disk.o: $(FIRMWARE)/common/disk.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
debug.o: $(FIRMWARE)/debug.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
ata-sim.o: ata-sim.c $(DRIVERS)/ata.h
|
||||
|
||||
debug.o: debug.c debug.h $(DRIVERS)/ata.h
|
||||
main.o: main.c $(DRIVERS)/ata.h
|
||||
|
||||
clean:
|
||||
rm -f *.o $(TARGET)
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
#ifndef DEBUG_H
|
||||
#define DEBUG_H
|
||||
|
||||
void dbg_dump_sector(int sec);
|
||||
void dbg_dump_buffer(unsigned char *buf);
|
||||
void dbg_print_bpb(struct bpb *bpb);
|
||||
void dbg_console(struct bpb *bpb);
|
||||
|
||||
#endif
|
|
@ -4,6 +4,12 @@
|
|||
#include "fat.h"
|
||||
#include "ata.h"
|
||||
#include "debug.h"
|
||||
#include "disk.h"
|
||||
|
||||
void dbg_dump_sector(int sec);
|
||||
void dbg_dump_buffer(unsigned char *buf);
|
||||
void dbg_print_bpb(struct bpb *bpb);
|
||||
void dbg_console(struct bpb *bpb);
|
||||
|
||||
void dbg_dump_sector(int sec)
|
||||
{
|
||||
|
@ -189,3 +195,25 @@ void dbg_console(struct bpb* bpb)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct bpb bpb;
|
||||
|
||||
if(ata_init()) {
|
||||
DEBUGF("*** Warning! The disk is uninitialized\n");
|
||||
return -1;
|
||||
}
|
||||
if (disk_init()) {
|
||||
DEBUGF("*** Failed reading partitions\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(fat_mount(&bpb,part[0].start)) {
|
||||
DEBUGF("*** Failed mounting fat\n");
|
||||
}
|
||||
|
||||
dbg_console(&bpb);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue