[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#272063: support for Xbox partitions



Package: kernel
Severity: wishlist
Tags: patch

The Xbox makes use of a static and implicit partitioning scheme.  The
locations and sizes of the four partitions on the Xbox hard disk are
hard-coded into the native Xbox kernel.

This patch is needed to access a hard disk partitioned for the Xbox under a
PC running a Linux kernel.  It is useless without FATX support, though (see
bug #272029).

-- System Information:
Debian Release: 3.1
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: i386 (i686)
Kernel: Linux 2.4.27-1-686
Locale: LANG=C, LC_CTYPE=C (ignored: LC_ALL set to C)
diff -Nur kernel-source-2.4.27-2.4.27.old/Documentation/Configure.help kernel-source-2.4.27-2.4.27/Documentation/Configure.help
--- kernel-source-2.4.27-2.4.27.old/Documentation/Configure.help	2004-09-13 23:30:48.000000000 +0200
+++ kernel-source-2.4.27-2.4.27/Documentation/Configure.help	2004-09-17 08:41:37.000000000 +0200
@@ -17649,6 +17649,18 @@
   Say Y here if you would like to use hard disks under Linux which
   were partitioned on a Macintosh.
 
+Xbox partition support
+CONFIG_XBOX_PARTITION
+  The Xbox makes use of a static and implicit partitioning scheme.
+  The locations and sizes of the four partitions on the Xbox hard
+  disk are hard-coded into the native Xbox kernel.
+
+  Say Y here if you are running Linux on the Xbox, or would like
+  to access a hard disk partitioned for the Xbox under a PC
+  running Linux.
+
+  If unsure, say N.
+
 Windows Logical Disk Manager (Dynamic Disk) support (EXPERIMENTAL)
 CONFIG_LDM_PARTITION
   Say Y here if you would like to use hard disks under Linux which
diff -Nur kernel-source-2.4.27-2.4.27.old/fs/partitions/Config.in kernel-source-2.4.27-2.4.27/fs/partitions/Config.in
--- kernel-source-2.4.27-2.4.27.old/fs/partitions/Config.in	2002-11-29 00:53:15.000000000 +0100
+++ kernel-source-2.4.27-2.4.27/fs/partitions/Config.in	2004-09-17 08:41:37.000000000 +0200
@@ -18,6 +18,7 @@
       bool '  IBM disk label and partition support' CONFIG_IBM_PARTITION
    fi
    bool '  Macintosh partition map support' CONFIG_MAC_PARTITION
+   bool '  Xbox partition support' CONFIG_XBOX_PARTITION
    bool '  PC BIOS (MSDOS partition tables) support' CONFIG_MSDOS_PARTITION
    if [ "$CONFIG_MSDOS_PARTITION" = "y" ]; then
       bool '    BSD disklabel (FreeBSD partition tables) support' CONFIG_BSD_DISKLABEL
diff -Nur kernel-source-2.4.27-2.4.27.old/fs/partitions/Makefile kernel-source-2.4.27-2.4.27/fs/partitions/Makefile
--- kernel-source-2.4.27-2.4.27.old/fs/partitions/Makefile	2002-11-29 00:53:15.000000000 +0100
+++ kernel-source-2.4.27-2.4.27/fs/partitions/Makefile	2004-09-17 08:41:37.000000000 +0200
@@ -19,6 +19,7 @@
 obj-$(CONFIG_MAC_PARTITION) += mac.o
 obj-$(CONFIG_LDM_PARTITION) += ldm.o
 obj-$(CONFIG_MSDOS_PARTITION) += msdos.o
+obj-$(CONFIG_XBOX_PARTITION) += xbox.o
 obj-$(CONFIG_OSF_PARTITION) += osf.o
 obj-$(CONFIG_SGI_PARTITION) += sgi.o
 obj-$(CONFIG_SUN_PARTITION) += sun.o
diff -Nur kernel-source-2.4.27-2.4.27.old/fs/partitions/check.c kernel-source-2.4.27-2.4.27/fs/partitions/check.c
--- kernel-source-2.4.27-2.4.27.old/fs/partitions/check.c	2004-02-18 14:36:31.000000000 +0100
+++ kernel-source-2.4.27-2.4.27/fs/partitions/check.c	2004-09-17 08:41:37.000000000 +0200
@@ -34,7 +34,9 @@
 #include "ibm.h"
 #include "ultrix.h"
 #include "efi.h"
-
+#ifdef CONFIG_XBOX_PARTITION
+#include "xbox.h"
+#endif
 extern int *blk_size[];
 
 int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/
@@ -268,6 +270,12 @@
 
 	printk(" unknown partition table\n");
 setup_devfs:
+/* if the drive is Xbox-formatted, add partitions 50+ to the existing
+   partitions - this way, an Xbox HD can have 2 partitioning systems
+   systems: the implicit Xbox one (50+) and the explicit one (1+) */
+#ifdef CONFIG_XBOX_PARTITION
+        xbox_partition(hd, bdev, first_sector, first_part_minor);
+#endif
 	invalidate_bdev(bdev, 1);
 	truncate_inode_pages(bdev->bd_inode->i_mapping, 0);
 	bdput(bdev);
diff -Nur kernel-source-2.4.27-2.4.27.old/fs/partitions/xbox.c kernel-source-2.4.27-2.4.27/fs/partitions/xbox.c
--- kernel-source-2.4.27-2.4.27.old/fs/partitions/xbox.c	1970-01-01 01:00:00.000000000 +0100
+++ kernel-source-2.4.27-2.4.27/fs/partitions/xbox.c	2004-09-17 08:41:42.000000000 +0200
@@ -0,0 +1,148 @@
+/*
+ *  fs/partitions/xbox.c
+ *
+ *  Created in June 2002 by SpeedBump
+ *  additions/policy changes/cleanups
+ *  by Edgar Hucek and Michael Steil
+ */
+
+#include <linux/config.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/genhd.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/blk.h>
+
+#ifdef CONFIG_BLK_DEV_IDE
+#include <linux/ide.h>	/* IDE xlate */
+#endif /* CONFIG_BLK_DEV_IDE */
+
+#include <asm/system.h>
+
+#include "check.h"
+#include "xbox.h"
+
+#define XBOX_SECTOR_STORE	(0x0055F400L)
+#define XBOX_SECTOR_SYSTEM	(0x00465400L)
+#define XBOX_SECTOR_CONFIG	(0x00000000L)
+#define XBOX_SECTOR_CACHE1	(0x00000400L)
+#define XBOX_SECTOR_CACHE2	(0x00177400L)
+#define XBOX_SECTOR_CACHE3	(0x002EE400L)
+#define XBOX_SECTOR_EXTEND_F	(0x00EE8AB0L)
+#define XBOX_SECTOR_EXTEND_G	(0x0FFFFFFFL)
+
+#define XBOX_SECTORS_STORE	(XBOX_SECTOR_EXTEND_F - XBOX_SECTOR_STORE)
+#define XBOX_SECTORS_SYSTEM	(XBOX_SECTOR_STORE  - XBOX_SECTOR_SYSTEM)
+#define XBOX_SECTORS_CACHE1	(XBOX_SECTOR_CACHE2 - XBOX_SECTOR_CACHE1)
+#define XBOX_SECTORS_CACHE2	(XBOX_SECTOR_CACHE3 - XBOX_SECTOR_CACHE2)
+#define XBOX_SECTORS_CACHE3	(XBOX_SECTOR_SYSTEM - XBOX_SECTOR_CACHE3)
+#define XBOX_SECTORS_CONFIG	(XBOX_SECTOR_CACHE1 - XBOX_SECTOR_CONFIG)
+/*F *may* end here - it depends on whether there's a G */
+#define XBOX_SECTORS_EXTEND_F_POSS (XBOX_SECTOR_EXTEND_G - XBOX_SECTOR_EXTEND_F)
+
+
+#define XBOX_SECTOR_MAGIC	(3L)
+
+static int
+xbox_sig_string_match(	struct block_device *bdev, 
+			unsigned long at_sector,
+			char *expect )
+{
+	Sector sect;
+	int retv;
+	char *data;
+
+	data = read_dev_sector(bdev, at_sector, &sect);
+	
+	if (!data) return 0;
+	
+	if (*(u32*)expect == *(u32*)data) retv = 1; else retv = 0;
+	
+	put_dev_sector(sect);
+	
+	/*
+	if (!retv) {
+		printk("xbox_sig_string_match: %s not found...found %c%c%c%c\n",
+			expect,data[0],data[1],data[2],data[3]);
+		for(i = 1; i<=512; i++) {
+			printk(((i%32)?"%02X ":"%02X\n"),(unsigned char)data[i]);
+		}
+	}
+	*/
+	return retv;
+}
+
+static inline int
+xbox_drive_detect(struct block_device *bdev)
+{
+	
+	/** 
+	* "BRFR" is apparently the magic number in the config area
+	* the others are just paranoid checks to assure the expected
+	* "FATX" tags for the other xbox partitions
+	*
+	* the odds against a non-xbox drive having random data to match is
+	* astronomical...but it's possible I guess...you should only include
+	* this check if you actually *have* an xbox drive...since it has to
+	* be detected first
+	*
+	* @see check.c
+	*/
+	if (	(xbox_sig_string_match(bdev,XBOX_SECTOR_MAGIC ,"BRFR")) &&
+		(xbox_sig_string_match(bdev,XBOX_SECTOR_SYSTEM,"FATX")) &&
+		(xbox_sig_string_match(bdev,XBOX_SECTOR_STORE ,"FATX"))) {
+		return 1; //success
+	}
+	
+	return 0; // no xbox drive
+}
+
+int xbox_partition(struct gendisk *hd, struct block_device *bdev,
+		   unsigned long first_sector, int first_part_minor)
+{
+	kdev_t dev;
+	unsigned long last_sector;
+	unsigned long last_lba28_sector;
+	int minor = first_part_minor;
+	int retv;
+	
+	// return if not hda, avoiding NULL pointers and Oopses
+	// if (hd->major != 3) return 0;
+
+	dev = to_kdev_t(bdev->bd_dev);
+	
+	last_sector = (blk_size[hd->major][minor] << 1) + 1; 
+	
+	if (first_sector != 0) {
+		//we only accept whole ide drives...no partials
+		printk("xbox_partition: failed...first_sector != 0 == %ld\n",first_sector);
+		return 0;
+	}
+	
+	retv = xbox_drive_detect(bdev);
+	if (retv > 0) {
+		/* trying to find the first free partition */
+		minor = 50;
+		add_gd_partition(hd,minor++,XBOX_SECTOR_STORE ,XBOX_SECTORS_STORE );
+		add_gd_partition(hd,minor++,XBOX_SECTOR_SYSTEM,XBOX_SECTORS_SYSTEM);
+		add_gd_partition(hd,minor++,XBOX_SECTOR_CACHE1,XBOX_SECTORS_CACHE1);
+		add_gd_partition(hd,minor++,XBOX_SECTOR_CACHE2,XBOX_SECTORS_CACHE2);
+		add_gd_partition(hd,minor++,XBOX_SECTOR_CACHE3,XBOX_SECTORS_CACHE3);
+		/* Support for 'extended partitions' */
+		if (xbox_sig_string_match(bdev,XBOX_SECTOR_EXTEND_F ,"FATX")) {
+			if ((XBOX_SECTOR_EXTEND_G < last_sector) && xbox_sig_string_match(bdev, XBOX_SECTOR_EXTEND_G, "FATX")) {
+				/* There's an F and G on this system - F only goes to the LBA28 boundary */
+				add_gd_partition(hd,minor++,XBOX_SECTOR_EXTEND_F,XBOX_SECTORS_EXTEND_F_POSS);
+				/* G goes to end of drive */
+				add_gd_partition(hd,minor++,XBOX_SECTOR_EXTEND_G, last_sector-XBOX_SECTOR_EXTEND_G);	
+			}
+			/* Just a large F on this system - to end of drive*/
+			else add_gd_partition(hd,minor++,XBOX_SECTOR_EXTEND_F,last_sector-XBOX_SECTOR_EXTEND_F);
+		}
+	} else {
+		//not an xbox drive
+		return 0;
+	}
+}
diff -Nur kernel-source-2.4.27-2.4.27.old/fs/partitions/xbox.h kernel-source-2.4.27-2.4.27/fs/partitions/xbox.h
--- kernel-source-2.4.27-2.4.27.old/fs/partitions/xbox.h	1970-01-01 01:00:00.000000000 +0100
+++ kernel-source-2.4.27-2.4.27/fs/partitions/xbox.h	2004-09-17 08:41:37.000000000 +0200
@@ -0,0 +1,7 @@
+/*
+ *  fs/partitions/xbox.h
+ */
+
+int xbox_partition(struct gendisk *hd, struct block_device *bdev,
+		   unsigned long first_sector, int first_part_minor);
+

Reply to: