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