Skip to content

Instantly share code, notes, and snippets.

@dogtopus
Created September 14, 2020 20:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dogtopus/8ae56d29f93fe1370c4ad629a54ab30d to your computer and use it in GitHub Desktop.
Save dogtopus/8ae56d29f93fe1370c4ad629a54ab30d to your computer and use it in GitHub Desktop.
PSVita eMMC partition table support for kpartx
diff --git a/kpartx/Makefile b/kpartx/Makefile
index 2906a984..0404f029 100644
--- a/kpartx/Makefile
+++ b/kpartx/Makefile
@@ -13,7 +13,7 @@ ifneq ($(call check_func,dm_task_set_cookie,/usr/include/libdevmapper.h),0)
endif
OBJS = bsd.o dos.o kpartx.o solaris.o unixware.o dasd.o sun.o \
- gpt.o mac.o ps3.o crc32.o lopart.o xstrncpy.o devmapper.o
+ gpt.o mac.o ps3.o psvita.o crc32.o lopart.o xstrncpy.o devmapper.o
EXEC = kpartx
diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c
index d3620c5c..bf7fdf97 100644
--- a/kpartx/kpartx.c
+++ b/kpartx/kpartx.c
@@ -76,6 +76,7 @@ addpts(char *t, ptreader f)
static void
initpts(void)
{
+ addpts("psvita", read_psvita_pt);
addpts("gpt", read_gpt_pt);
addpts("dos", read_dos_pt);
addpts("bsd", read_bsd_pt);
diff --git a/kpartx/kpartx.h b/kpartx/kpartx.h
index 67edeb82..02666b55 100644
--- a/kpartx/kpartx.h
+++ b/kpartx/kpartx.h
@@ -60,6 +60,7 @@ extern ptreader read_dasd_pt;
extern ptreader read_mac_pt;
extern ptreader read_sun_pt;
extern ptreader read_ps3_pt;
+extern ptreader read_psvita_pt;
char *getblock(int fd, unsigned int secnr);
diff --git a/kpartx/psvita.c b/kpartx/psvita.c
new file mode 100644
index 00000000..2e601e1c
--- /dev/null
+++ b/kpartx/psvita.c
@@ -0,0 +1,60 @@
+/*
+ * Part of this file is based on mbrtool by SKGleba.
+ * Copyright (c) 2020 SKGleba, dogtopus
+ */
+
+#include "kpartx.h"
+#include "byteorder.h"
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define MAX_PARTITIONS 16
+
+typedef struct
+{
+ uint32_t off;
+ uint32_t sz;
+ uint8_t code;
+ uint8_t type;
+ uint8_t active;
+ uint32_t flags;
+ uint16_t unk;
+} __attribute__((packed)) psvita_partition_t;
+
+typedef struct
+{
+ char magic[0x20];
+ uint32_t version;
+ uint32_t device_size;
+ char unk1[0x28];
+ psvita_partition_t partitions[MAX_PARTITIONS];
+ char unk2[0x5e];
+ char unk3[0x10 * 4];
+ uint16_t sig;
+} __attribute__((packed)) psvita_master_block_t;
+
+static const char mbr_magic[0x20] = "Sony Computer Entertainment Inc.";
+
+int
+read_psvita_pt(int fd, __attribute__((unused)) struct slice all,
+ struct slice *sp, __attribute__((unused)) unsigned int ns)
+{
+ psvita_master_block_t *mbr = NULL;
+ int i = 0, n = 0;
+ mbr = (psvita_master_block_t *) getblock(fd, 0);
+ if (!mbr) return -1;
+ if (memcmp(mbr->magic, mbr_magic, sizeof(mbr_magic)) != 0) {
+ free(mbr);
+ return -1;
+ }
+ for (i=0; i<MAX_PARTITIONS; i++) {
+ if (mbr->partitions[i].code != 0) {
+ sp[n].start = mbr->partitions[i].off;
+ sp[n].size = mbr->partitions[i].sz;
+ n++;
+ }
+ }
+ free(mbr);
+ return n;
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment