Deprecated: Return type of Requests_Cookie_Jar::offsetExists($key) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/francisfisher/francisfisher.me.uk/problem/wp-includes/Requests/Cookie/Jar.php on line 63

Deprecated: Return type of Requests_Cookie_Jar::offsetGet($key) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/francisfisher/francisfisher.me.uk/problem/wp-includes/Requests/Cookie/Jar.php on line 73

Deprecated: Return type of Requests_Cookie_Jar::offsetSet($key, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/francisfisher/francisfisher.me.uk/problem/wp-includes/Requests/Cookie/Jar.php on line 89

Deprecated: Return type of Requests_Cookie_Jar::offsetUnset($key) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/francisfisher/francisfisher.me.uk/problem/wp-includes/Requests/Cookie/Jar.php on line 102

Deprecated: Return type of Requests_Cookie_Jar::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/francisfisher/francisfisher.me.uk/problem/wp-includes/Requests/Cookie/Jar.php on line 111

Deprecated: Return type of Requests_Utility_CaseInsensitiveDictionary::offsetExists($key) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/francisfisher/francisfisher.me.uk/problem/wp-includes/Requests/Utility/CaseInsensitiveDictionary.php on line 40

Deprecated: Return type of Requests_Utility_CaseInsensitiveDictionary::offsetGet($key) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/francisfisher/francisfisher.me.uk/problem/wp-includes/Requests/Utility/CaseInsensitiveDictionary.php on line 51

Deprecated: Return type of Requests_Utility_CaseInsensitiveDictionary::offsetSet($key, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/francisfisher/francisfisher.me.uk/problem/wp-includes/Requests/Utility/CaseInsensitiveDictionary.php on line 68

Deprecated: Return type of Requests_Utility_CaseInsensitiveDictionary::offsetUnset($key) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/francisfisher/francisfisher.me.uk/problem/wp-includes/Requests/Utility/CaseInsensitiveDictionary.php on line 82

Deprecated: Return type of Requests_Utility_CaseInsensitiveDictionary::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/francisfisher/francisfisher.me.uk/problem/wp-includes/Requests/Utility/CaseInsensitiveDictionary.php on line 91

Warning: Cannot modify header information - headers already sent by (output started at /home/francisfisher/francisfisher.me.uk/problem/wp-includes/Requests/Cookie/Jar.php:15) in /home/francisfisher/francisfisher.me.uk/problem/wp-includes/rest-api/class-wp-rest-server.php on line 1758

Warning: Cannot modify header information - headers already sent by (output started at /home/francisfisher/francisfisher.me.uk/problem/wp-includes/Requests/Cookie/Jar.php:15) in /home/francisfisher/francisfisher.me.uk/problem/wp-includes/rest-api/class-wp-rest-server.php on line 1758

Warning: Cannot modify header information - headers already sent by (output started at /home/francisfisher/francisfisher.me.uk/problem/wp-includes/Requests/Cookie/Jar.php:15) in /home/francisfisher/francisfisher.me.uk/problem/wp-includes/rest-api/class-wp-rest-server.php on line 1758

Warning: Cannot modify header information - headers already sent by (output started at /home/francisfisher/francisfisher.me.uk/problem/wp-includes/Requests/Cookie/Jar.php:15) in /home/francisfisher/francisfisher.me.uk/problem/wp-includes/rest-api/class-wp-rest-server.php on line 1758

Warning: Cannot modify header information - headers already sent by (output started at /home/francisfisher/francisfisher.me.uk/problem/wp-includes/Requests/Cookie/Jar.php:15) in /home/francisfisher/francisfisher.me.uk/problem/wp-includes/rest-api/class-wp-rest-server.php on line 1758

Warning: Cannot modify header information - headers already sent by (output started at /home/francisfisher/francisfisher.me.uk/problem/wp-includes/Requests/Cookie/Jar.php:15) in /home/francisfisher/francisfisher.me.uk/problem/wp-includes/rest-api/class-wp-rest-server.php on line 1758

Warning: Cannot modify header information - headers already sent by (output started at /home/francisfisher/francisfisher.me.uk/problem/wp-includes/Requests/Cookie/Jar.php:15) in /home/francisfisher/francisfisher.me.uk/problem/wp-includes/rest-api/class-wp-rest-server.php on line 1758

Warning: Cannot modify header information - headers already sent by (output started at /home/francisfisher/francisfisher.me.uk/problem/wp-includes/Requests/Cookie/Jar.php:15) in /home/francisfisher/francisfisher.me.uk/problem/wp-includes/rest-api/class-wp-rest-server.php on line 1758
{"id":331,"date":"2014-10-28T18:29:07","date_gmt":"2014-10-28T18:29:07","guid":{"rendered":"http:\/\/francisfisher.me.uk\/problem\/?p=331"},"modified":"2023-01-15T11:53:39","modified_gmt":"2023-01-15T11:53:39","slug":"warning-about-large-hard-discs-gpt-and-gigabyte-motherboards-such-as-ga-p35-ds4","status":"publish","type":"post","link":"https:\/\/francisfisher.me.uk\/problem\/2014\/warning-about-large-hard-discs-gpt-and-gigabyte-motherboards-such-as-ga-p35-ds4\/","title":{"rendered":"Warning about large hard discs, GPT, and Gigabyte Motherboards such as GA-P35-DS4"},"content":{"rendered":"

Or, Gigabyte BIOS considered harmful<\/h1>\n

After changing\u00a0the motherboard, a computer became unbootable because the Gigabyte BIOS created a Host Protected Area (HPA) using sectors already allocated to a disc partition, corrupting the partition table and overwriting data.<\/p>\n

What Gigabyte are trying to do is store a copy of the BIOS onto disc in order to secure the computer against viruses. The process is explained over here<\/a> in the section titled \"GIGABYTE Xpress BIOS Rescue™ Technology\" (and is referred to in the specification of the motherboard as \"Virtual Dual BIOS\").\u00a0At boot time, a copy of the BIOS is stored into an\u00a0unused section of the disc by creating a Host Protected Area<\/a>. If a virus corrupts the BIOS then it can apparently detect this and restore the safe copy of the BIOS from the disc. Magical!<\/span><\/p>\n

This process goes badly wrong when you have discs larger than 2TB. The traditional partition table format, which dates back to the early 80s, runs into a limit when discs reach 2TB. A\u00a0new partition table format was created called GUID Partition Table<\/a>\u00a0(GPT)\u00a0which handles\u00a0much larger\u00a0discs.<\/p>\n

If you have certain\u00a0Gigabyte motherboards with the Virtual Dual BIOS feature, then\u00a0as the computer boots it will try and create an HPA on the first hard disc, and save the current BIOS there. One assumes that if the partition table indicates that the disc is already full, then the BIOS will avoid creating this HPA. What seems to be happening with large hard discs with GPT, is that\u00a0the BIOS doesn't understand the partition table,\u00a0doesn't realise that the all space on the disc is entirely accounted for already, then grabs some of the space\u00a0from the end of the disc and overwrites it with a copy of the BIOS.<\/p>\n

Once\u00a0the HPA has been created, the size of the disc that is reported to the OS changes. This means that the\u00a0values\u00a0stored in the GPT structures don't match those reported by the disc\u00a0so may make it impossible to boot from the disc - which is what happened to me.<\/p>\n

How do I tell if I have this problem?<\/h2>\n

You are likely to see this problem if you have a disc larger than 2TB that you partitioned with a GPT on a different motherboard then attached\u00a0to\u00a0the Gigabyte motherboard as\u00a0the first hard disc.<\/p>\n

For me, I had\u00a0a 1.5 TB disc with a \/boot partition and 2 3TB discs in raid-1 via Linux software raid (mdadm).\u00a0I had\u00a0partitioned\u00a0these discs on a different motherboard and the computer would boot without problems, however when I switched to the Gigabyte motherboard it would no longer boot. Specifically, I would receive a grub error like this:<\/p>\n

error: disk 'mduuid\/3c620ba3b6ebc2ba2dec4bdc61f7191b' not found.\r\nEntering rescue mode...\r\ngrub rescue><\/pre>\n

When I booted from a usb stick and attempted to mount the raid partition it was only able to load one of the discs:<\/p>\n

ubuntu@ubuntu:~$ sudo mdadm --assemble \/dev\/md0\r\nmdadm: \/dev\/md0 has been started with 1 drive (out of 2).\r\nubuntu@ubuntu:~$\r\n<\/pre>\n

I then ran gdisk to inspect each of the two discs forming the raid array, gdisk\u00a0printed various errors about the disc that the BIOS had interfered with:<\/p>\n

ubuntu@ubuntu:~$ sudo gdisk \/dev\/sdb\r\nGPT fdisk (gdisk) version 0.8.8\r\n\r\nWarning! Disk size is smaller than the main header indicates! Loading\r\nsecondary header from the last sector of the disk! You should use 'v' to\r\nverify disk integrity, and perhaps options on the experts' menu to repair\r\nthe disk.\r\nCaution: invalid backup GPT header, but valid main header; regenerating\r\nbackup header from main header.\r\n\r\nWarning! One or more CRCs don't match. You should repair the disk!\r\n\r\nPartition table scan:\r\n  MBR: protective\r\n  BSD: not present\r\n  APM: not present\r\n  GPT: damaged\r\n\r\n****************************************************************************\r\nCaution: Found protective or hybrid MBR and corrupt GPT. Using GPT, but disk\r\nverification and recovery are STRONGLY recommended.\r\n****************************************************************************\r\n\r\nCommand (? for help):\r\n<\/pre>\n

If one performs the recommended verification step, 5 errors are detected:<\/p>\n

Command (? for help): v\r\n\r\nCaution: The CRC for the backup partition table is invalid. This table may\r\nbe corrupt. This program will automatically create a new backup partition\r\ntable when you save your partitions.\r\n\r\nProblem: The secondary header's self-pointer indicates that it doesn't reside\r\nat the end of the disk. If you've added a disk to a RAID array, use the 'e'\r\noption on the experts' menu to adjust the secondary header's and partition\r\ntable's locations.\r\n\r\nProblem: Disk is too small to hold all the data!\r\n(Disk size is 5860531055 sectors, needs to be 5860533168 sectors.)\r\nThe 'e' option on the experts' menu may fix this problem.\r\n\r\nProblem: GPT claims the disk is larger than it is! (Claimed last usable\r\nsector is 5860533134, but backup header is at\r\n5860533167 and disk size is 5860531055 sectors.\r\nThe 'e' option on the experts' menu will probably fix this problem\r\n\r\nProblem: partition 2 is too big for the disk.\r\n\r\nIdentified 5 problems!\r\n\r\nCommand (? for help):\r\n<\/pre>\n

In fact there is only 1 error,\u00a0which is that part of the disc has been co-opted by the BIOS. This can be seen with hdparm (contrast sdb which has been corrupted with sdd which is in its original state):<\/p>\n

ubuntu@ubuntu:~$ sudo hdparm -N \/dev\/sdb\r\n\r\n\/dev\/sdb:\r\n max sectors   = 5860531055\/5860533168, HPA is enabled\r\nubuntu@ubuntu:~$ sudo hdparm -N \/dev\/sdd\r\n\r\n\/dev\/sdd:\r\n max sectors   = 5860533168\/5860533168, HPA is disabled\r\nubuntu@ubuntu:~$\r\n<\/pre>\n

 <\/p>\n

How do I fix the problem?<\/h2>\n

You must either live with the HPA, or remove it and ensure you never again boot with a the GPT disc as primary. Even if you decide to live with the HPA you will need to temporarily remove it so that you can backup your data or resize the partition and filesystem.<\/p>\n

So regardless of what you choose to deal with this problem, you will need to disable the HPA and make the entire disc available. This can be done with hdparm, by setting the visible sectors to the full amount with the parameter \"-N p<full amount of sectors>\" as below:<\/p>\n

ubuntu@ubuntu:~$ sudo hdparm -N \/dev\/sdb\r\n\r\n\/dev\/sdb:\r\n max sectors   = 5860531055\/5860533168, HPA is enabled\r\nubuntu@ubuntu:~$ sudo hdparm -N p5860533168 \/dev\/sdb\r\n\r\n\/dev\/sdb:\r\n setting max visible sectors to 5860533168 (permanent)\r\n max sectors   = 5860533168\/5860533168, HPA is disabled\r\nubuntu@ubuntu:~$\r\n<\/pre>\n

Now that this has been done, the GPT partition table will correspond to the number of sectors reported by the disc (although some data has been unavoidably lost when the BIOS overwrote the end of the disc). However if you reboot and this\u00a0disc is still the\u00a0primary disc then the BIOS will just create the HPA again!<\/p>\n","protected":false},"excerpt":{"rendered":"

Or, Gigabyte BIOS considered harmful After changing\u00a0the motherboard, a computer became unbootable because the Gigabyte BIOS created a Host Protected Area (HPA) using sectors already allocated to a disc partition, corrupting the partition table and overwriting data. What Gigabyte are trying to do is store a copy of the BIOS onto disc in order to […]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false},"categories":[3],"tags":[11,13],"_links":{"self":[{"href":"https:\/\/francisfisher.me.uk\/problem\/wp-json\/wp\/v2\/posts\/331"}],"collection":[{"href":"https:\/\/francisfisher.me.uk\/problem\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/francisfisher.me.uk\/problem\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/francisfisher.me.uk\/problem\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/francisfisher.me.uk\/problem\/wp-json\/wp\/v2\/comments?post=331"}],"version-history":[{"count":6,"href":"https:\/\/francisfisher.me.uk\/problem\/wp-json\/wp\/v2\/posts\/331\/revisions"}],"predecessor-version":[{"id":435,"href":"https:\/\/francisfisher.me.uk\/problem\/wp-json\/wp\/v2\/posts\/331\/revisions\/435"}],"wp:attachment":[{"href":"https:\/\/francisfisher.me.uk\/problem\/wp-json\/wp\/v2\/media?parent=331"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/francisfisher.me.uk\/problem\/wp-json\/wp\/v2\/categories?post=331"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/francisfisher.me.uk\/problem\/wp-json\/wp\/v2\/tags?post=331"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}