Unix Technical Forum

Re: [PATCH] iPod nano 8G

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


Go Back   Unix Technical Forum > Unix Operating Systems > OpenBSD > mailing.openbsd.tech

Register FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 02-18-2008, 08:59 AM
Tobias Weingartner
 
Posts: n/a
Default Re: [PATCH] iPod nano 8G

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);

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 02:36 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com