From ae656a0f818b8923edc3b3c166ab7b75d6c20af1 Mon Sep 17 00:00:00 2001 From: CTCaer Date: Mon, 27 Apr 2020 08:58:37 +0300 Subject: [PATCH] types: User a proper struct for MBR partition table --- bootloader/storage/mbr_gpt.h | 84 +++++++++++++++++++++++++ bootloader/storage/nx_emmc.c | 1 + nyx/nyx_gui/frontend/fe_emmc_tools.c | 11 ++-- nyx/nyx_gui/frontend/fe_emummc_tools.c | 5 +- nyx/nyx_gui/frontend/gui_emmc_tools.c | 2 +- nyx/nyx_gui/frontend/gui_emummc_tools.c | 37 +++++------ nyx/nyx_gui/storage/mbr_gpt.h | 84 +++++++++++++++++++++++++ nyx/nyx_gui/storage/nx_emmc.c | 1 + 8 files changed, 196 insertions(+), 29 deletions(-) create mode 100644 bootloader/storage/mbr_gpt.h create mode 100644 nyx/nyx_gui/storage/mbr_gpt.h diff --git a/bootloader/storage/mbr_gpt.h b/bootloader/storage/mbr_gpt.h new file mode 100644 index 0000000..7ee5b99 --- /dev/null +++ b/bootloader/storage/mbr_gpt.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2018 naehrwert + * Copyright (c) 2019 CTCaer + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef MBR_GPT_H +#define MBR_GPT_H + +#include "../utils/types.h" + +typedef struct _mbr_chs_t +{ + u8 head; + u8 sector; + u8 cylinder; +} __attribute__((packed)) mbr_chs_t; + +typedef struct _mbr_part_t +{ + u8 status; + mbr_chs_t start_sct_chs; + u8 type; + mbr_chs_t end_sct_chs; + u32 start_sct; + u32 size_sct; +} __attribute__((packed)) mbr_part_t; + +typedef struct _mbr_t +{ + u8 bootstrap[0x1B8]; + u32 signature; + u16 copy_protected; + mbr_part_t partitions[4]; + u16 boot_signature; +} __attribute__((packed)) mbr_t; + +typedef struct _gpt_entry_t +{ + u8 type_guid[0x10]; + u8 part_guid[0x10]; + u64 lba_start; + u64 lba_end; + u64 attrs; + u16 name[36]; +} gpt_entry_t; + +typedef struct _gpt_header_t +{ + u64 signature; // "EFI PART" + u32 revision; + u32 size; + u32 crc32; + u32 res1; + u64 my_lba; + u64 alt_lba; + u64 first_use_lba; + u64 last_use_lba; + u8 disk_guid[0x10]; + u64 part_ent_lba; + u32 num_part_ents; + u32 part_ent_size; + u32 part_ents_crc32; + u8 res2[420]; // Used as first 3 partition entries backup for HOS. +} gpt_header_t; + +typedef struct _gpt_t +{ + gpt_header_t header; + gpt_entry_t entries[128]; +} gpt_t; + +#endif diff --git a/bootloader/storage/nx_emmc.c b/bootloader/storage/nx_emmc.c index 2cae846..05215ef 100644 --- a/bootloader/storage/nx_emmc.c +++ b/bootloader/storage/nx_emmc.c @@ -16,6 +16,7 @@ #include +#include "mbr_gpt.h" #include "nx_emmc.h" #include "emummc.h" #include "../mem/heap.h" diff --git a/nyx/nyx_gui/frontend/fe_emmc_tools.c b/nyx/nyx_gui/frontend/fe_emmc_tools.c index d88573b..a2ada65 100644 --- a/nyx/nyx_gui/frontend/fe_emmc_tools.c +++ b/nyx/nyx_gui/frontend/fe_emmc_tools.c @@ -30,6 +30,7 @@ #include "../mem/heap.h" #include "../sec/se.h" #include "../sec/se_t210.h" +#include "../storage/mbr_gpt.h" #include "../storage/nx_emmc.h" #include "../storage/sdmmc.h" #include "../utils/btn.h" @@ -53,19 +54,17 @@ extern void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_st static void get_valid_partition(u32 *sector_start, u32 *sector_size, u32 *part_idx, bool backup) { sd_mount(); - u8 *mbr = (u8 *)malloc(0x200); + mbr_t *mbr = (mbr_t *)calloc(sizeof(mbr_t), 1); sdmmc_storage_read(&sd_storage, 0, 1, mbr); - memcpy(mbr, mbr + 0x1BE, 0x40); - *part_idx = 0; int i = 0; u32 curr_part_size = 0; for (i = 1; i < 4; i++) { - curr_part_size = *(u32 *)&mbr[0x0C + (0x10 * i)]; - *sector_start = *(u32 *)&mbr[0x08 + (0x10 * i)]; - u8 type = mbr[0x04 + (0x10 * i)]; + curr_part_size = mbr->partitions[i].size_sct; + *sector_start = mbr->partitions[i].start_sct; + u8 type = mbr->partitions[i].type; if ((curr_part_size >= *sector_size) && *sector_start && type != 0x83 && (!backup || type == 0xE0)) break; } diff --git a/nyx/nyx_gui/frontend/fe_emummc_tools.c b/nyx/nyx_gui/frontend/fe_emummc_tools.c index 22c1e1a..8fb19aa 100644 --- a/nyx/nyx_gui/frontend/fe_emummc_tools.c +++ b/nyx/nyx_gui/frontend/fe_emummc_tools.c @@ -27,6 +27,7 @@ #include "../libs/fatfs/ff.h" #include "../mem/heap.h" #include "../sec/se.h" +#include "../storage/mbr_gpt.h" #include "../storage/nx_emmc.h" #include "../storage/sdmmc.h" #include "../utils/btn.h" @@ -596,9 +597,9 @@ static int _dump_emummc_raw_part(emmc_tool_gui_t *gui, int active_part, int part // Hide the partition. if (active_part == 2) { - u8 *mbr = (u8 *)malloc(0x200); + mbr_t *mbr = (mbr_t *)malloc(sizeof(mbr_t)); sdmmc_storage_read(&sd_storage, 0, 1, mbr); - mbr[MBR_1ST_PART_TYPE_OFF + (0x10 * part_idx)] = 0xE0; + mbr->partitions[part_idx].type = 0xE0; sdmmc_storage_write(&sd_storage, 0, 1, mbr); free(mbr); } diff --git a/nyx/nyx_gui/frontend/gui_emmc_tools.c b/nyx/nyx_gui/frontend/gui_emmc_tools.c index 10981a5..c01ab84 100644 --- a/nyx/nyx_gui/frontend/gui_emmc_tools.c +++ b/nyx/nyx_gui/frontend/gui_emmc_tools.c @@ -29,7 +29,7 @@ #include "../mem/heap.h" #include "../sec/se.h" #include "../soc/fuse.h" -#include "../storage/nx_emmc.h" +#include "../storage/nx_sd.h" #include "../storage/sdmmc.h" #include "../utils/sprintf.h" #include "../utils/util.h" diff --git a/nyx/nyx_gui/frontend/gui_emummc_tools.c b/nyx/nyx_gui/frontend/gui_emummc_tools.c index b80d2e2..eef522b 100644 --- a/nyx/nyx_gui/frontend/gui_emummc_tools.c +++ b/nyx/nyx_gui/frontend/gui_emummc_tools.c @@ -21,6 +21,7 @@ #include "../config/ini.h" #include "../libs/fatfs/ff.h" #include "../mem/heap.h" +#include "../storage/mbr_gpt.h" #include "../storage/sdmmc.h" #include "../utils/dirlist.h" #include "../utils/list.h" @@ -34,8 +35,6 @@ extern bool sd_mount(); extern void sd_unmount(bool deinit); extern void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_storage_t *storage); -#define MBR_1ST_PART_TYPE_OFF 0x1C2 - static int part_idx; static u32 sector_start; @@ -160,12 +159,11 @@ static void _create_mbox_emummc_raw() lv_obj_set_width(mbox, LV_HOR_RES / 9 * 6); char *txt_buf = (char *)malloc(0x500); - u8 *mbr = (u8 *)malloc(0x200); + mbr_t *mbr = (mbr_t *)malloc(sizeof(mbr_t)); sd_mount(); sdmmc_storage_read(&sd_storage, 0, 1, mbr); sd_unmount(false); - memcpy(mbr, mbr + 0x1BE, 0x40); sdmmc_storage_t storage; sdmmc_t sdmmc; @@ -173,9 +171,9 @@ static void _create_mbox_emummc_raw() for (int i = 1; i < 4; i++) { - u32 curr_part_size = *(u32 *)&mbr[0x0C + (0x10 * i)]; - sector_start = *(u32 *)&mbr[0x08 + (0x10 * i)]; - u8 type = mbr[0x04 + (0x10 * i)]; + u32 curr_part_size = mbr->partitions[i].size_sct; + sector_start = mbr->partitions[i].start_sct; + u8 type = mbr->partitions[i].type; if ((curr_part_size >= (storage.sec_cnt + 0xC000)) && sector_start && type != 0x83) //! TODO: For now it skips linux partitions. { part_idx = i; @@ -201,10 +199,10 @@ static void _create_mbox_emummc_raw() "Part 1: Type: %02x, Start: %08x, Size: %08x\n" "Part 2: Type: %02x, Start: %08x, Size: %08x\n" "Part 3: Type: %02x, Start: %08x, Size: %08x\n", - mbr[0x04], *(u32 *)&mbr[0x08], *(u32 *)&mbr[0x0C], - mbr[0x14], *(u32 *)&mbr[0x18], *(u32 *)&mbr[0x1C], - mbr[0x24], *(u32 *)&mbr[0x28], *(u32 *)&mbr[0x2C], - mbr[0x34], *(u32 *)&mbr[0x38], *(u32 *)&mbr[0x3C]); + mbr->partitions[0].type, mbr->partitions[0].start_sct, mbr->partitions[0].size_sct, + mbr->partitions[1].type, mbr->partitions[1].start_sct, mbr->partitions[1].size_sct, + mbr->partitions[2].type, mbr->partitions[2].start_sct, mbr->partitions[2].size_sct, + mbr->partitions[3].type, mbr->partitions[3].start_sct, mbr->partitions[3].size_sct); lv_mbox_set_text(mbox, txt_buf); @@ -272,9 +270,9 @@ static lv_res_t _create_mbox_emummc_create(lv_obj_t *btn) static void _change_raw_emummc_part_type() { - u8 *mbr = (u8 *)malloc(0x200); + mbr_t *mbr = (mbr_t *)malloc(sizeof(mbr_t)); sdmmc_storage_read(&sd_storage, 0, 1, mbr); - mbr[MBR_1ST_PART_TYPE_OFF + (0x10 * part_idx)] = 0xE0; + mbr->partitions[mbr_ctx.part_idx].type = 0xE0; sdmmc_storage_write(&sd_storage, 0, 1, mbr); free(mbr); } @@ -513,7 +511,7 @@ static lv_res_t _create_mbox_emummc_migrate(lv_obj_t *btn) lv_obj_set_width(mbox, LV_HOR_RES / 9 * 6); char *txt_buf = (char *)malloc(0x500); - u8 *mbr = (u8 *)malloc(0x200); + mbr_t *mbr = (mbr_t *)malloc(sizeof(mbr_t)); u8 *efi_part = (u8 *)malloc(0x200); sd_mount(); @@ -534,7 +532,7 @@ static lv_res_t _create_mbox_emummc_migrate(lv_obj_t *btn) for (int i = 1; i < 4; i++) { - sector_start = *(u32 *)&mbr[0x08 + (0x10 * i)]; + sector_start = mbr->partitions[i].start_sct; if (sector_start) { sdmmc_storage_read(&sd_storage, sector_start + 0xC001, 1, efi_part); @@ -747,19 +745,18 @@ static lv_res_t _create_change_emummc_window() emummc_img = malloc(sizeof(emummc_images_t)); emummc_img->win = win; - u8 *mbr = (u8 *)malloc(0x200); + mbr_t *mbr = (mbr_t *)malloc(sizeof(mbr_t)); char *path = malloc(256); sdmmc_storage_read(&sd_storage, 0, 1, mbr); - memcpy(mbr, mbr + 0x1BE, 0x40); memset(emummc_img->part_path, 0, 3 * 128); for (int i = 1; i < 4; i++) { - emummc_img->part_sector[i - 1] = *(u32 *)&mbr[0x08 + (0x10 * i)]; - emummc_img->part_end[i - 1] = emummc_img->part_sector[i - 1] + *(u32 *)&mbr[0x0C + (0x10 * i)] - 1; - emummc_img->part_type[i - 1] = mbr[0x04 + (0x10 * i)]; + emummc_img->part_sector[i - 1] = mbr->partitions[i].start_sct; + emummc_img->part_end[i - 1] = emummc_img->part_sector[i - 1] + mbr->partitions[i].size_sct - 1; + emummc_img->part_type[i - 1] = mbr->partitions[i].type; } free(mbr); diff --git a/nyx/nyx_gui/storage/mbr_gpt.h b/nyx/nyx_gui/storage/mbr_gpt.h new file mode 100644 index 0000000..7ee5b99 --- /dev/null +++ b/nyx/nyx_gui/storage/mbr_gpt.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2018 naehrwert + * Copyright (c) 2019 CTCaer + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef MBR_GPT_H +#define MBR_GPT_H + +#include "../utils/types.h" + +typedef struct _mbr_chs_t +{ + u8 head; + u8 sector; + u8 cylinder; +} __attribute__((packed)) mbr_chs_t; + +typedef struct _mbr_part_t +{ + u8 status; + mbr_chs_t start_sct_chs; + u8 type; + mbr_chs_t end_sct_chs; + u32 start_sct; + u32 size_sct; +} __attribute__((packed)) mbr_part_t; + +typedef struct _mbr_t +{ + u8 bootstrap[0x1B8]; + u32 signature; + u16 copy_protected; + mbr_part_t partitions[4]; + u16 boot_signature; +} __attribute__((packed)) mbr_t; + +typedef struct _gpt_entry_t +{ + u8 type_guid[0x10]; + u8 part_guid[0x10]; + u64 lba_start; + u64 lba_end; + u64 attrs; + u16 name[36]; +} gpt_entry_t; + +typedef struct _gpt_header_t +{ + u64 signature; // "EFI PART" + u32 revision; + u32 size; + u32 crc32; + u32 res1; + u64 my_lba; + u64 alt_lba; + u64 first_use_lba; + u64 last_use_lba; + u8 disk_guid[0x10]; + u64 part_ent_lba; + u32 num_part_ents; + u32 part_ent_size; + u32 part_ents_crc32; + u8 res2[420]; // Used as first 3 partition entries backup for HOS. +} gpt_header_t; + +typedef struct _gpt_t +{ + gpt_header_t header; + gpt_entry_t entries[128]; +} gpt_t; + +#endif diff --git a/nyx/nyx_gui/storage/nx_emmc.c b/nyx/nyx_gui/storage/nx_emmc.c index b801f1a..d30b374 100644 --- a/nyx/nyx_gui/storage/nx_emmc.c +++ b/nyx/nyx_gui/storage/nx_emmc.c @@ -16,6 +16,7 @@ #include +#include "mbr_gpt.h" #include "nx_emmc.h" #include "../mem/heap.h" #include "../utils/list.h"