diff options
Diffstat (limited to 'ftl_format.c')
-rw-r--r-- | ftl_format.c | 512 |
1 files changed, 256 insertions, 256 deletions
diff --git a/ftl_format.c b/ftl_format.c index 8739fab..c35e18b 100644 --- a/ftl_format.c +++ b/ftl_format.c @@ -4,36 +4,36 @@ */ /*====================================================================== - Utility to create an FTL partition in a memory region + Utility to create an FTL partition in a memory region - ftl_format.c 1.13 1999/10/25 20:01:35 + ftl_format.c 1.13 1999/10/25 20:01:35 - The contents of this file are subject to the Mozilla Public - License Version 1.1 (the "License"); you may not use this file - except in compliance with the License. You may obtain a copy of - the License at http://www.mozilla.org/MPL/ + The contents of this file are subject to the Mozilla Public + License Version 1.1 (the "License"); you may not use this file + except in compliance with the License. You may obtain a copy of + the License at http://www.mozilla.org/MPL/ - Software distributed under the License is distributed on an "AS - IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - implied. See the License for the specific language governing - rights and limitations under the License. + Software distributed under the License is distributed on an "AS + IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + implied. See the License for the specific language governing + rights and limitations under the License. - The initial developer of the original code is David A. Hinds - <dhinds@pcmcia.sourceforge.org>. Portions created by David A. Hinds - are Copyright (C) 1999 David A. Hinds. All Rights Reserved. + The initial developer of the original code is David A. Hinds + <dhinds@pcmcia.sourceforge.org>. Portions created by David A. Hinds + are Copyright (C) 1999 David A. Hinds. All Rights Reserved. - Alternatively, the contents of this file may be used under the - terms of the GNU Public License version 2 (the "GPL"), in which - case the provisions of the GPL are applicable instead of the - above. If you wish to allow the use of your version of this file - only under the terms of the GPL and not to allow others to use - your version of this file under the MPL, indicate your decision - by deleting the provisions above and replace them with the notice - and other provisions required by the GPL. If you do not delete - the provisions above, a recipient may use your version of this - file under either the MPL or the GPL. + Alternatively, the contents of this file may be used under the + terms of the GNU Public License version 2 (the "GPL"), in which + case the provisions of the GPL are applicable instead of the + above. If you wish to allow the use of your version of this file + only under the terms of the GPL and not to allow others to use + your version of this file under the MPL, indicate your decision + by deleting the provisions above and replace them with the notice + and other provisions required by the GPL. If you do not delete + the provisions above, a recipient may use your version of this + file under either the MPL or the GPL. -======================================================================*/ + ======================================================================*/ #include <sys/types.h> #include <stdio.h> @@ -70,274 +70,274 @@ static void print_size(u_int s) { - if ((s > 0x100000) && ((s % 0x100000) == 0)) - printf("%d mb", s / 0x100000); - else if ((s > 0x400) && ((s % 0x400) == 0)) - printf("%d kb", s / 0x400); - else - printf("%d bytes", s); + if ((s > 0x100000) && ((s % 0x100000) == 0)) + printf("%d mb", s / 0x100000); + else if ((s > 0x400) && ((s % 0x400) == 0)) + printf("%d kb", s / 0x400); + else + printf("%d bytes", s); } /*====================================================================*/ static const char LinkTarget[] = { - 0x13, 0x03, 'C', 'I', 'S' + 0x13, 0x03, 'C', 'I', 'S' }; static const char DataOrg[] = { - 0x46, 0x39, 0x00, 'F', 'T', 'L', '1', '0', '0', 0x00 + 0x46, 0x39, 0x00, 'F', 'T', 'L', '1', '0', '0', 0x00 }; static void build_header(erase_unit_header_t *hdr, u_int RegionSize, - u_int BlockSize, u_int Spare, int Reserve, - u_int BootSize) + u_int BlockSize, u_int Spare, int Reserve, + u_int BootSize) { - u_int i, BootUnits, nbam, __FormattedSize; - - /* Default everything to the erased state */ - memset(hdr, 0xff, sizeof(*hdr)); - memcpy(hdr->LinkTargetTuple, LinkTarget, 5); - memcpy(hdr->DataOrgTuple, DataOrg, 10); - hdr->EndTuple[0] = hdr->EndTuple[1] = 0xff; - BootSize = (BootSize + (BlockSize-1)) & ~(BlockSize-1); - BootUnits = BootSize / BlockSize; - - /* We only support 512-byte blocks */ - hdr->BlockSize = 9; - hdr->EraseUnitSize = 0; - for (i = BlockSize; i > 1; i >>= 1) - hdr->EraseUnitSize++; - hdr->EraseCount = TO_LE32(0); - hdr->FirstPhysicalEUN = TO_LE16(BootUnits); - hdr->NumEraseUnits = TO_LE16((RegionSize - BootSize) >> hdr->EraseUnitSize); - hdr->NumTransferUnits = Spare; - __FormattedSize = RegionSize - ((Spare + BootUnits) << hdr->EraseUnitSize); - /* Leave a little bit of space between the CIS and BAM */ - hdr->BAMOffset = TO_LE32(0x80); - /* Adjust size to account for BAM space */ - nbam = ((1 << (hdr->EraseUnitSize - hdr->BlockSize)) * sizeof(u_int) - + FROM_LE32(hdr->BAMOffset) + (1 << hdr->BlockSize) - 1) >> hdr->BlockSize; - - __FormattedSize -= - (FROM_LE16(hdr->NumEraseUnits) - Spare) * (nbam << hdr->BlockSize); - __FormattedSize -= ((__FormattedSize * Reserve / 100) & ~0xfff); - - hdr->FormattedSize = TO_LE32(__FormattedSize); - - /* hdr->FirstVMAddress defaults to erased state */ - hdr->NumVMPages = TO_LE16(0); - hdr->Flags = 0; - /* hdr->Code defaults to erased state */ - hdr->SerialNumber = TO_LE32(time(NULL)); - /* hdr->AltEUHOffset defaults to erased state */ + u_int i, BootUnits, nbam, __FormattedSize; + + /* Default everything to the erased state */ + memset(hdr, 0xff, sizeof(*hdr)); + memcpy(hdr->LinkTargetTuple, LinkTarget, 5); + memcpy(hdr->DataOrgTuple, DataOrg, 10); + hdr->EndTuple[0] = hdr->EndTuple[1] = 0xff; + BootSize = (BootSize + (BlockSize-1)) & ~(BlockSize-1); + BootUnits = BootSize / BlockSize; + + /* We only support 512-byte blocks */ + hdr->BlockSize = 9; + hdr->EraseUnitSize = 0; + for (i = BlockSize; i > 1; i >>= 1) + hdr->EraseUnitSize++; + hdr->EraseCount = TO_LE32(0); + hdr->FirstPhysicalEUN = TO_LE16(BootUnits); + hdr->NumEraseUnits = TO_LE16((RegionSize - BootSize) >> hdr->EraseUnitSize); + hdr->NumTransferUnits = Spare; + __FormattedSize = RegionSize - ((Spare + BootUnits) << hdr->EraseUnitSize); + /* Leave a little bit of space between the CIS and BAM */ + hdr->BAMOffset = TO_LE32(0x80); + /* Adjust size to account for BAM space */ + nbam = ((1 << (hdr->EraseUnitSize - hdr->BlockSize)) * sizeof(u_int) + + FROM_LE32(hdr->BAMOffset) + (1 << hdr->BlockSize) - 1) >> hdr->BlockSize; + + __FormattedSize -= + (FROM_LE16(hdr->NumEraseUnits) - Spare) * (nbam << hdr->BlockSize); + __FormattedSize -= ((__FormattedSize * Reserve / 100) & ~0xfff); + + hdr->FormattedSize = TO_LE32(__FormattedSize); + + /* hdr->FirstVMAddress defaults to erased state */ + hdr->NumVMPages = TO_LE16(0); + hdr->Flags = 0; + /* hdr->Code defaults to erased state */ + hdr->SerialNumber = TO_LE32(time(NULL)); + /* hdr->AltEUHOffset defaults to erased state */ } /* build_header */ /*====================================================================*/ static int format_partition(int fd, int quiet, int interrogate, - u_int spare, int reserve, u_int bootsize) + u_int spare, int reserve, u_int bootsize) { - mtd_info_t mtd; - erase_info_t erase; - erase_unit_header_t hdr; - u_int step, lun, i, nbam, *bam; - - /* Get partition size, block size */ - if (ioctl(fd, MEMGETINFO, &mtd) != 0) { - perror("get info failed"); - return -1; - } + mtd_info_t mtd; + erase_info_t erase; + erase_unit_header_t hdr; + u_int step, lun, i, nbam, *bam; + + /* Get partition size, block size */ + if (ioctl(fd, MEMGETINFO, &mtd) != 0) { + perror("get info failed"); + return -1; + } #if 0 - /* Intel Series 100 Flash: skip first block */ - if ((region.JedecMfr == 0x89) && (region.JedecInfo == 0xaa) && - (bootsize == 0)) { - if (!quiet) - printf("Skipping first block to protect CIS info...\n"); - bootsize = 1; - } + /* Intel Series 100 Flash: skip first block */ + if ((region.JedecMfr == 0x89) && (region.JedecInfo == 0xaa) && + (bootsize == 0)) { + if (!quiet) + printf("Skipping first block to protect CIS info...\n"); + bootsize = 1; + } #endif - /* Create header */ - build_header(&hdr, mtd.size, mtd.erasesize, - spare, reserve, bootsize); - - if (!quiet) { - printf("Partition size = "); - print_size(mtd.size); - printf(", erase unit size = "); - print_size(mtd.erasesize); - printf(", %d transfer units\n", spare); - if (bootsize != 0) { - print_size(FROM_LE16(hdr.FirstPhysicalEUN) << hdr.EraseUnitSize); - printf(" allocated for boot image\n"); - } - printf("Reserved %d%%, formatted size = ", reserve); - print_size(FROM_LE32(hdr.FormattedSize)); - printf("\n"); - fflush(stdout); - } - - if (interrogate) { - char str[3]; - printf("This will destroy all data on the target device. " - "Confirm (y/n): "); - if (fgets(str, 3, stdin) == NULL) - return -1; - if ((strcmp(str, "y\n") != 0) && (strcmp(str, "Y\n") != 0)) - return -1; - } - - /* Create basic block allocation table for control blocks */ - nbam = ((mtd.erasesize >> hdr.BlockSize) * sizeof(u_int) - + FROM_LE32(hdr.BAMOffset) + (1 << hdr.BlockSize) - 1) >> hdr.BlockSize; - bam = malloc(nbam * sizeof(u_int)); - for (i = 0; i < nbam; i++) - bam[i] = TO_LE32(BLOCK_CONTROL); - - /* Erase partition */ - if (!quiet) { - printf("Erasing all blocks...\n"); - fflush(stdout); - } - erase.length = mtd.erasesize; - erase.start = mtd.erasesize * FROM_LE16(hdr.FirstPhysicalEUN); - for (i = 0; i < FROM_LE16(hdr.NumEraseUnits); i++) { - if (ioctl(fd, MEMERASE, &erase) < 0) { - if (!quiet) { - putchar('\n'); - fflush(stdout); - } - perror("block erase failed"); - return -1; - } - erase.start += erase.length; + /* Create header */ + build_header(&hdr, mtd.size, mtd.erasesize, + spare, reserve, bootsize); + if (!quiet) { - if (mtd.size <= 0x800000) { - if (erase.start % 0x100000) { - if (!(erase.start % 0x20000)) putchar('-'); + printf("Partition size = "); + print_size(mtd.size); + printf(", erase unit size = "); + print_size(mtd.erasesize); + printf(", %d transfer units\n", spare); + if (bootsize != 0) { + print_size(FROM_LE16(hdr.FirstPhysicalEUN) << hdr.EraseUnitSize); + printf(" allocated for boot image\n"); } - else putchar('+'); - } - else { - if (erase.start % 0x800000) { - if (!(erase.start % 0x100000)) putchar('+'); - } - else putchar('*'); - } - fflush(stdout); + printf("Reserved %d%%, formatted size = ", reserve); + print_size(FROM_LE32(hdr.FormattedSize)); + printf("\n"); + fflush(stdout); } - } - if (!quiet) putchar('\n'); - - /* Prepare erase units */ - if (!quiet) { - printf("Writing erase unit headers...\n"); - fflush(stdout); - } - lun = 0; - /* Distribute transfer units over the entire region */ - step = (spare) ? (FROM_LE16(hdr.NumEraseUnits)/spare) : (FROM_LE16(hdr.NumEraseUnits)+1); - for (i = 0; i < FROM_LE16(hdr.NumEraseUnits); i++) { - u_int ofs = (i + FROM_LE16(hdr.FirstPhysicalEUN)) << hdr.EraseUnitSize; - if (lseek(fd, ofs, SEEK_SET) == -1) { - perror("seek failed"); - break; + + if (interrogate) { + char str[3]; + printf("This will destroy all data on the target device. " + "Confirm (y/n): "); + if (fgets(str, 3, stdin) == NULL) + return -1; + if ((strcmp(str, "y\n") != 0) && (strcmp(str, "Y\n") != 0)) + return -1; } - /* Is this a transfer unit? */ - if (((i+1) % step) == 0) - hdr.LogicalEUN = TO_LE16(0xffff); - else { - hdr.LogicalEUN = TO_LE16(lun); - lun++; + + /* Create basic block allocation table for control blocks */ + nbam = ((mtd.erasesize >> hdr.BlockSize) * sizeof(u_int) + + FROM_LE32(hdr.BAMOffset) + (1 << hdr.BlockSize) - 1) >> hdr.BlockSize; + bam = malloc(nbam * sizeof(u_int)); + for (i = 0; i < nbam; i++) + bam[i] = TO_LE32(BLOCK_CONTROL); + + /* Erase partition */ + if (!quiet) { + printf("Erasing all blocks...\n"); + fflush(stdout); } - if (write(fd, &hdr, sizeof(hdr)) == -1) { - perror("write failed"); - break; + erase.length = mtd.erasesize; + erase.start = mtd.erasesize * FROM_LE16(hdr.FirstPhysicalEUN); + for (i = 0; i < FROM_LE16(hdr.NumEraseUnits); i++) { + if (ioctl(fd, MEMERASE, &erase) < 0) { + if (!quiet) { + putchar('\n'); + fflush(stdout); + } + perror("block erase failed"); + return -1; + } + erase.start += erase.length; + if (!quiet) { + if (mtd.size <= 0x800000) { + if (erase.start % 0x100000) { + if (!(erase.start % 0x20000)) putchar('-'); + } + else putchar('+'); + } + else { + if (erase.start % 0x800000) { + if (!(erase.start % 0x100000)) putchar('+'); + } + else putchar('*'); + } + fflush(stdout); + } } - if (lseek(fd, ofs + FROM_LE32(hdr.BAMOffset), SEEK_SET) == -1) { - perror("seek failed"); - break; + if (!quiet) putchar('\n'); + + /* Prepare erase units */ + if (!quiet) { + printf("Writing erase unit headers...\n"); + fflush(stdout); } - if (write(fd, bam, nbam * sizeof(u_int)) == -1) { - perror("write failed"); - break; + lun = 0; + /* Distribute transfer units over the entire region */ + step = (spare) ? (FROM_LE16(hdr.NumEraseUnits)/spare) : (FROM_LE16(hdr.NumEraseUnits)+1); + for (i = 0; i < FROM_LE16(hdr.NumEraseUnits); i++) { + u_int ofs = (i + FROM_LE16(hdr.FirstPhysicalEUN)) << hdr.EraseUnitSize; + if (lseek(fd, ofs, SEEK_SET) == -1) { + perror("seek failed"); + break; + } + /* Is this a transfer unit? */ + if (((i+1) % step) == 0) + hdr.LogicalEUN = TO_LE16(0xffff); + else { + hdr.LogicalEUN = TO_LE16(lun); + lun++; + } + if (write(fd, &hdr, sizeof(hdr)) == -1) { + perror("write failed"); + break; + } + if (lseek(fd, ofs + FROM_LE32(hdr.BAMOffset), SEEK_SET) == -1) { + perror("seek failed"); + break; + } + if (write(fd, bam, nbam * sizeof(u_int)) == -1) { + perror("write failed"); + break; + } } - } - if (i < FROM_LE16(hdr.NumEraseUnits)) - return -1; - else - return 0; + if (i < FROM_LE16(hdr.NumEraseUnits)) + return -1; + else + return 0; } /* format_partition */ /*====================================================================*/ int main(int argc, char *argv[]) { - int quiet, interrogate, reserve; - int optch, errflg, fd, ret; - u_int spare, bootsize; - char *s; - extern char *optarg; - struct stat buf; - - quiet = 0; - interrogate = 0; - spare = 1; - reserve = 5; - errflg = 0; - bootsize = 0; - - while ((optch = getopt(argc, argv, "qir:s:b:")) != -1) { - switch (optch) { - case 'q': - quiet = 1; break; - case 'i': - interrogate = 1; break; - case 's': - spare = strtoul(optarg, NULL, 0); break; - case 'r': - reserve = strtoul(optarg, NULL, 0); break; - case 'b': - bootsize = strtoul(optarg, &s, 0); - if ((*s == 'k') || (*s == 'K')) - bootsize *= 1024; - break; - default: - errflg = 1; break; + int quiet, interrogate, reserve; + int optch, errflg, fd, ret; + u_int spare, bootsize; + char *s; + extern char *optarg; + struct stat buf; + + quiet = 0; + interrogate = 0; + spare = 1; + reserve = 5; + errflg = 0; + bootsize = 0; + + while ((optch = getopt(argc, argv, "qir:s:b:")) != -1) { + switch (optch) { + case 'q': + quiet = 1; break; + case 'i': + interrogate = 1; break; + case 's': + spare = strtoul(optarg, NULL, 0); break; + case 'r': + reserve = strtoul(optarg, NULL, 0); break; + case 'b': + bootsize = strtoul(optarg, &s, 0); + if ((*s == 'k') || (*s == 'K')) + bootsize *= 1024; + break; + default: + errflg = 1; break; + } + } + if (errflg || (optind != argc-1)) { + fprintf(stderr, "usage: %s [-q] [-i] [-s spare-blocks]" + " [-r reserve-percent] [-b bootsize] device\n", argv[0]); + exit(EXIT_FAILURE); + } + + if (stat(argv[optind], &buf) != 0) { + perror("status check failed"); + exit(EXIT_FAILURE); + } + if (!(buf.st_mode & S_IFCHR)) { + fprintf(stderr, "%s is not a character special device\n", + argv[optind]); + exit(EXIT_FAILURE); + } + fd = open(argv[optind], O_RDWR); + if (fd == -1) { + perror("open failed"); + exit(EXIT_FAILURE); } - } - if (errflg || (optind != argc-1)) { - fprintf(stderr, "usage: %s [-q] [-i] [-s spare-blocks]" - " [-r reserve-percent] [-b bootsize] device\n", argv[0]); - exit(EXIT_FAILURE); - } - - if (stat(argv[optind], &buf) != 0) { - perror("status check failed"); - exit(EXIT_FAILURE); - } - if (!(buf.st_mode & S_IFCHR)) { - fprintf(stderr, "%s is not a character special device\n", - argv[optind]); - exit(EXIT_FAILURE); - } - fd = open(argv[optind], O_RDWR); - if (fd == -1) { - perror("open failed"); - exit(EXIT_FAILURE); - } - - ret = format_partition(fd, quiet, interrogate, spare, reserve, - bootsize); - if (!quiet) { - if (ret) - printf("format failed.\n"); - else - printf("format successful.\n"); - } - close(fd); - exit((ret) ? EXIT_FAILURE : EXIT_SUCCESS); - return 0; + ret = format_partition(fd, quiet, interrogate, spare, reserve, + bootsize); + if (!quiet) { + if (ret) + printf("format failed.\n"); + else + printf("format successful.\n"); + } + close(fd); + + exit((ret) ? EXIT_FAILURE : EXIT_SUCCESS); + return 0; } |