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 via email to