@@ -185,6 +185,29 @@ static int gpt2mbr_type(uint64_t gpt_type1, uint64_t gpt_type2) {
185185 return -1 ;
186186}
187187
188+ static void lba2chs (uint8_t * chs , uint64_t lba ) {
189+ // If LBA is too big to express, use a standard value for CHS.
190+ if (lba > 63 * 255 * 1024 ) {
191+ goto lba_too_big ;
192+ }
193+
194+ uint64_t cylinder = lba / (255 * 63 );
195+ if (cylinder >= 1024 ) {
196+ lba_too_big :
197+ chs [0 ] = 0xfe ;
198+ chs [1 ] = 0xff ;
199+ chs [2 ] = 0xff ;
200+ return ;
201+ }
202+ uint64_t head = (lba / 63 ) % 255 ;
203+ uint64_t sector = (lba % 63 ) + 1 ;
204+
205+ chs [0 ] = head ;
206+ chs [1 ] = (cylinder >> 2 ) & 0xc0 ; // high 2 bits
207+ chs [1 ] |= sector & 0x3f ;
208+ chs [2 ] = cylinder ; // low 8 bits
209+ }
210+
188211static uint32_t crc32 (void * _stream , size_t len ) {
189212 uint8_t * stream = _stream ;
190213 uint32_t ret = 0xffffffff ;
@@ -761,6 +784,8 @@ static int bios_install(int argc, char *argv[]) {
761784 struct {
762785 uint64_t lba_start ;
763786 uint64_t lba_end ;
787+ uint8_t chs_start [3 ];
788+ uint8_t chs_end [3 ];
764789 uint8_t type ;
765790 } part_to_conv [4 ];
766791 size_t part_to_conv_i = 0 ;
@@ -784,13 +809,16 @@ static int bios_install(int argc, char *argv[]) {
784809 goto no_mbr_conv ;
785810 }
786811 part_to_conv [part_to_conv_i ].lba_start = ENDSWAP (gpt_entry .starting_lba );
812+ lba2chs (part_to_conv [part_to_conv_i ].chs_start , part_to_conv [part_to_conv_i ].lba_start );
813+
787814 if (ENDSWAP (gpt_entry .ending_lba ) > UINT32_MAX ) {
788815 if (!quiet ) {
789816 fprintf (stderr , "Ending LBA of partition %zu is greater than UINT32_MAX, will not convert GPT.\n" , i + 1 );
790817 }
791818 goto no_mbr_conv ;
792819 }
793820 part_to_conv [part_to_conv_i ].lba_end = ENDSWAP (gpt_entry .ending_lba );
821+ lba2chs (part_to_conv [part_to_conv_i ].chs_end , part_to_conv [part_to_conv_i ].lba_end );
794822
795823 int type = gpt2mbr_type (ENDSWAP (gpt_entry .partition_type_guid [0 ]),
796824 ENDSWAP (gpt_entry .partition_type_guid [1 ]));
@@ -849,6 +877,9 @@ static int bios_install(int argc, char *argv[]) {
849877 device_write (& lba_start , 0x1be + i * 16 + 0x08 , 4 );
850878 uint32_t sect_count = ENDSWAP ((part_to_conv [i ].lba_end - part_to_conv [i ].lba_start ) + 1 );
851879 device_write (& sect_count , 0x1be + i * 16 + 0x0c , 4 );
880+
881+ device_write (part_to_conv [i ].chs_start , 0x1be + i * 16 + 1 , 3 );
882+ device_write (part_to_conv [i ].chs_end , 0x1be + i * 16 + 5 , 3 );
852883 }
853884
854885 if (!quiet ) {
0 commit comments