diff --git a/generate_nand.c b/generate_nand.c index 49b73c5..609aaf6 100644 --- a/generate_nand.c +++ b/generate_nand.c @@ -64,10 +64,11 @@ uint32_t crc32(const uint8_t *buf, int len) return update_crc32(0xffffffffL, buf, len) ^ 0xffffffffL; } -void get_physical_address(uint32_t vpn, uint32_t *bank, uint32_t *physical_block_index, uint32_t *page_in_block) { +void get_physical_address(uint32_t vpn, uint32_t *bank, uint32_t *pn) { *bank = vpn % BANKS; - *physical_block_index = vpn / PAGES_PER_SUBLOCK; - *page_in_block = (vpn / BANKS) % PAGES_PER_BLOCK; + uint32_t pbi = vpn / PAGES_PER_SUBLOCK; + uint32_t pib = (vpn / BANKS) % PAGES_PER_BLOCK; + *pn = pbi * PAGES_PER_BLOCK + pib; } void write_page(uint8_t *page, uint8_t *spare, int bank, int page_index) { @@ -136,14 +137,14 @@ void write_vfl_context() { } void write_ftl_context() { - uint32_t bank, pbi, pib; + uint32_t bank, pn; // set the FTL spare type of the first page of the FTL CXT block to indicate that there is a CTX index VFLSpare *vfl_ctx_spare = (VFLSpare *)calloc(BYTES_PER_SPARE, sizeof(char)); vfl_ctx_spare->bSpareType = FTL_SPARE_TYPE_CXT_INDEX; vfl_ctx_spare->eccMarker = 0xff; - get_physical_address( (FTL_CXT_SECTION_START + FTL_CTX_VBLK_IND) * PAGES_PER_SUBLOCK, &bank, &pbi, &pib); - write_page(NULL, (uint8_t *)vfl_ctx_spare, 0, pbi * PAGES_PER_BLOCK + pib); + get_physical_address( (FTL_CXT_SECTION_START + FTL_CTX_VBLK_IND) * PAGES_PER_SUBLOCK, &bank, &pn); + write_page(NULL, (uint8_t *)vfl_ctx_spare, 0, pn); // create the FTL Meta page on the last page of the FTL Cxt block and embed the right versions FTLMeta *ftl_meta = (FTLMeta *)calloc(sizeof(FTLMeta), sizeof(char)); @@ -169,37 +170,38 @@ void write_ftl_context() { for(int ind_in_map = 0; ind_in_map < 1024; ind_in_map++) { mapping_page[ind_in_map] = (i * 1024) + ind_in_map + 1; } - get_physical_address( FTL_CXT_SECTION_START * PAGES_PER_SUBLOCK + i + 1, &bank, &pbi, &pib); - //printf("Writing to bank %d and page %d (vp: %d)\n", bank, pbi * PAGES_PER_BLOCK + pib, FTL_CXT_SECTION_START * PAGES_PER_SUBLOCK + i + 1); - write_page((uint8_t *)mapping_page, NULL, bank, pbi * PAGES_PER_BLOCK + pib); + get_physical_address( FTL_CXT_SECTION_START * PAGES_PER_SUBLOCK + i + 1, &bank, &pn); + write_page((uint8_t *)mapping_page, NULL, bank, pn); } vfl_ctx_spare = (VFLSpare *)calloc(BYTES_PER_SPARE, sizeof(char)); vfl_ctx_spare->bSpareType = FTL_SPARE_TYPE_CXT_INDEX; - get_physical_address( (FTL_CXT_SECTION_START + FTL_CTX_VBLK_IND + 1) * PAGES_PER_SUBLOCK - 1, &bank, &pbi, &pib); + get_physical_address( (FTL_CXT_SECTION_START + FTL_CTX_VBLK_IND + 1) * PAGES_PER_SUBLOCK - 1, &bank, &pn); printf("Writing FTL Meta to virtual page %d\n", (FTL_CXT_SECTION_START + FTL_CTX_VBLK_IND + 1) * PAGES_PER_SUBLOCK - 1); - write_page((uint8_t *)ftl_meta, (uint8_t *)vfl_ctx_spare, bank, pbi * PAGES_PER_BLOCK + pib); + write_page((uint8_t *)ftl_meta, (uint8_t *)vfl_ctx_spare, bank, pn); } uint32_t write_hfs_partition(char *filename, uint32_t page_offset) { // write the HFS+ partition to the first page and update the associated spare - uint32_t bank, pbi, pib; + uint32_t bank, pn, vpn; FILE *hfs_file = fopen(filename, "rb"); fseek(hfs_file, 0L, SEEK_END); int partition_size = ftell(hfs_file); fclose(hfs_file); hfs_file = fopen(filename, "rb"); + vpn = (FTL_CXT_SECTION_START + 1) * PAGES_PER_SUBLOCK + page_offset; for(int i = 0; i < partition_size / BYTES_PER_PAGE; i++) { uint8_t *page = malloc(BYTES_PER_PAGE); fread(page, BYTES_PER_PAGE, sizeof(uint8_t), hfs_file); VFLSpare *spare = (VFLSpare *)calloc(BYTES_PER_SPARE, sizeof(char)); spare->eccMarker = 0xff; - get_physical_address((FTL_CXT_SECTION_START + 1) * PAGES_PER_SUBLOCK + i + page_offset, &bank, &pbi, &pib); + get_physical_address(vpn, &bank, &pn); if(i == 0) { - printf("Writing HFS partition offset %d to virtual page %d (writing to bank %d, page %d)\n", i * BYTES_PER_PAGE, (FTL_CXT_SECTION_START + 1) * PAGES_PER_SUBLOCK + i + page_offset, bank, pbi * PAGES_PER_BLOCK + pib); + printf("Writing HFS partition to virtual page %d (writing to bank %d, page %d)\n", vpn, bank, pn); } - write_page(page, (uint8_t *)spare, bank, pbi * PAGES_PER_BLOCK + pib); + write_page(page, (uint8_t *)spare, bank, pn); + vpn++; } fclose(hfs_file); @@ -207,11 +209,11 @@ uint32_t write_hfs_partition(char *filename, uint32_t page_offset) { } void write_mbr(int boot_partition_size) { - uint32_t bank, pbi, pib; + uint32_t bank, pn; // write the MBR bytes (LBA 0) uint8_t *mbr_page = malloc(BYTES_PER_PAGE); - get_physical_address((FTL_CXT_SECTION_START + 1) * PAGES_PER_SUBLOCK, &bank, &pbi, &pib); + get_physical_address((FTL_CXT_SECTION_START + 1) * PAGES_PER_SUBLOCK, &bank, &pn); struct mbr_partition *boot_partition = (struct mbr_partition *)(mbr_page + MBR_ADDRESS); boot_partition->sysid = 0xEE; boot_partition->startlba = BOOT_PARTITION_FIRST_PAGE; @@ -228,8 +230,8 @@ void write_mbr(int boot_partition_size) { VFLSpare *spare = (VFLSpare *)calloc(BYTES_PER_SPARE, sizeof(char)); spare->eccMarker = 0xff; - printf("Writing MBR to page %d, bank %d\n", pbi * PAGES_PER_BLOCK + pib, bank); - write_page(mbr_page, (uint8_t *)spare, bank, pbi * PAGES_PER_BLOCK + pib); + printf("Writing MBR to page %d, bank %d\n", pn, bank); + write_page(mbr_page, (uint8_t *)spare, bank, pn); } void write_filesystem() { @@ -239,7 +241,7 @@ void write_filesystem() { //printf("Required pages for filesystem partition: %d\n", pages_for_filesystem_partition); // initialize the EFI header (LBA 1) - uint32_t bank, pbi, pib; + uint32_t bank, pn; uint8_t *gpt_header_page = malloc(BYTES_PER_PAGE); gpt_hdr *gpt_header = (gpt_hdr *)gpt_header_page; @@ -257,24 +259,9 @@ void write_filesystem() { gpt_entry_boot_partition->ent_lba_end = BOOT_PARTITION_FIRST_PAGE + pages_for_boot_partition; printf("Boot system partition located on page %lld - %lld\n", gpt_entry_boot_partition->ent_lba_start, gpt_entry_boot_partition->ent_lba_end); - get_physical_address((FTL_CXT_SECTION_START + 1) * PAGES_PER_SUBLOCK + 2, &bank, &pbi, &pib); - printf("Writing GUID boot partition entry to page %d, bank %d\n", pbi * PAGES_PER_BLOCK + pib, bank); - write_page(gpt_entry_boot_partition_page, (uint8_t *)spare, bank, pbi * PAGES_PER_BLOCK + pib); - - // // create the file system partition entry (LBA 3) - // uint8_t *gpt_entry_filesystem_partition_page = malloc(BYTES_PER_PAGE); - // gpt_ent *gpt_entry_filesystem_partition = (gpt_ent *)gpt_entry_filesystem_partition_page; - // gpt_entry_filesystem_partition->ent_type[0] = 0x48465300; - // gpt_entry_filesystem_partition->ent_type[1] = 0x11AA0000; - // gpt_entry_filesystem_partition->ent_type[2] = 0x300011AA; - // gpt_entry_filesystem_partition->ent_type[3] = 0xACEC4365; - // gpt_entry_filesystem_partition->ent_lba_start = BOOT_PARTITION_FIRST_PAGE + pages_for_boot_partition + 1; - // gpt_entry_filesystem_partition->ent_lba_end = gpt_entry_filesystem_partition->ent_lba_start + pages_for_filesystem_partition; - // printf("File system partition located on page %lld - %lld\n", gpt_entry_filesystem_partition->ent_lba_start, gpt_entry_filesystem_partition->ent_lba_end); - - // get_physical_address((FTL_CXT_SECTION_START + 1) * PAGES_PER_SUBLOCK + 3, &bank, &pbi, &pib); - // printf("Writing GUID filesystem partition entry to page %d, bank %d\n", pbi * PAGES_PER_BLOCK + pib, bank); - // write_page(gpt_entry_filesystem_partition_page, (uint8_t *)spare, bank, pbi * PAGES_PER_BLOCK + pib); + get_physical_address((FTL_CXT_SECTION_START + 1) * PAGES_PER_SUBLOCK + 2, &bank, &pn); + printf("Writing GUID boot partition entry to page %d, bank %d\n", pn, bank); + write_page(gpt_entry_boot_partition_page, (uint8_t *)spare, bank, pn); // finalize the GPT header // TODO add the secondary GPT entry! @@ -287,9 +274,9 @@ void write_filesystem() { gpt_header->hdr_crc_table = crc32(gpt_entry_boot_partition_page, sizeof(gpt_ent)); gpt_header->hdr_crc_self = crc32((uint8_t *)gpt_header, 0x5C); - get_physical_address((FTL_CXT_SECTION_START + 1) * PAGES_PER_SUBLOCK + 1, &bank, &pbi, &pib); - printf("Writing GUID header to page %d, bank %d\n", pbi * PAGES_PER_BLOCK + pib, bank); - write_page(gpt_header_page, (uint8_t *)spare, bank, pbi * PAGES_PER_BLOCK + pib); + get_physical_address((FTL_CXT_SECTION_START + 1) * PAGES_PER_SUBLOCK + 1, &bank, &pn); + printf("Writing GUID header to page %d, bank %d\n", pn, bank); + write_page(gpt_header_page, (uint8_t *)spare, bank, pn); // finally, write the MBR write_mbr(pages_for_boot_partition);