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, §);
+
+ 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: