{"id":1604,"date":"2015-08-08T14:39:45","date_gmt":"2015-08-08T20:39:45","guid":{"rendered":"http:\/\/dev.iachieved.it\/iachievedit\/?p=1604"},"modified":"2015-08-08T14:39:45","modified_gmt":"2015-08-08T20:39:45","slug":"exploring-img-files-on-linux","status":"publish","type":"post","link":"https:\/\/dev.iachieved.it\/iachievedit\/exploring-img-files-on-linux\/","title":{"rendered":"Exploring .img Files on Linux"},"content":{"rendered":"<p>Editor&#8217;s note:  This tutorial is written using Ubuntu Linux.  If you are on a different platform you may need to replace commands such as <code>apt-get<\/code> with your distributions equivalent.<\/p>\n<h2>What&#8217;s In Those .img Files?<\/h2>\n<p>Have you ever found yourself with an <code>.img<\/code> file blindly following the tutorial on &#8220;flashing&#8221; it onto an SD card?  Did you know you can create your own disk image files for distributions on thumb drives, SD cards, etc. with minimal effort?  This tutorial aims to show you how to:<\/p>\n<ul>\n<li>Discover the hidden secrets of a monolithic <code>.img<\/code> file\n<li>Mount the partitions in an <code>.img<\/code> file using <code>losetup<\/code>, <code>kpartx<\/code> and <code>mount<\/code>\n<li>Create your own <code>.img<\/code> files and use them as virtual disks\n<li>Write out your virtual disk image to a thumb drive (or any drive for that matter) for use later\n<\/ul>\n<p>Let&#8217;s take a look at the BeagleBone Black Debian distribution file.  You can download it with <a href=\"http:\/\/debian.beagleboard.org\/images\/bone-debian-7.8-lxde-4gb-armhf-2015-03-01-4gb.img.xz\">this link<\/a>.<\/p>\n<p>Once its downloaded you will want to uncompress it with <code>xz --decompress<\/code>:<\/p>\n<pre>\r\n$ xz --decompress bone-debian-7.8-lxde-4gb-armhf-2015-03-01-4gb.img.xz\r\n<\/pre>\n<p>If you don&#8217;t have <code>xz<\/code> installed you can obtain it through <code>apt-get install xz-utils<\/code>.<\/p>\n<p>Once the image is decompressed many tutorials would have you stop there and go straight to using <code>dd<\/code> to do a byte-by-byte copy onto an SD card, insert into the BeagleBone Black, and boot.  We want to examine it a bit further first.<\/p>\n<p>First, we&#8217;re going to attach the image file to what is known as a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Loop_device\">loopback device<\/a>.  The Wikipedia entry introduction is succinct:  &#8220;In Unix-like operating systems, a loop device is a pseudo-device that makes a file accessible as a block device.&#8221;  In short, a loop device allows us to present the image file to the operating system as if it were an actual &#8220;disk&#8221;.  To set up the loop device:<\/p>\n<pre>\r\n$ sudo losetup \/dev\/loop0 bone-debian-7.8-lxde-4gb-armhf-2015-03-01-4gb.img\r\n<\/pre>\n<p>We used <code>\/dev\/loop0<\/code> in this example.  <i>If<\/i> <code>\/dev\/loop0<\/code> wasn&#8217;t available to us (that is, it was already in use), we could have chosen <code>\/dev\/loop1<\/code>, etc.  To get a list of the loopback devices that are already in use, one can use <code>losetup -a<\/code>:<\/p>\n<pre>\r\n$ sudo losetup -a\r\n\/dev\/loop0: [0801]:10976989 (\/home\/user\/BBB\/bone-debian-7.8-lxde-4gb-armhf-2015-03-01-4gb.img)\r\n<\/pre>\n<p>Now <code>\/dev\/loop0<\/code> is attached.  What can we do?  How about look at the partition table with <code>fdisk<\/code>?<\/p>\n<pre>\r\n$ sudo fdisk -l \/dev\/loop0 \r\n\r\nDisk \/dev\/loop0: 3879 MB, 3879731200 bytes\r\n255 heads, 63 sectors\/track, 471 cylinders, total 7577600 sectors\r\nUnits = sectors of 1 * 512 = 512 bytes\r\nSector size (logical\/physical): 512 bytes \/ 512 bytes\r\nI\/O size (minimum\/optimal): 512 bytes \/ 512 bytes\r\nDisk identifier: 0x00000000\r\n\r\n      Device Boot      Start         End      Blocks   Id  System\r\n\/dev\/loop0p1   *        2048      198655       98304    e  W95 FAT16 (LBA)\r\n\/dev\/loop0p2          198656     7577599     3689472   83  Linux\r\n<\/pre>\n<p>Whoa!  From the output of <code>fdisk<\/code> we can infer a few things, namely that:<\/p>\n<ul>\n<li>There is a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Partition_table\">partition table<\/a> present\n<li>There are two partitions:  one with a FAT16 filesystem and another with a &#8220;Linux&#8221; filesystem\n<\/ul>\n<p>We want some more information about the filesystems on the partitions, so we&#8217;re going to utilize the utility <code>kpartx<\/code>, which according to the <code>man<\/code> page will <i>Create device maps from partition tables<\/i>.  If you don&#8217;t have <code>kpartx<\/code> on your system, it can be installed with <code>apt-get install kpartx<\/code>.<\/p>\n<p>To see what <code>kpartx<\/code> <i>would<\/i> map, run it with the <code>-l<\/code> option:<\/p>\n<pre>\r\n$ sudo kpartx -l \/dev\/loop0 \r\nloop0p1 : 0 196608 \/dev\/loop0 2048\r\nloop0p2 : 0 7378944 \/dev\/loop0 198656\r\n<\/pre>\n<p>Let&#8217;s go ahead and run it and add the maps:<\/p>\n<pre>\r\n$ sudo kpartx -a \/dev\/loop0 \r\n<\/pre>\n<p>Don&#8217;t go looking for <code>loop0p1<\/code> in <code>\/dev<\/code>, but rather you should look in <code>\/dev\/mapper<\/code>.  <code>kpartx<\/code> will assign the partitions it found and enumerate the partitions in <code>\/dev\/mapper<\/code> with the pattern <code>loop0p<b>X<\/b><\/code> where <b>X<\/b> is the partition number assigned.<\/p>\n<p>Now that the partitions are mapped, let&#8217;s examine the filesystems on each partition with <code>file<\/code> and the <code>--special-files<\/code> and <code>--dereference<\/code> options.<\/p>\n<pre>\r\n$ sudo  file -sL \/dev\/mapper\/loop0p1\r\n\/dev\/mapper\/loop0p1: x86 boot sector, mkdosfs boot message display, code offset 0x3c, OEM-ID \"mkfs.fat\", sectors\/cluster 4, root entries 512, Media descriptor 0xf8, sectors\/FAT 192, heads 255, sectors 196608 (volumes > 32 MB) , serial number 0xed080652, label: \"BEAGLEBONE \", FAT (16 bit)\r\n<\/pre>\n<p>From the <code>file<\/code> manpage:  Specifying the -s option causes file to also read argument files which are block or character special files. This is useful for determining the filesystem types of the data in raw disk partitions, which are block special files.<\/p>\n<p>Let&#8217;s look at the second partition, which the only thing we know thus far is that it is a &#8220;Linux filesystem&#8221;.<\/p>\n<pre>\r\nsudo file -sL \/dev\/mapper\/loop0p2\r\n\/dev\/mapper\/loop0p2: Linux rev 1.0 ext4 filesystem data, UUID=8e249d34-9f95-4aa2-928f-584551296f5e, volume name \"rootfs\" (extents) (large files) (huge files)\r\n<\/pre>\n<p>The second partition is clearly formatted with an  <code>ext4<\/code> filesystem.<\/p>\n<p>Now that we have our partitions mapped, we can mount them.  Create two directories to serve as mountpoints:<\/p>\n<pre>\r\n$ mkdir BEAGLEBONE # We will mount the FAT partition here\r\n$ mkdir rootfs     # We will mount the ext4 partition here\r\n<\/pre>\n<p>Once they are created, <code>mount<\/code> the filesystems.<\/p>\n<pre>\r\n$ sudo mount \/dev\/mapper\/loop0p1 BEAGLEBONE\r\n$ sudo mount \/dev\/mapper\/loop0p2 rootfs\r\n<\/pre>\n<p>It should be quite clear as to why we chose these commands to mount the filesystems.  Once they are mounted you can <code>cd<\/code> into them and look around, change things, etc.<\/p>\n<p>Once you are done and want to &#8220;let go&#8221; of the <code>.img<\/code> file, reverse the process with:<\/p>\n<pre>\r\n$ sudo umount BEAGLEBONE\r\n$ sudo umount rootfs\r\n$ sudo kpartx -d \/dev\/loop0\r\n$ sudo losetup -d \/dev\/loop0\r\n<\/pre>\n<h2>Creating Your Own .img Files<\/h2>\n<p>Creating your own <code>.img<\/code> files is quite easy.  Let&#8217;s say we want to distribute a 2G USB stick that is partitioned with two filesystems:  one an ext4 filesystem and the other a btrfs filesystem. On each we&#8217;ll store the latest (as of this writing) kernel source code:  linux-4.2-rc5.  <\/p>\n<p>First, we&#8217;ll use the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Dd_(Unix)\"><code>dd<\/code><\/a> utility and the <code>\/dev\/zero<\/code> device to create a monolithic 2G file.  We&#8217;ll use the SI definition for 2 gigabytes, which is 2000000000.  This command instructs <code>dd<\/code> to use <code>\/dev\/zero<\/code> as the input file and <code>linuxsource.img<\/code> as the output file.  <code>bs<\/code> is <i>block size<\/i> and <code>count<\/code> is the number of blocks to write.  We could have used a block size of 1 but <code>dd<\/code> is much slower (an inordinate number of minutes compared to 10 seconds with a blocksize of 1000).<\/p>\n<p><b>Warning:<\/b>  It is a time honored tradition to remind you to treat <code>dd<\/code> with respect, akin to issuing commands as <code>root<\/code>.  Misused or supplied the wrong arguments <code>dd<\/code> can seriously ruin your day.<\/p>\n<pre>\r\n$ sudo dd if=\/dev\/zero of=linuxsource.img bs=1000 count=2000000\r\n2000000+0 records in\r\n2000000+0 records out\r\n2000000000 bytes (2.0 GB) copied, 11.6933 s, 171 MB\/s\r\n<\/pre>\n<p>Now we have a raw file, 2G in length, full of zeroes.  What do we do with it?<\/p>\n<p>The answer is to present it to the OS as a loop device, and then use <code>fdisk<\/code> to create a partition table.  We effectively created a blank disk drive with nothing on it, so the first step is to put a partition table on the disk.<\/p>\n<pre>\r\n# Present the file as a loop device\r\n$ sudo losetup \/dev\/loop0 linuxsource.img\r\n<\/pre>\n<p>Now we use <code>fdisk<\/code>:<\/p>\n<pre>\r\n$ sudo fdisk \/dev\/loop0 \r\nDevice contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel\r\nBuilding a new DOS disklabel with disk identifier 0xed4eb569.\r\nChanges will remain in memory only, until you decide to write them.\r\nAfter that, of course, the previous content won't be recoverable.\r\n\r\nWarning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)\r\n\r\nCommand (m for help):\r\n<\/pre>\n<p>Surprise!  There&#8217;s no partition table on the &#8220;disk&#8221;.  We have to create one and create our partitions.  Type <code>n<\/code> at the Command prompt.  <code>n<\/code> is for <b>new<\/b> partition.<\/p>\n<pre>\r\nCommand (m for help): n\r\nPartition type:\r\n   p   primary (0 primary, 0 extended, 4 free)\r\n   e   extended\r\nSelect (default p): \r\n<\/pre>\n<p>Hit <code>ENTER<\/code> to accept the default of a <b>primary<\/b> partition.  Hit <code>ENTER<\/code> again to accept the default of <code>partition number 1<\/code>.  Hit <code>ENTER<\/code> again to accept the default of <b>2048<\/b> as the <b>first sector<\/b>.<\/p>\n<p>Now we will enter <b>+900M<\/b> as our &#8220;last sector&#8221;, which is actually applying a size of 900MB for the partition.  Here is what the full sequence looks like for creating our first partition:<\/p>\n<pre>\r\nCommand (m for help): n\r\nPartition type:\r\n   p   primary (0 primary, 0 extended, 4 free)\r\n   e   extended\r\nSelect (default p): \r\nUsing default response p\r\nPartition number (1-4, default 1): \r\nUsing default value 1\r\nFirst sector (2048-3906249, default 2048): \r\nUsing default value 2048\r\nLast sector, +sectors or +size{K,M,G} (2048-3906249, default 3906249): +900M\r\n\r\nCommand (m for help): \r\n<\/pre>\n<p>Let&#8217;s create a second partition while we are at it, but if you are curious, you can press <code>p<\/code> here to print out what the partition <i>will<\/i> look like when its written.<\/p>\n<pre>\r\nCommand (m for help): p\r\n\r\nDisk \/dev\/loop0: 2000 MB, 2000000000 bytes\r\n255 heads, 63 sectors\/track, 243 cylinders, total 3906250 sectors\r\nUnits = sectors of 1 * 512 = 512 bytes\r\nSector size (logical\/physical): 512 bytes \/ 512 bytes\r\nI\/O size (minimum\/optimal): 512 bytes \/ 512 bytes\r\nDisk identifier: 0xed4eb569\r\n\r\n      Device Boot      Start         End      Blocks   Id  System\r\n\/dev\/loop0p1            2048     1845247      921600   83  Linux\r\n<\/pre>\n<p>Create the second partition by issuing <code>n<\/code> and following the same steps.  Choose defaults for the <b>partition type<\/b>, <b>partition number<\/b>, <b>first sector<\/b>, and use <b>+990M<\/b> for the last sector.  To write out the partition table type <code>w<\/code>.<\/p>\n<pre>\r\nCommand (m for help): w\r\nThe partition table has been altered!\r\n\r\nCalling ioctl() to re-read partition table.\r\n\r\nWARNING: Re-reading the partition table failed with error 22: Invalid argument.\r\nThe kernel still uses the old table. The new table will be used at\r\nthe next reboot or after you run partprobe(8) or kpartx(8)\r\nSyncing disks.\r\n<\/pre>\n<p>Don&#8217;t ignore the warning here.  You&#8217;ve changed the partition table of a disk but the kernel is still referencing the old (i.e., non-existent) partition table.  Run <code>partprobe<\/code> and the kernel will reread all of its attached devices for the partition tables.  If you run <code>fdisk -l \/dev\/loop0<\/code> now, you won&#8217;t get a nasty comment about no partition table!<\/p>\n<pre>\r\n$ sudo fdisk -l \/dev\/loop0 \r\n\r\nDisk \/dev\/loop0: 2000 MB, 2000000000 bytes\r\n255 heads, 63 sectors\/track, 243 cylinders, total 3906250 sectors\r\nUnits = sectors of 1 * 512 = 512 bytes\r\nSector size (logical\/physical): 512 bytes \/ 512 bytes\r\nI\/O size (minimum\/optimal): 512 bytes \/ 512 bytes\r\nDisk identifier: 0xed4eb569\r\n\r\n      Device Boot      Start         End      Blocks   Id  System\r\n\/dev\/loop0p1            2048     1845247      921600   83  Linux\r\n\/dev\/loop0p2         1845248     3872767     1013760   83  Linux\r\n<\/pre>\n<p>Okay, we have our partition table written, but there are no actual filesystems present.  We will have to <i>make<\/i> them with <i>mkfs<\/i> (<b>m<\/b>a<b>k<\/b>e <b>f<\/b>ile<b>s<\/b>ystem) utilities.  Using <code>kpartx<\/code> once more we need to map the partitions.<\/p>\n<pre>\r\n$ sudo kpartx -a \/dev\/loop0 \r\n$ ls \/dev\/mapper\/loop0p*\r\n\/dev\/mapper\/loop0p1  \/dev\/mapper\/loop0p2\r\n<\/pre>\n<p>We&#8217;ll start with our first partition and create an <a href=\"https:\/\/en.wikipedia.org\/wiki\/Ext4\"><b>ext4<\/b><\/a> filesystem, followed by a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Btrfs\"><b>btrfs<\/b><\/a> filesystem on the second partition.<\/p>\n<pre>\r\n$ sudo mkfs.ext4 \/dev\/mapper\/loop0p1 \r\n$ sudo mkfs.btrfs \/dev\/mapper\/loop0p2\r\n<\/pre>\n<p><b>Note:<\/b>  If <code>mkfs.btrfs<\/code> is not available you can install it with <code>apt-get install btrfs-tools<\/code>.<\/p>\n<p>After these commands you should be able to use <code>file -SL<\/code> to examine the filesystems present.<\/p>\n<pre>\r\n$ sudo file -sL \/dev\/mapper\/loop0p1 \r\n\/dev\/mapper\/loop0p1: Linux rev 1.0 ext4 filesystem data, UUID=7ed2c156-dc38-4626-a10f-ed6fdb1c30b5 (extents) (large files) (huge files)\r\n$ sudo file -sL \/dev\/mapper\/loop0p2 \r\n\/dev\/mapper\/loop0p2: BTRFS Filesystem sectorsize 4096, nodesize 4096, leafsize 4096)\r\n<\/pre>\n<p>Now let&#8217;s mount our two filesystems:<\/p>\n<pre>\r\n$ sudo mkdir ext4\r\n$ sudo mkdir btrfs \r\n$ sudo mount \/dev\/mapper\/loop0p1 ext4\r\n$ sudo mount \/dev\/mapper\/loop0p2 btrfs\r\n<\/pre>\n<p>If you look in the <code>ext4<\/code> directory you should find a directory called <code>lost+found<\/code>.  This is a special directory present on <code>ext<\/code>-based filesystems where <code>fsck<\/code> puts recovered files.  You will not see this directory present in the <code>btrfs<\/code> directory.  <\/p>\n<p>We&#8217;re going to unpack the Linux source tree into both filesystems.  Download the source from <a href=\"https:\/\/www.kernel.org\">Kernel.org<\/a>.  We are using <a href=\"https:\/\/www.kernel.org\/pub\/linux\/kernel\/v4.x\/testing\/linux-4.2-rc5.tar.xz\">4.2 Release Candidate 5<\/a>.<\/p>\n<pre>\r\n$ cd ext4 # Go into our ext4 filesystem\r\n$ sudo tar -xJf ~\/Downloads\/linux-4.2-rc5.tar.xz\r\n$ cd ..\/btrfs # Go into our btrfs filesystem\r\n$ sudo tar -xJf ~\/Downloads\/linux-4.2-rc5.tar.xz \r\n<\/pre>\n<p>Using <code>df<\/code> in the respective directory you can see how much space was taken up.<\/p>\n<pre>\r\n$ cd ext4\r\n$ df -h .\r\nFilesystem           Size  Used Avail Use% Mounted on\r\n\/dev\/mapper\/loop0p1  870M  707M  103M  88% \/home\/user\/BBB\/ext4\r\n$ cd ..\/btrfs\/\r\n$ df -h .\r\nFilesystem           Size  Used Avail Use% Mounted on\r\n\/dev\/mapper\/loop0p2  990M  766M  101M  89% \/home\/user\/BBB\/btrfs\r\n<\/pre>\n<p>Now that the source has been exploded into the two filesystems, unmount the partitions.<\/p>\n<pre>\r\n$ sudo umount btrfs\/ ext4\/\r\n<\/pre>\n<p>Go ahead and instruct <code>kpartx<\/code> to unmap the partitions as well and remind yourself that <code>\/dev\/loop0<\/code> is still presenting our original image file.  You can release it as well.<\/p>\n<pre>\r\n$ kpartx -d \/dev\/loop0\r\n$ sudo losetup -a\r\n\/dev\/loop0: [0801]:10976993 (\/home\/user\/BBB\/linuxsource.img)\r\n$ sudo losetup -d \/dev\/loop0\r\n<\/pre>\n<h2>Writing Out the .img File<\/h2>\n<p>Now we come to writing the entire <code>linuxsource.img<\/code> out to a USB thumbdrive.  Once more we will be using <code>dd<\/code> and <b>once more we&#8217;ll warn you<\/b>:  ensure you are writing out to the USB device.  <b>Writing to the wrong device could render your system inoperable and destroy data!<\/b>.  I suggest watching <code>\/var\/log\/syslog<\/code> with <code>tail -f<\/code> to see where the USB drive was attached.  In this case it was attached to <code>\/dev\/sdh<\/code>.<\/p>\n<pre>\r\nAug  8 14:36:34 darthvader kernel: [70798.027860] scsi 19:0:0:0: Direct-Access     USB 2.0  USB Flash Drive  0.00 PQ: 0 ANSI: 2\r\nAug  8 14:36:34 darthvader kernel: [70798.028505] sd 19:0:0:0: Attached scsi generic sg8 type 0\r\nAug  8 14:36:34 darthvader kernel: [70798.030276] sd 19:0:0:0: [sdh] 3947016 512-byte logical blocks: (2.02 GB\/1.88 GiB)\r\n<\/pre>\n<p><b>Warning:<\/b>  Replace <code>\/dev\/sdX<\/code> below with the device <b>your system<\/b> mounted the USB drive.<\/p>\n<pre>\r\n$ sudo dd if=linuxsource.img of=\/dev\/sdX bs=1M\r\n1907+1 records in\r\n1907+1 records out\r\n2000000000 bytes (2.0 GB) copied, 234.545 s, 8.5 MB\/s\r\n<\/pre>\n<p><code>dd<\/code> will happily write out every byte in <code>linuxsource.img<\/code> onto the device presented at <code>\/dev\/sdh<\/code>.  Once it is done we&#8217;re going to have a USB stick with a partition table and two partitions.  Once the command completes run <code>fdisk -l \/dev\/sdX<\/code>, where <b>X<\/b> is where your system has the USB drive available. <\/p>\n<pre>\r\n$ sudo fdisk -l \/dev\/sdh\r\n\r\nDisk \/dev\/sdh: 2020 MB, 2020872192 bytes\r\n63 heads, 62 sectors\/track, 1010 cylinders, total 3947016 sectors\r\nUnits = sectors of 1 * 512 = 512 bytes\r\nSector size (logical\/physical): 512 bytes \/ 512 bytes\r\nI\/O size (minimum\/optimal): 512 bytes \/ 512 bytes\r\nDisk identifier: 0xed4eb569\r\n\r\n   Device Boot      Start         End      Blocks   Id  System\r\n\/dev\/sdh1            2048     1845247      921600   83  Linux\r\n\/dev\/sdh2         1845248     3872767     1013760   83  Linux\r\n<\/pre>\n<p>We can take a look at our partitions and see our filesystems are there!<\/p>\n<pre>\r\n$ sudo file -sL \/dev\/sdh1\r\n\/dev\/sdh1: Linux rev 1.0 ext4 filesystem data, UUID=7ed2c156-dc38-4626-a10f-ed6fdb1c30b5 (extents) (large files) (huge files)\r\n$ sudo file -sL \/dev\/sdh2 \r\n\/dev\/sdh2: BTRFS Filesystem sectorsize 4096, nodesize 4096, leafsize 4096)\r\n<\/pre>\n<p>Mount a partition and verify that our Linux kernel source is intact!<\/p>\n<h2>Closing Remarks<\/h2>\n<p>Linux provides a variety of powerful tools for creating and manipulating disk images and disks.  Although a little daunting at first the concepts of devices, partitions, and filesystems are quite simple to grasp.  Hopefully this tutorial was helpful in exploring how to leverage these tools to create your own disk images!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Editor&#8217;s note: This tutorial is written using Ubuntu Linux. If you are on a different platform you may need to replace commands such as apt-get with your distributions equivalent. What&#8217;s In Those .img Files? Have you ever found yourself with an .img file blindly following the tutorial on &#8220;flashing&#8221; it onto an SD card? Did [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[19],"tags":[],"class_list":["post-1604","post","type-post","status-publish","format-standard","hentry","category-linux"],"_links":{"self":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/1604"}],"collection":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/comments?post=1604"}],"version-history":[{"count":27,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/1604\/revisions"}],"predecessor-version":[{"id":1631,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/1604\/revisions\/1631"}],"wp:attachment":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/media?parent=1604"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/categories?post=1604"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/tags?post=1604"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}