summaryrefslogtreecommitdiffhomepage
path: root/lib/partition-map.h
blob: f034335144fa2121bfe302c2836dd374ae161327 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/* -------------------------------------------

  Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved.

------------------------------------------- */

#ifndef __PARTITION_MAP_H__
#define __PARTITION_MAP_H__

#include <lib/boot.h>

/* @brief AMD64 magic for EPM */
#define EPM_MAGIC_X86 "EPMAM"

/* @brief RISC-V magic for EPM */
#define EPM_MAGIC_RV "EPMRV"

/* @brief ARM magic for EPM */
#define EPM_MAGIC_ARM "EPMAR"

/* @brief 64x0 magic for EPM */
#define EPM_MAGIC_64X0 "EPM64"

/* @brief 32x0 magic for EPM */
#define EPM_MAGIC_32X0 "EPM32"

/* @brief POWER magic for EPM */
#define EPM_MAGIC_PPC "EPMPC"

#ifdef __aarch64__
#define EPM_MAGIC EPM_MAGIC_ARM
#elif defined(__riscv64__)
#define EPM_MAGIC EPM_MAGIC_RV
#else
#define EPM_MAGIC "EPMMS" /* mass storage */
#endif

#define EPM_MAX_BLKS (128) /* 1 on UEFI EPM, because of it would only fit on a sector. */

/// @brief Size of a partition block (roughly 512 bytes)
#define EPM_PART_BLK_SZ sizeof(struct part_block)

/// @brief Start of EPM headers.
/// @note There could be anything before this LBA.
/// Such as PC specific structures.
#define EPM_PART_BLK_START (0)

/// @brief EPM revision (actually at version 2)
#define EPM_REVISION (2U)

/// @brief EPM GUID block.
typedef struct boot_guid {
  uint32_t data1;
  uint16_t data2;
  uint16_t data3;
  uint8_t  data4[8];
} __attribute__((packed)) boot_guid_t;

/* The first 0 > 128 addresses of a disk contains these headers. */

/**
 * @brief The EPM partition block.
 * used to represent a partition inside a media.
 */
struct __attribute__((packed)) part_block {
  ascii_char_t magic[5];
  ascii_char_t name[32];
  boot_guid_t  uuid;
  int32_t      version;
  int32_t      num_blocks;
  int64_t      lba_start;
  int64_t      sector_sz;
  int64_t      lba_end;
  int16_t      type;
  int32_t      fs_version;
  ascii_char_t fs[16]; /* ffs_2 */
  ascii_char_t reserved[401];
};

typedef struct part_block part_block_t;

///! @brief variant enum.
///! use it in the boot block version field.
enum {
  EPM_INVALID     = 0x00,
  EPM_GENERIC_OS  = 0xcf,
  EPM_LINUX       = 0x8f,
  EPM_BSD         = 0x9f,
  EPM_NEKERNEL_OS = 0x1f,
  EPM_SNU_OS      = 0x2f,
};

/// @brief check for supported filesystem.
boolean cb_filesystem_exists(caddr_t fs, size_t len);

/// @brief Parse EPM block from blob.
bool cb_parse_partition_block_data_at(voidptr_t blob, size_t blob_sz, size_t index, size_t* end_lba,
                                      size_t* start_lba, size_t* sector_sz);

/// @brief Parse Partition block info at index.
/// @param index the partition block to parse.
part_block_t* cb_parse_partition_block_at(voidptr_t blob, size_t blob_sz, size_t index);

#endif  // ifndef __PARTITION_MAP_H__