1. Run Bootable iso9660 disk to run OS
2. Creating GPT Partition along with FAT32 Partition by FatFS library function f_mkfs() function .
3. Updating Protective MBR (Sector 0)
4. Writing and Updating GPT Partition Header and Partition Entries(Sector 1-33)
5. GPT Backup at Last Sector
6. Copy following files at Sector offset 2048:
Code: Select all
"/BOOT/BOOT_LOA.BMP",
"/BOOT/KERNEL.BIN",
"/BOOT/LIMINE/LIMINE_B.BIN",
"/BOOT/LIMINE/LIMINE_B.SYS",
"/BOOT/LIMINE/LIMINE_U.BIN",
"/BOOT/LIMINE.CON",
"/BOOT/USER_MAI.ELF",
"/BOOT.CAT",
"/EFI/BOOT/BOOTIA32.EFI",
"/EFI/BOOT/BOOTX64.EFI",
Code: Select all
gdisk -l disk_img/disk_1.img
GPT fdisk (gdisk) version 1.0.10
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present
Found valid GPT with protective MBR; using GPT.
Warning! Main partition table overlaps the first partition by 34 blocks!
You will need to delete this partition or resize it in another utility.
Disk disk_img/disk_1.img: 4194304 sectors, 2.0 GiB
Sector size (logical): 512 bytes
Disk identifier (GUID): 14131211-1615-1817-191A-1B1C1D1E1F20
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 4194270
Partitions will be aligned on 2048-sector boundaries
Total free space is 2014 sectors (1007.0 KiB)
Number Start (sector) End (sector) Size Code Name
1 2048 4194270 2.0 GiB EF00 E
Code: Select all
BdsDxe: failed to load Boot0001 "UEFI QEMU HARDDISK QM00013 " from PciRoot(0x0)/Pci(0x2,0x0)/Sata(0x0,0xFFFF,0x0): Not Found
BdsDxe: failed to load Boot0002 "UEFI QEMU HARDDISK QM00015 " from PciRoot(0x0)/Pci(0x2,0x0)/Sata(0x1,0xFFFF,0x0): Not Found
Here my functionss:
Code: Select all
// Function to create protective MBR
bool create_protective_mbr(int disk_no) {
Disk disk = disks[disk_no];
uint64_t total_sectors = disk.total_sectors;
uint8_t mbr[512];
memset(mbr, 0, sizeof(mbr));
// ---- Partition Entry @ offset 0x1BE ----
// Boot indicator
mbr[446] = 0x00; // non-bootable
// Starting CHS (C=0, H=0, S=2)
mbr[447] = 0x00; // head
mbr[448] = 0x02; // sector (2)
mbr[449] = 0x00; // cylinder low
// Partition type: 0xEE = GPT protective
mbr[450] = 0xEE;
// Ending CHS (max out)
mbr[451] = 0xFF;
mbr[452] = 0xFF;
mbr[453] = 0xFF;
// Starting LBA = 1
mbr[454] = 0x01;
mbr[455] = 0x00;
mbr[456] = 0x00;
mbr[457] = 0x00;
// Size in sectors = total_sectors - 1 (limited to 32-bit)
uint32_t size_lba = (total_sectors > 0xFFFFFFFFULL) ? 0xFFFFFFFF : (uint32_t)(total_sectors - 1);
mbr[458] = (size_lba >> 0) & 0xFF;
mbr[459] = (size_lba >> 8) & 0xFF;
mbr[460] = (size_lba >> 16) & 0xFF;
mbr[461] = (size_lba >> 24) & 0xFF;
// ---- Boot signature ----
mbr[510] = 0x55;
mbr[511] = 0xAA;
// ---- Write LBA 0 ----
return kebla_disk_write(disk_no, 0, 1, mbr);
}
// CRC32 lookup table
static uint32_t crc32_table[256];
static int crc32_table_computed = 0;
// Generate CRC32 lookup table
static void generate_crc32_table(void) {
if (crc32_table_computed) return;
for (uint32_t i = 0; i < 256; i++) {
uint32_t c = i;
for (int j = 0; j < 8; j++) {
if (c & 1) {
c = 0xEDB88320 ^ (c >> 1);
} else {
c = c >> 1;
}
}
crc32_table[i] = c;
}
crc32_table_computed = 1;
}
// Calculate CRC32 for data buffer
uint32_t crc32(const void *buf, size_t len){
generate_crc32_table();
const uint8_t *data = (const uint8_t *)buf;
uint32_t crc = 0xFFFFFFFF;
for (size_t i = 0; i < len; i++) {
uint8_t byte = data[i];
uint32_t index = (crc ^ byte) & 0xFF;
crc = (crc >> 8) ^ crc32_table[index];
}
return ~crc;
}
// Function to create GPT header
bool create_gpt_header(int disk_no){
Disk disk = disks[disk_no];
uint64_t total_sectors = disk.total_sectors;
gpt_header_t header = {0};
// GPT signature
header.signature = 0x5452415020494645ULL; // "EFI PART"
header.revision = 0x00010000;
header.header_size = sizeof(gpt_header_t);
header.current_lba = 1;
header.backup_lba = total_sectors - 1;
header.first_usable_lba = 34;
header.last_usable_lba = total_sectors - 34; // Use actual disk size
header.partition_entries_lba = 2;
header.num_partition_entries = 128;
header.partition_entry_size = sizeof(gpt_partition_entry_t);
// Generate disk GUID
for(int i = 0; i < 16; i++) {
header.disk_guid[i] = 0x11 + i;
}
// Calculate header CRC32 (temporarily set to 0 for calculation)
header.header_crc32 = 0;
header.header_crc32 = crc32(&header, header.header_size);
return kebla_disk_write(disk_no, 1, 1, &header);
}
bool create_complete_gpt(int disk_no) {
Disk disk = disks[disk_no];
uint64_t total_sectors = disk.total_sectors;
// Create partition entries array
gpt_partition_entry_t partitions[128] = {0};
// Create EFI system partition (first entry)
uint8_t efi_type_guid[16] = {0x28, 0x73, 0x2A, 0xC1, 0x1F, 0xF8, 0xD2, 0x11,
0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B};
memcpy(partitions[0].type_guid, efi_type_guid, 16);
// Generate partition GUID
for(int i = 0; i < 16; i++) {
partitions[0].partition_guid[i] = 0x22 + i;
}
// FIX: Don't use entire disk - leave space for backup GPT
partitions[0].first_lba = 2048;
partitions[0].last_lba = total_sectors - 34; // Leave last 33 sectors for backup GPT
// Set EFI system partition attributes (bit 1 = legacy BIOS bootable)
partitions[0].attributes = 0x1; // OR 0x8000000000000001 for UEFI required
// Partition name
const char* name = "EFI System Partition";
for(int i = 0; i < strlen(name) && i < 36; i++) {
partitions[0].name[i * 2] = name[i]; // UTF-16LE low byte
partitions[0].name[i * 2 + 1] = 0; // UTF-16LE high byte
}
// Calculate partition entries CRC32
uint32_t num_entries = 128;
uint32_t entry_size = sizeof(gpt_partition_entry_t);
uint32_t partition_entries_crc = crc32(partitions, num_entries * entry_size);
// Create primary GPT header
gpt_header_t primary_header = {0};
primary_header.signature = 0x5452415020494645ULL;
primary_header.revision = 0x00010000;
primary_header.header_size = sizeof(gpt_header_t);
primary_header.current_lba = 1;
primary_header.backup_lba = total_sectors - 1;
primary_header.first_usable_lba = 34;
primary_header.last_usable_lba = total_sectors - 34; // Last usable before backup area
primary_header.partition_entries_lba = 2;
primary_header.num_partition_entries = num_entries;
primary_header.partition_entry_size = entry_size;
primary_header.partition_entries_crc32 = partition_entries_crc;
// Generate disk GUID
for(int i = 0; i < 16; i++) {
primary_header.disk_guid[i] = 0x11 + i;
}
// Calculate primary header CRC32
primary_header.header_crc32 = 0;
primary_header.header_crc32 = crc32(&primary_header, primary_header.header_size);
// Create backup GPT header
gpt_header_t backup_header = primary_header;
backup_header.current_lba = total_sectors - 1; // Backup header at end
backup_header.backup_lba = 1; // Points to primary header
backup_header.partition_entries_lba = total_sectors - 33; // Backup entries before header
// Calculate backup header CRC32
backup_header.header_crc32 = 0;
backup_header.header_crc32 = crc32(&backup_header, backup_header.header_size);
// Write everything
bool success = true;
// Primary GPT structures
success = success && kebla_disk_write(disk_no, 1, 1, &primary_header); // Primary header
success = success && kebla_disk_write(disk_no, 2, 32, partitions); // Primary partition table (32 sectors)
// Backup GPT structures
success = success && kebla_disk_write(disk_no, (total_sectors - 33), 32, partitions); // Backup partition table
success = success && kebla_disk_write(disk_no, (total_sectors - 1), 1, &backup_header); // Backup header
return success;
}
I am getting this disk behavior:
Code: Select all
sudo gdisk disk_img/disk_1.img
GPT fdisk (gdisk) version 1.0.10
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present
Found valid GPT with protective MBR; using GPT.
Warning! Main partition table overlaps the first partition by 34 blocks!
You will need to delete this partition or resize it in another utility.
Command (? for help): p
Disk disk_img/disk_1.img: 4194304 sectors, 2.0 GiB
Sector size (logical): 512 bytes
Disk identifier (GUID): 14131211-1615-1817-191A-1B1C1D1E1F20
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 4194270
Partitions will be aligned on 2048-sector boundaries
Total free space is 2014 sectors (1007.0 KiB)
Number Start (sector) End (sector) Size Code Name
1 2048 4194270 2.0 GiB EF00 E
Code: Select all
Servicing hardware INT=0x20
727: v=20 e=0000 i=0 cpl=0 IP=0038:000000007e8dcbcd pc=000000007e8dcbcd SP=0030:000000007fe65850 env->regs[R_EAX]=0000000000000060
RAX=0000000000000060 RBX=000000007e744398 RCX=0000000000000011 RDX=00000000000003fd
RSI=0000000000000005 RDI=000000007e744398 RBP=000000007fe65860 RSP=000000007fe65850
R8 =000000007fe6594c R9 =00000000000003fd R10=00000000000005f2 R11=0000000000000001
R12=000000007e7443a8 R13=0000000000000000 R14=000000007fe6588f R15=000000007fe887c0
RIP=000000007e8dcbcd RFL=00000293 [--S-A-C] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0038 0000000000000000 ffffffff 00af9a00 DPL=0 CS64 [-R-]
SS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT= 000000007f5dc000 00000047
IDT= 000000007f137018 00000fff
CR0=80010033 CR2=0000000000000000 CR3=000000007f801000 CR4=00000668
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000091 CCD=fffffffffffffffe CCO=EFLAGS
EFER=0000000000000d00
Servicing hardware INT=0x20
728: v=20 e=0000 i=0 cpl=0 IP=0038:000000007e8dcbcd pc=000000007e8dcbcd SP=0030:000000007fe65850 env->regs[R_EAX]=0000000000000060
RAX=0000000000000060 RBX=000000007e744398 RCX=0000000000000011 RDX=00000000000003fd
RSI=0000000000000005 RDI=000000007e744398 RBP=000000007fe65860 RSP=000000007fe65850
R8 =000000007fe6594c R9 =00000000000003fd R10=00000000000005f2 R11=0000000000000001
R12=000000007e7443a8 R13=0000000000000000 R14=000000007fe6588f R15=000000007fe887c0
RIP=000000007e8dcbcd RFL=00000293 [--S-A-C] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0038 0000000000000000 ffffffff 00af9a00 DPL=0 CS64 [-R-]
SS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT= 000000007f5dc000 00000047
IDT= 000000007f137018 00000fff
CR0=80010033 CR2=0000000000000000 CR3=000000007f801000 CR4=00000668
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000091 CCD=0000000000000000 CCO=EFLAGS
EFER=0000000000000d00

