static int setup_openiboot() { arm_setup(); mmu_setup(); tasks_setup(); setup_devices(); LeaveCriticalSection(); clock_set_sdiv(0); aes_setup(); nor_setup(); images_setup(); nvram_setup(); lcd_setup(); framebuffer_setup(); audiohw_init(); camera_setup(); return 0; }
static int setup_openiboot() { arm_setup(); mmu_setup(); tasks_setup(); setup_devices(); LeaveCriticalSection(); #ifndef CONFIG_IPHONE_4 clock_set_sdiv(0); aes_setup(); nor_setup(); syscfg_setup(); images_setup(); nvram_setup(); lcd_setup(); framebuffer_setup(); audiohw_init(); #endif isMultitouchLoaded = 0; return 0; }
void images_duplicate_at(Image* image, uint32_t type, int index, int offset) { if(image == NULL) return; uint32_t totalLen = sizeof(Img2Header) + image->padded; uint8_t* buffer = (uint8_t*) malloc(totalLen); nor_read(buffer, image->offset, totalLen); Img2Header* header = (Img2Header*) buffer; header->imageType = type; if(index >= 0) header->index = index; calculateDataHash(buffer + sizeof(Img2Header), image->padded, header->dataHash); uint32_t checksum = 0; crc32(&checksum, buffer, 0x64); header->header_checksum = checksum; calculateHash(header, header->hash); nor_write(buffer, offset, totalLen); free(buffer); images_release(); images_setup(); }
void images_write(Image* image, void* data, unsigned int length, int encrypt) { bufferPrintf("images_write(%x, %x, %x)\r\n", image, data, length); if(image == NULL) return; mtd_t *dev = images_device(); if(!dev) return; mtd_prepare(dev); uint32_t padded = length; if((length & 0xF) != 0) { padded = (padded & ~0xF) + 0x10; } if(image->next != NULL && (image->offset + sizeof(Img2Header) + padded) >= image->next->offset) { bufferPrintf("**ABORTED** requested length greater than available space.\r\n"); return; } uint32_t totalLen = sizeof(Img2Header) + padded; uint8_t* writeBuffer = (uint8_t*) malloc(totalLen); mtd_read(dev, writeBuffer, image->offset, sizeof(Img2Header)); memcpy(writeBuffer + sizeof(Img2Header), data, length); if(encrypt) aes_838_encrypt(writeBuffer + sizeof(Img2Header), padded, NULL); Img2Header* header = (Img2Header*) writeBuffer; header->dataLen = length; header->dataLenPadded = padded; calculateDataHash(writeBuffer + sizeof(Img2Header), padded, header->dataHash); uint32_t checksum = 0; crc32(&checksum, writeBuffer, 0x64); header->header_checksum = checksum; calculateHash(header, header->hash); bufferPrintf("mtd_write(0x%p, %x, %x, %x)\r\n", dev, writeBuffer, image->offset, totalLen); mtd_write(dev, writeBuffer, image->offset, totalLen); bufferPrintf("mtd_write(0x%p, %x, %x, %x) done\r\n", dev, writeBuffer, image->offset, totalLen); free(writeBuffer); mtd_finish(dev); images_release(); images_setup(); }
void images_erase(Image* image) { if(image == NULL) return; nor_erase_sector(image->offset); images_release(); images_setup(); }
void platform_init() { arm_setup(); mmu_setup(); tasks_setup(); // Basic prerequisites for everything else miu_setup(); power_setup(); clock_setup(); // Need interrupts for everything afterwards interrupt_setup(); gpio_setup(); // For scheduling/sleeping niceties timer_setup(); event_setup(); wdt_setup(); // Other devices // uart_setup(); i2c_setup(); // dma_setup(); spi_setup(); LeaveCriticalSection(); aes_setup(); nor_setup(); syscfg_setup(); images_setup(); nvram_setup(); // lcd_setup(); framebuffer_hook(); // TODO: Remove once LCD implemented framebuffer_setup(); // audiohw_init(); framebuffer_setdisplaytext(TRUE); gpio_register_interrupt(BUTTONS_HOLD_IRQ, BUTTONS_HOLD_IRQTYPE, BUTTONS_HOLD_IRQLEVEL, BUTTONS_HOLD_IRQAUTOFLIP, gpio_test_handler, 0); gpio_interrupt_enable(BUTTONS_HOLD_IRQ); gpio_register_interrupt(BUTTONS_HOME_IRQ, BUTTONS_HOME_IRQTYPE, BUTTONS_HOME_IRQLEVEL, BUTTONS_HOME_IRQAUTOFLIP, gpio_test_handler, 1); gpio_interrupt_enable(BUTTONS_HOME_IRQ); gpio_register_interrupt(BUTTONS_VOLUP_IRQ, BUTTONS_VOLUP_IRQTYPE, BUTTONS_VOLUP_IRQLEVEL, BUTTONS_VOLUP_IRQAUTOFLIP, gpio_test_handler, 2); gpio_interrupt_enable(BUTTONS_VOLUP_IRQ); gpio_register_interrupt(BUTTONS_VOLDOWN_IRQ, BUTTONS_VOLDOWN_IRQTYPE, BUTTONS_VOLDOWN_IRQLEVEL, BUTTONS_VOLDOWN_IRQAUTOFLIP, gpio_test_handler, 3); gpio_interrupt_enable(BUTTONS_VOLDOWN_IRQ); }
static void nor_init() { if(!nor_device_init(&nor_device)) { mtd_register(&nor_device.mtd); #ifdef S5L8900 images_setup(); #endif nvram_setup(); syscfg_setup(); } }
void images_from_template(Image* image, uint32_t type, int index, void* dataBuffer, unsigned int len, int encrypt) { if(image == NULL) return; mtd_t *dev = images_device(); if(!dev) return; mtd_prepare(dev); uint32_t offset = MaxOffset + (SegmentSize - (MaxOffset % SegmentSize)); uint32_t padded = len; if((len & 0xF) != 0) { padded = (padded & ~0xF) + 0x10; } uint32_t totalLen = sizeof(Img2Header) + padded; uint8_t* buffer = (uint8_t*) malloc(totalLen); mtd_read(dev, buffer, image->offset, sizeof(Img2Header)); Img2Header* header = (Img2Header*) buffer; header->imageType = type; if(index >= 0) header->index = index; header->dataLen = len; header->dataLenPadded = padded; memcpy(buffer + sizeof(Img2Header), dataBuffer, len); if(encrypt) aes_838_encrypt(buffer + sizeof(Img2Header), padded, NULL); calculateDataHash(buffer + sizeof(Img2Header), image->padded, header->dataHash); uint32_t checksum = 0; crc32(&checksum, buffer, 0x64); header->header_checksum = checksum; calculateHash(header, header->hash); mtd_write(dev, buffer, offset, totalLen); free(buffer); mtd_finish(dev); images_release(); images_setup(); }
void images_append(void* data, int len) { if(MaxOffset >= 0xfc000 || (MaxOffset + len) >= 0xfc000) { bufferPrintf("writing image of size %d at %x would overflow NOR!\r\n", len, MaxOffset); } else { nor_write(data, MaxOffset, len); // Destroy any following image if((MaxOffset + len) < 0xfc000) { uint8_t zero = 0; nor_write(&zero, MaxOffset + len, 1); } images_release(); images_setup(); } }
void images_duplicate(Image* image, uint32_t type, int index) { if(image == NULL) return; mtd_t *dev = images_device(); if(!dev) return; mtd_prepare(dev); uint32_t offset = MaxOffset + (SegmentSize - (MaxOffset % SegmentSize)); uint32_t totalLen = sizeof(Img2Header) + image->padded; uint8_t* buffer = (uint8_t*) malloc(totalLen); mtd_read(dev, buffer, image->offset, totalLen); Img2Header* header = (Img2Header*) buffer; header->imageType = type; if(index >= 0) header->index = index; calculateDataHash(buffer + sizeof(Img2Header), image->padded, header->dataHash); uint32_t checksum = 0; crc32(&checksum, buffer, 0x64); header->header_checksum = checksum; calculateHash(header, header->hash); mtd_write(dev, buffer, offset, totalLen); free(buffer); mtd_finish(dev); images_release(); images_setup(); }
void images_append(void* data, int len) { mtd_t *dev = images_device(); if(!dev) return; mtd_prepare(dev); if(MaxOffset >= 0xfc000 || (MaxOffset + len) >= 0xfc000) { bufferPrintf("**ABORTED** Writing image of size %d at %x would overflow NOR!\r\n", len, MaxOffset); } else { mtd_write(dev, data, MaxOffset, len); // Destroy any following image if((MaxOffset + len) < 0xfc000) { uint8_t zero = 0; mtd_write(dev, &zero, MaxOffset + len, 1); } images_release(); images_setup(); } mtd_finish(dev); }
void images_uninstall(uint32_t _fourcc, uint32_t _unreplace) { ImageDataList* list = NULL; ImageDataList* cur = NULL; ImageDataList* oldImage = NULL; mtd_t *dev = images_device(); if(!dev) return; mtd_prepare(dev); Image* curImage = imageList; while(curImage != NULL) { if(curImage->type != _fourcc) { if(cur == NULL) { list = cur = malloc(sizeof(ImageDataList)); } else { cur->next = malloc(sizeof(ImageDataList)); cur = cur->next; } bufferPrintf("Reading: "); print_fourcc(curImage->type); bufferPrintf(" (%d bytes)\r\n", curImage->padded); cur->type = curImage->type; cur->next = NULL; cur->data = malloc(curImage->padded); mtd_read(dev, cur->data, curImage->offset, curImage->padded); if(_fourcc != _unreplace && cur->type == _unreplace) { oldImage = cur; } } else { bufferPrintf("Skipping: "); print_fourcc(curImage->type); bufferPrintf(" (%d bytes)\r\n", curImage->padded); } curImage = curImage->next; } mtd_finish(dev); if(_fourcc != _unreplace && oldImage == NULL) { bufferPrintf("No openiBoot installation was found.\n"); while(list != NULL) { cur = list; list = list->next; free(cur->data); free(cur); } return; } oldImage->type = _fourcc; images_change_type(oldImage->data, _fourcc); images_rewind(); while(list != NULL) { cur = list; list = list->next; AppleImg3RootHeader* header = (AppleImg3RootHeader*) cur->data; bufferPrintf("Flashing: "); print_fourcc(cur->type); bufferPrintf(" (%x, %d bytes)\r\n", cur->data, header->base.size); images_append(cur->data, header->base.size); free(cur->data); free(cur); } bufferPrintf("Images uninstalled.\r\n"); images_release(); images_setup(); bufferPrintf("Uninstall complete.\r\n"); }
void images_install(void* newData, size_t newDataLen, uint32_t newFourcc, uint32_t replaceFourcc) { ImageDataList* list = NULL; ImageDataList* cur = NULL; ImageDataList* toReplace = NULL; ImageDataList* verify = NULL; int isReplace = (replaceFourcc != newFourcc) ? TRUE : FALSE; int isUpgrade = FALSE; mtd_t *dev = images_device(); if(!dev) return; mtd_prepare(dev); Image* curImage = imageList; while(curImage != NULL) { if(cur == NULL) { list = cur = verify = malloc(sizeof(ImageDataList)); } else { cur->next = malloc(sizeof(ImageDataList)); cur = cur->next; } bufferPrintf("Reading: "); print_fourcc(curImage->type); bufferPrintf(" (%d bytes)\r\n", curImage->padded); cur->type = curImage->type; cur->next = NULL; cur->data = malloc(curImage->padded); mtd_read(dev, cur->data, curImage->offset, curImage->padded); if(isReplace && cur->type == replaceFourcc) { isUpgrade = TRUE; } else if(cur->type == newFourcc) { toReplace = cur; } curImage = curImage->next; } mtd_finish(dev); if(!isUpgrade) { bufferPrintf("Performing installation... (%d bytes)\r\n", newDataLen); ImageDataList* ibox = malloc(sizeof(ImageDataList)); ibox->type = replaceFourcc; ibox->data = toReplace->data; ibox->next = toReplace->next; toReplace->next = ibox; toReplace->data = images_inject_img3(toReplace->data, newData, newDataLen); images_change_type(ibox->data, ibox->type); } else { bufferPrintf("Performing upgrade... (%d bytes)\r\n", newDataLen); void* newIBoot = images_inject_img3(toReplace->data, newData, newDataLen); free(toReplace->data); toReplace->data = newIBoot; } //check for size and availability size_t newPaddedDataLen=0; size_t totalBytes=0; //if somebody can find how to get padded length for new ibot maybe this loop not needed while(verify != NULL) { cur = verify; verify = verify->next; AppleImg3RootHeader* header = (AppleImg3RootHeader*) cur->data; totalBytes += header->base.size; if(cur->type == newFourcc) { newPaddedDataLen = header->base.size; } } bufferPrintf("Total size to be written %d\r\n",totalBytes); if((ImagesStart + totalBytes) >= 0xfc000) { bufferPrintf("**ABORTED** Writing total image size: 0x%x, new ibot size: 0x%x at 0x%x would overflow NOR!\r\n", totalBytes, newPaddedDataLen,ImagesStart); images_rewind(); images_release(); images_setup(); return; } bufferPrintf("Flashing...\r\n"); images_rewind(); while(list != NULL) { cur = list; list = list->next; AppleImg3RootHeader* header = (AppleImg3RootHeader*) cur->data; bufferPrintf("Flashing: "); print_fourcc(cur->type); bufferPrintf(" (%x, %d bytes)\r\n", cur->data, header->base.size); images_append(cur->data, header->base.size); free(cur->data); free(cur); } bufferPrintf("Flashing Complete, Free space after flashing %d\r\n",0xfc000-MaxOffset); images_release(); images_setup(); //bufferPrintf("Configuring openiBoot settings...\r\n"); /*#ifndef CONFIG_S5L8720 //TODO: add this back in once FTL is up and running Volume* volume; io_func* io; io = bdev_open(0); volume = openVolume(io); char buffer [sizeof(XSTRINGIFY(OPENIBOOT_VERSION))]; strcpy(buffer, XSTRINGIFY(OPENIBOOT_VERSION)); add_hfs(volume, (uint8_t*)buffer, sizeof(buffer), "/openiboot"); closeVolume(volume); CLOSE(io); ftl_sync(); #endif*/ // TODO: This is broken now, move into menu.c for next release -- Ricky26 /* if(!nvram_getvar("opib-temp-os")) { nvram_setvar("opib-temp-os", "0"); } if(!nvram_getvar("opib-default-os")) { nvram_setvar("opib-default-os", "1"); } if(!nvram_getvar("opib-menu-timeout")) { nvram_setvar("opib-menu-timeout", "10000"); } nvram_save();*/ // TODO: The defaults should NOT be written to NVRAM. -- Ricky26 //bufferPrintf("openiBoot installation complete.\r\n"); }
void images_uninstall() { ImageDataList* list = NULL; ImageDataList* cur = NULL; ImageDataList* iboot = NULL; Image* curImage = imageList; bufferPrintf("Reading images...\r\n"); while(curImage != NULL) { if(curImage->type != fourcc("ibot")) { if(cur == NULL) { list = cur = malloc(sizeof(ImageDataList)); } else { cur->next = malloc(sizeof(ImageDataList)); cur = cur->next; } bufferPrintf("Reading: "); print_fourcc(curImage->type); bufferPrintf(" (%d bytes)\r\n", curImage->padded); cur->type = curImage->type; cur->next = NULL; cur->data = malloc(curImage->padded); nor_read(cur->data, curImage->offset, curImage->padded); if(cur->type == fourcc("ibox")) { iboot = cur; } } else { bufferPrintf("Skipping: "); print_fourcc(curImage->type); bufferPrintf(" (%d bytes)\r\n", curImage->padded); } curImage = curImage->next; } if(iboot == NULL) { bufferPrintf("openiboot does not seem to be installed\n"); while(list != NULL) { cur = list; list = list->next; free(cur->data); free(cur); } return; } iboot->type = fourcc("ibot"); images_change_type(iboot->data, fourcc("ibot")); bufferPrintf("Flashing...\r\n"); images_rewind(); while(list != NULL) { cur = list; list = list->next; AppleImg3RootHeader* header = (AppleImg3RootHeader*) cur->data; bufferPrintf("Flashing: "); print_fourcc(cur->type); bufferPrintf(" (%x, %d bytes)\r\n", cur->data, header->base.size); images_append(cur->data, header->base.size); free(cur->data); free(cur); } bufferPrintf("Done with uninstallation!\r\n"); images_release(); images_setup(); bufferPrintf("Refreshed image list\r\n"); }
void images_install(void* newData, size_t newDataLen) { ImageDataList* list = NULL; ImageDataList* cur = NULL; ImageDataList* iboot = NULL; int isUpgrade = FALSE; Image* curImage = imageList; bufferPrintf("Reading images...\r\n"); while(curImage != NULL) { if(cur == NULL) { list = cur = malloc(sizeof(ImageDataList)); } else { cur->next = malloc(sizeof(ImageDataList)); cur = cur->next; } bufferPrintf("Reading: "); print_fourcc(curImage->type); bufferPrintf(" (%d bytes)\r\n", curImage->padded); cur->type = curImage->type; cur->next = NULL; cur->data = malloc(curImage->padded); nor_read(cur->data, curImage->offset, curImage->padded); if(cur->type == fourcc("ibox")) { isUpgrade = TRUE; } else if(cur->type == fourcc("ibot")) { iboot = cur; } curImage = curImage->next; } if(!isUpgrade) { bufferPrintf("Performing installation... (%d bytes)\r\n", newDataLen); ImageDataList* ibox = malloc(sizeof(ImageDataList)); ibox->type = fourcc("ibox"); ibox->data = iboot->data; ibox->next = iboot->next; iboot->next = ibox; iboot->data = images_inject_img3(iboot->data, newData, newDataLen); images_change_type(ibox->data, ibox->type); } else { bufferPrintf("Performing upgrade... (%d bytes)\r\n", newDataLen); void* newIBoot = images_inject_img3(iboot->data, newData, newDataLen); free(iboot->data); iboot->data = newIBoot; } bufferPrintf("Flashing...\r\n"); images_rewind(); while(list != NULL) { cur = list; list = list->next; AppleImg3RootHeader* header = (AppleImg3RootHeader*) cur->data; bufferPrintf("Flashing: "); print_fourcc(cur->type); bufferPrintf(" (%x, %d bytes)\r\n", cur->data, header->base.size); images_append(cur->data, header->base.size); free(cur->data); free(cur); } bufferPrintf("Done with installation!\r\n"); images_release(); images_setup(); bufferPrintf("Refreshed image list\r\n"); }
void images_install(void* newData, size_t newDataLen, uint32_t newFourcc, uint32_t replaceFourcc) { ImageDataList* list = NULL; ImageDataList* cur = NULL; ImageDataList* toReplace = NULL; ImageDataList* verify = NULL; int isReplace = (replaceFourcc != newFourcc) ? TRUE : FALSE; int isUpgrade = FALSE; Image* curImage = imageList; while(curImage != NULL) { if(cur == NULL) { list = cur = verify = malloc(sizeof(ImageDataList)); } else { cur->next = malloc(sizeof(ImageDataList)); cur = cur->next; } bufferPrintf("Reading: "); print_fourcc(curImage->type); bufferPrintf(" (%d bytes)\r\n", curImage->padded); cur->type = curImage->type; cur->next = NULL; cur->data = malloc(curImage->padded); nor_read(cur->data, curImage->offset, curImage->padded); if(isReplace && cur->type == replaceFourcc) { isUpgrade = TRUE; } else if(cur->type == newFourcc) { toReplace = cur; } curImage = curImage->next; } if(!isUpgrade) { bufferPrintf("Performing installation... (%d bytes)\r\n", newDataLen); ImageDataList* ibox = malloc(sizeof(ImageDataList)); ibox->type = replaceFourcc; ibox->data = toReplace->data; ibox->next = toReplace->next; toReplace->next = ibox; toReplace->data = images_inject_img3(toReplace->data, newData, newDataLen); images_change_type(ibox->data, ibox->type); } else { bufferPrintf("Performing upgrade... (%d bytes)\r\n", newDataLen); void* newIBoot = images_inject_img3(toReplace->data, newData, newDataLen); free(toReplace->data); toReplace->data = newIBoot; } //check for size and availability size_t newPaddedDataLen=0; size_t totalBytes=0; //if somebody can find how to get padded length for new ibot maybe this loop not needed while(verify != NULL) { cur = verify; verify = verify->next; AppleImg3RootHeader* header = (AppleImg3RootHeader*) cur->data; totalBytes += header->base.size; if(cur->type == newFourcc) { newPaddedDataLen = header->base.size; } } bufferPrintf("Total size to be written %d\r\n",totalBytes); if((ImagesStart + totalBytes) >= 0xfc000) { bufferPrintf("**ABORTED** Writing total image size: 0x%x, new ibot size: 0x%x at 0x%x would overflow NOR!\r\n", totalBytes, newPaddedDataLen,ImagesStart); images_rewind(); images_release(); images_setup(); return; } bufferPrintf("Flashing...\r\n"); images_rewind(); while(list != NULL) { cur = list; list = list->next; AppleImg3RootHeader* header = (AppleImg3RootHeader*) cur->data; bufferPrintf("Flashing: "); print_fourcc(cur->type); bufferPrintf(" (%x, %d bytes)\r\n", cur->data, header->base.size); images_append(cur->data, header->base.size); free(cur->data); free(cur); } bufferPrintf("Flashing Complete, Free space after flashing %d\r\n",0xfc000-MaxOffset); images_release(); images_setup(); bufferPrintf("Configuring openiBoot settings...\r\n"); nvram_setvar("opib-version", "0.1.2"); if(!nvram_getvar("opib-temp-os")) { nvram_setvar("opib-temp-os", "0"); } if(!nvram_getvar("opib-default-os")) { nvram_setvar("opib-default-os", "0"); } if(!nvram_getvar("opib-menu-timeout")) { nvram_setvar("opib-menu-timeout", "10000"); } nvram_save(); bufferPrintf("openiBoot installation complete.\r\n"); }