static int grub_mmc_check_permissions(const char *path, int *allow) { int ret; ext4_file f; struct ext4_inode_ref ref; // open file ret = ext4_fopen(&f, path, "rb"); if(ret != EOK){ dprintf(CRITICAL, "ext4_fopen ERROR = %d\n", ret); return -1; } // get inode ref ret = ext4_fs_get_inode_ref(&f.mp->fs, f.inode, &ref); if(ret != EOK){ dprintf(CRITICAL, "ext4_fs_get_inode_ref ERROR = %d\n", ret); goto err_close_file; } // check permissions if(ref.inode->uid==0 && ref.inode->gid==0 && ALLOW_BOOT(ref.inode->mode)) *allow = 1; else *allow = 0; if(*allow==0) { ref.inode->mode |= S_IXUGO; dprintf(CRITICAL, "file %s has wrong permissions!\n", path); } ext4_fclose(&f); return 0; err_close_file: ext4_fclose(&f); return -1; }
static int grub_load_from_mmc(void) { ext4_file f; uint32_t bytes_read; int ret = 0, allow = 0; dprintf(INFO, "%s: part=[%s] path=[%s]\n", __func__, GRUB_BOOT_PARTITION, GRUB_PATH); // create ext4 device struct ext4_blockdev* mmcdev = ext4_mmcdev_get(GRUB_BOOT_PARTITION); if(!mmcdev){ dprintf(CRITICAL, "MMC device ERROR\n"); return -1; } // register it ret = ext4_device_register(mmcdev, 0, GRUB_BOOT_PARTITION); if(ret != EOK){ dprintf(CRITICAL, "ext4_device_register ERROR = %d\n", ret); return ret; } // mount it ret = ext4_mount(GRUB_BOOT_PARTITION, GRUB_MOUNTPOINT); if(ret != EOK){ dprintf(CRITICAL, "ext4_mount ERROR = %d\n", ret); return -1; } // check permissions of crucial files if(grub_mmc_check_permissions(GRUB_MOUNTPOINT GRUB_PATH "/core.img", &allow)==EOK && !allow) return -1; if(grub_mmc_check_permissions(GRUB_MOUNTPOINT GRUB_PATH "/grub.cfg", &allow)==EOK && !allow) return -1; if(grub_mmc_check_permissions(GRUB_MOUNTPOINT GRUB_PATH "/grubenv", &allow)==EOK && !allow) return -1; dprintf(INFO, "Permissions are good\n"); // open file ret = ext4_fopen(&f, GRUB_MOUNTPOINT GRUB_PATH "/core.img", "rb"); if(ret != EOK){ dprintf(CRITICAL, "ext4_fopen ERROR = %d\n", ret); return -1; } // read file ret = ext4_fread(&f, (void*)GRUB_LOADING_ADDRESS_VIRT, ext4_fsize(&f), &bytes_read); if(ret != EOK){ dprintf(CRITICAL, "ext4_fread ERROR = %d\n", ret); return -1; } // close file ret = ext4_fclose(&f); if(ret != EOK){ dprintf(CRITICAL, "ext4_fclose ERROR = %d\n", ret); return -1; } // unmount partition ret = ext4_umount(GRUB_MOUNTPOINT); if(ret != EOK){ dprintf(CRITICAL, "ext4_umount ERROR = %d\n", ret); return -1; } // store bootdev unsigned int index = (unsigned int) partition_get_index(GRUB_BOOT_PARTITION); char buf[20]; sprintf(buf, "hd0,%u", index+1); grub_bootdev = strdup(buf); grub_bootpath = strdup(GRUB_BOOT_PATH_PREFIX "boot/grub"); dprintf(INFO, "Loaded GRUB from MMC\n"); return 0; }
bool test_lwext4_file_test(uint8_t *rw_buff, uint32_t rw_size, uint32_t rw_count) { int r; size_t size; uint32_t i; long int start; long int stop; long int diff; uint32_t kbps; uint64_t size_bytes; ext4_file f; printf("file_test:\n"); printf(" rw size: %" PRIu32 "\n", rw_size); printf(" rw count: %" PRIu32 "\n", rw_count); /*Add hello world file.*/ r = ext4_fopen(&f, "/mp/hello.txt", "wb"); r = ext4_fwrite(&f, "Hello World !\n", strlen("Hello World !\n"), 0); r = ext4_fclose(&f); io_timings_clear(); start = get_ms(); r = ext4_fopen(&f, "/mp/test1", "wb"); if (r != EOK) { printf("ext4_fopen ERROR = %d\n", r); return false; } printf("ext4_write: %" PRIu32 " * %" PRIu32 " ...\n", rw_size, rw_count); for (i = 0; i < rw_count; ++i) { memset(rw_buff, i % 10 + '0', rw_size); r = ext4_fwrite(&f, rw_buff, rw_size, &size); if ((r != EOK) || (size != rw_size)) break; } if (i != rw_count) { printf(" file_test: rw_count = %" PRIu32 "\n", i); return false; } stop = get_ms(); diff = stop - start; size_bytes = rw_size * rw_count; size_bytes = (size_bytes * 1000) / 1024; kbps = (size_bytes) / (diff + 1); printf(" write time: %d ms\n", (int)diff); printf(" write speed: %" PRIu32 " KB/s\n", kbps); printf_io_timings(diff); r = ext4_fclose(&f); io_timings_clear(); start = get_ms(); r = ext4_fopen(&f, "/mp/test1", "r+"); if (r != EOK) { printf("ext4_fopen ERROR = %d\n", r); return false; } printf("ext4_read: %" PRIu32 " * %" PRIu32 " ...\n", rw_size, rw_count); for (i = 0; i < rw_count; ++i) { r = ext4_fread(&f, rw_buff, rw_size, &size); if ((r != EOK) || (size != rw_size)) break; if (verify_buf(rw_buff, rw_size, i % 10 + '0')) break; } if (i != rw_count) { printf(" file_test: rw_count = %" PRIu32 "\n", i); return false; } stop = get_ms(); diff = stop - start; size_bytes = rw_size * rw_count; size_bytes = (size_bytes * 1000) / 1024; kbps = (size_bytes) / (diff + 1); printf(" read time: %d ms\n", (int)diff); printf(" read speed: %d KB/s\n", (int)kbps); printf_io_timings(diff); r = ext4_fclose(&f); return true; }