This is a discussion on Re: [PATCH] iPod nano 8G within the mailing.openbsd.tech forums, part of the OpenBSD category; --> On Tuesday, November 14, Peter Galbavy wrote: > Alexey Vatchenko wrote: > > Hi! > > > > Second ...
| |||||||
| Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| On Tuesday, November 14, Peter Galbavy wrote: > Alexey Vatchenko wrote: > > Hi! > > > > Second generation iPod nano (i've got black one) has 2048-bytes block > > size. That's why system doesn't want to work with this device. I've > > made a little change to scsi layer and msdosfs. > > This is also the case for non-SDHC 4GB cards like the Transcend I use. I > will try this patch on that problem shortly. Thanks! Yup, as well as the 80GB iPods, etc. I've got a patch for this as well, but Alexey has patched it a little different. It's good to have 2-3 different implementations to try and get all the quirks worked out for this. I have a patch for fdisk. Attached below. --Toby. Index: cmd.c ================================================== ================= RCS file: /cvs/src/sbin/fdisk/cmd.c,v retrieving revision 1.42 diff -u -r1.42 cmd.c --- cmd.c 27 Jul 2006 04:06:13 -0000 1.42 +++ cmd.c 14 Oct 2006 16:13:48 -0000 @@ -46,7 +46,7 @@ char buf[DEV_BSIZE]; /* Copy template MBR */ - MBR_make(tt, buf); + MBR_make(tt, buf, disk->real->sec_size); MBR_parse(disk, buf, mbr->offset, mbr->reloffset, mbr); MBR_init(disk, mbr); @@ -321,8 +321,8 @@ printf("Writing MBR at offset %d.\n", offset); fd = DISK_open(disk->name, O_RDWR); - MBR_make(mbr, mbr_buf); - if (MBR_write(fd, offset, mbr_buf) != -1) + MBR_make(mbr, mbr_buf, disk->real->sec_size); + if (MBR_write(fd, offset, mbr_buf, disk->real->sec_size) != -1) ret = CMD_CLEAN; close(fd); return (ret); Index: disk.c ================================================== ================= RCS file: /cvs/src/sbin/fdisk/disk.c,v retrieving revision 1.24 diff -u -r1.24 disk.c --- disk.c 18 Dec 2005 03:42:23 -0000 1.24 +++ disk.c 14 Oct 2006 16:13:48 -0000 @@ -98,11 +98,21 @@ lm->heads = dl.d_ntracks; lm->sectors = dl.d_nsectors; lm->size = dl.d_secperunit; + lm->sec_size = dl.d_secsize; unit_types[SECTORS].conversion = dl.d_secsize; } DISK_close(fd); } + if (lm && lm->sec_size != 512 && lm->sec_size != 1024 && + lm->sec_size != 2048 && lm->sec_size != 4096 && + lm->sec_size != 8192) { + + warnx("Invalid sector size %d, setting to %d", lm->sec_size, + DEV_BSIZE); + lm->sec_size = DEV_BSIZE; + } + return (lm); } @@ -156,6 +166,7 @@ bm->heads = di.bios_heads; bm->sectors = di.bios_sectors; bm->size = di.bios_cylinders * di.bios_heads * di.bios_sectors; + bm->sec_size = DEV_BSIZE; return (bm); } #else @@ -186,6 +197,13 @@ disk->label = DISK_getlabelmetrics(disk->name); disk->bios = DISK_getbiosmetrics(disk->name); + /* + * If we have a disklabel, the kernel tells us what size sector + * this raw device has. As such, use it. Yes, not pretty. + */ + if (disk->label && disk->bios) + disk->bios->sec_size = disk->label->sec_size; + /* If user supplied, use that */ if (user) { disk->real = user; @@ -235,11 +253,12 @@ size = ((double)disk->real->size * unit_types[SECTORS].conversion) / unit_types[i].conversion; printf("Disk: %s\t", disk->name); - if (disk->real) - printf("geometry: %d/%d/%d [%.0f %s]\n", disk->real->cylinders, + if (disk->real) { + printf("geometry: %d/%d/%d [%.0f %s] ", disk->real->cylinders, disk->real->heads, disk->real->sectors, size, unit_types[i].lname); - else + printf("(%d byte sectors)\n", disk->real->sec_size); + } else printf("geometry: <none>\n"); return (0); Index: disk.h ================================================== ================= RCS file: /cvs/src/sbin/fdisk/disk.h,v retrieving revision 1.8 diff -u -r1.8 disk.h --- disk.h 3 Aug 2004 09:22:03 -0000 1.8 +++ disk.h 14 Oct 2006 16:13:48 -0000 @@ -34,6 +34,7 @@ u_int32_t heads; u_int32_t sectors; u_int32_t size; + u_int32_t sec_size; } DISK_metrics; typedef struct _disk_t { Index: fdisk.c ================================================== ================= RCS file: /cvs/src/sbin/fdisk/fdisk.c,v retrieving revision 1.43 diff -u -r1.43 fdisk.c --- fdisk.c 27 Jul 2006 04:53:27 -0000 1.43 +++ fdisk.c 14 Oct 2006 16:13:48 -0000 @@ -74,7 +74,9 @@ char *mbrfile = NULL; #endif mbr_t mbr; - char mbr_buf[DEV_BSIZE]; + char mbr_buf[MBR_MAX_SIZE]; + + memset(mbr_buf, 0, sizeof(mbr_buf)); while ((ch = getopt(argc, argv, "ieuf:c:h:s:")) != -1) { const char *errstr; @@ -153,9 +155,9 @@ mbrfile == NULL; } if (mbrfile == NULL) { - memcpy(mbr_buf, builtin_mbr, sizeof(mbr_buf)); + memcpy(mbr_buf, builtin_mbr, DEV_BSIZE); } else { - MBR_read(fd, 0, mbr_buf); + MBR_read(fd, 0, mbr_buf, DEV_BSIZE); close(fd); } MBR_parse(&disk, mbr_buf, 0, 0, &mbr); Index: mbr.c ================================================== ================= RCS file: /cvs/src/sbin/fdisk/mbr.c,v retrieving revision 1.22 diff -u -r1.22 mbr.c --- mbr.c 29 May 2006 05:09:36 -0000 1.22 +++ mbr.c 14 Oct 2006 16:13:48 -0000 @@ -97,6 +97,7 @@ mbr->offset = offset; mbr->reloffset = reloff; mbr->signature = getshort(&mbr_buf[MBR_SIG_OFF]); + memcpy(mbr->rest, mbr_buf+DEV_BSIZE, disk->real->sec_size - DEV_BSIZE); for (i = 0; i < NDOSPART; i++) PRT_parse(disk, &mbr_buf[MBR_PART_OFF + MBR_PART_SIZE * i], @@ -104,12 +105,13 @@ } void -MBR_make(mbr_t *mbr, char *mbr_buf) +MBR_make(mbr_t *mbr, char *mbr_buf, int size) { int i; memcpy(mbr_buf, mbr->code, MBR_CODE_SIZE); putshort(&mbr_buf[MBR_SIG_OFF], mbr->signature); + memcpy(mbr_buf+DEV_BSIZE, mbr->rest, size - DEV_BSIZE); for (i = 0; i < NDOSPART; i++) PRT_make(&mbr->part[i], mbr->offset, mbr->reloffset, @@ -132,19 +134,19 @@ } int -MBR_read(int fd, off_t where, char *buf) +MBR_read(int fd, off_t where, char *buf, int size) { off_t off; ssize_t len; - where *= DEV_BSIZE; + where *= size; off = lseek(fd, where, SEEK_SET); if (off != where) return (-1); - len = read(fd, buf, DEV_BSIZE); + len = read(fd, buf, size); if (len == -1) return (-1); - if (len != DEV_BSIZE) { + if (len != size) { /* short read */ errno = EIO; return (-1); @@ -153,19 +155,19 @@ } int -MBR_write(int fd, off_t where, char *buf) +MBR_write(int fd, off_t where, char *buf, int size) { off_t off; ssize_t len; - where *= DEV_BSIZE; + where *= size; off = lseek(fd, where, SEEK_SET); if (off != where) return (-1); - len = write(fd, buf, DEV_BSIZE); + len = write(fd, buf, size); if (len == -1) return (-1); - if (len != DEV_BSIZE) { + if (len != size) { /* short write */ errno = EIO; return (-1); @@ -182,11 +184,12 @@ MBR_pcopy(disk_t *disk, mbr_t *mbr) { int i, fd, offset = 0, reloff = 0; + int size = disk->real->sec_size; mbr_t mbrd; - char mbr_disk[DEV_BSIZE]; + char mbr_disk[size]; fd = DISK_open(disk->name, O_RDONLY); - MBR_read(fd, offset, mbr_disk); + MBR_read(fd, offset, mbr_disk, size); DISK_close(fd); MBR_parse(disk, mbr_disk, offset, reloff, &mbrd); for (i = 0; i < NDOSPART; i++) { Index: mbr.h ================================================== ================= RCS file: /cvs/src/sbin/fdisk/mbr.h,v retrieving revision 1.11 diff -u -r1.11 mbr.h --- mbr.h 3 Jun 2003 01:13:19 -0000 1.11 +++ mbr.h 14 Oct 2006 16:13:48 -0000 @@ -28,6 +28,7 @@ #ifndef _MBR_H #define _MBR_H +#include <machine/param.h> #include "part.h" /* Various constants */ @@ -35,7 +36,7 @@ #define MBR_PART_SIZE 0x10 #define MBR_PART_OFF 0x1BE #define MBR_SIG_OFF 0x1FE - +#define MBR_MAX_SIZE 8192 /* MBR type */ typedef struct _mbr_t { @@ -44,16 +45,17 @@ unsigned char code[MBR_CODE_SIZE]; prt_t part[NDOSPART]; unsigned short signature; + unsigned char rest[MBR_MAX_SIZE-DEV_BSIZE]; } mbr_t; /* Prototypes */ void MBR_print_disk(char *); void MBR_print(mbr_t *, char *); void MBR_parse(disk_t *, char *, off_t, off_t, mbr_t *); -void MBR_make(mbr_t *, char *); +void MBR_make(mbr_t *, char *, int); void MBR_init(disk_t *, mbr_t *); -int MBR_read(int, off_t, char *); -int MBR_write(int, off_t, char *); +int MBR_read(int, off_t, char *, int); +int MBR_write(int, off_t, char *, int); void MBR_pcopy(disk_t *, mbr_t *); /* Sanity check */ Index: user.c ================================================== ================= RCS file: /cvs/src/sbin/fdisk/user.c,v retrieving revision 1.23 diff -u -r1.23 user.c --- user.c 27 Jul 2006 04:06:13 -0000 1.23 +++ user.c 14 Oct 2006 16:13:48 -0000 @@ -68,7 +68,7 @@ USER_init(disk_t *disk, mbr_t *tt, int preserve) { int fd, yn; - char mbr_buf[DEV_BSIZE]; + char mbr_buf[MBR_MAX_SIZE]; char *msgp = "\nDo you wish to write new MBR?"; char *msgk = "\nDo you wish to write new MBR and partition table?"; @@ -89,8 +89,8 @@ if (yn) { fd = DISK_open(disk->name, O_RDWR); - MBR_make(tt, mbr_buf); - if (MBR_write(fd, 0, mbr_buf) == -1) { + MBR_make(tt, mbr_buf, disk->real->sec_size); + if (MBR_write(fd, 0, mbr_buf, disk->real->sec_size) == -1) { int saved_errno = errno; DISK_close(fd); errno = saved_errno; @@ -109,7 +109,7 @@ USER_modify(disk_t *disk, mbr_t *tt, off_t offset, off_t reloff) { static int editlevel; - char mbr_buf[DEV_BSIZE]; + char mbr_buf[MBR_MAX_SIZE]; mbr_t mbr; cmd_t cmd; int i, st, fd; @@ -122,7 +122,7 @@ /* Read MBR & partition */ fd = DISK_open(disk->name, O_RDONLY); - MBR_read(fd, offset, mbr_buf); + MBR_read(fd, offset, mbr_buf, disk->real->sec_size); DISK_close(fd); /* Parse the sucker */ @@ -173,8 +173,8 @@ if (st == CMD_SAVE) { printf("Writing current MBR to disk.\n"); fd = DISK_open(disk->name, O_RDWR); - MBR_make(&mbr, mbr_buf); - if (MBR_write(fd, offset, mbr_buf) == -1) { + MBR_make(&mbr, mbr_buf, disk->real->sec_size); + if (MBR_write(fd, offset, mbr_buf, disk->real->sec_size) == -1) { warn("error writing MBR"); close(fd); goto again; @@ -193,8 +193,8 @@ int USER_print_disk(disk_t *disk) { - int fd, offset, firstoff, i; - char mbr_buf[DEV_BSIZE]; + int fd, offset, firstoff, i, st = 0; + char mbr_buf[MBR_MAX_SIZE]; mbr_t mbr; fd = DISK_open(disk->name, O_RDONLY); @@ -203,7 +203,9 @@ DISK_printmetrics(disk, NULL); do { - MBR_read(fd, (off_t)offset, mbr_buf); + st = MBR_read(fd, (off_t)offset, mbr_buf, disk->real->sec_size); + if (st == -1) + err(1, "MBR_read"); MBR_parse(disk, mbr_buf, offset, firstoff, &mbr); printf("Offset: %d\t", (int)offset); |