Chameleon

Chameleon Commit Details

Date:2013-12-01 17:39:32 (5 years 7 months ago)
Author:Jief Luce
Commit:2270
Parents: 2269
Message:Only GPT + new signature
Changes:
M/branches/Jief/i386/boot0/boot0.s

File differences

branches/Jief/i386/boot0/boot0.s
5252
5353
5454
55
55
5656
5757
5858
5959
60
60
6161
6262
6363
......
7575
7676
7777
78
7879
7980
8081
......
164165
165166
166167
167
168
169
168
169
170
171
170172
171173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
172199
173200
174201
175202
176203
177
178
204
205
179206
180
207
181208
182209
183210
......
223250
224251
225252
226
253
254
227255
228
229
230
231
232
233256
234257
235258
......
250273
251274
252275
253
276
254277
255278
256279
257280
258281
259282
283
284
260285
261286
262287
......
269294
270295
271296
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390297
391298
392299
......
404311
405312
406313
314
407315
408316
409317
......
440348
441349
442350
443
351
352
353
354
444355
445
356
446357
447358
448359
......
456367
457368
458369
370
459371
460372
461373
462374
463375
464376
465
466377
467378
468
469
470
471
379
380
381
382
383
472384
473385
474386
475
476387
388
477389
478390
479391
......
486398
487399
488400
489
490
491401
492402
493403
......
502412
503413
504414
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531415
532
416
533417
534418
535
419
536420
537421
538
539422
540
541423
542424
543425
......
569451
570452
571453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
572470
573471
574472
......
604502
605503
606504
607
505
608506
609507
610508
......
632530
633531
634532
635
533
636534
637535
638536
......
658556
659557
660558
661
662
663
664
665
666
559
560
561
562
563
564
565
566
567
568
569
570
571
667572
668
669
670
671
672573
673
674
675
676574
677575
678576
......
762660
763661
764662
765
766
663
664
767665
768666
769667
770
668
771669
772670
773671
......
791689
792690
793691
794
692
693
795694
796695
797696
;
; Set to 1 to enable obscure debug messages.
;
DEBUGEQU CONFIG_BOOT0_DEBUG
DEBUGEQU 1
;
; Set to 1 to enable verbose mode
;
VERBOSEEQU CONFIG_BOOT0_VERBOSE
VERBOSEEQU 0
;
; Various constants.
kMBRPartTableEQU kMBRBuffer + kPartTableOffset
kSectorBytesEQU 512; sector size in bytes
kChameleonBoot1hSignatureEQU0xBB99; boot sector signature
kBootSignatureEQU 0xAA55; boot sector signature
kHFSPSignatureEQU 'H+'; HFS+ volume signature
kHFSPCaseSignatureEQU 'HX'; HFS+ volume case-sensitive signature
;
; Macros.
;
%macro DebugCharMacro 1
mov al, %1
call print_char
%macro PrintCharMacro 1
moval, %1
callprint_char
%endmacro
%macro PrintHexEaxMacro 0
callprint_hex
%endmacro
%macro PrintHexMacro 1
mov eax, %1
callprint_hex
%endmacro
;%macro xGetCharMacro 0
;callgetc
;%endmacro
%if DEBUG
%define PrintChar(x) PrintCharMacro x
%define PrintHex(x) PrintHexMacro x
%define PrintHexEax PrintHexEaxMacro
; %define xGetChar xGetCharMarco
%else
%define PrintChar(x)
%define PrintHex(x)
%define PrintHexEax
; %define xGetChar
%endif
%macro LogString 1
mov di, %1
call log_string
%endmacro
%if DEBUG
%define DebugChar(x) DebugCharMacro x
%if VERBOSE
%define LogString(x) LogStringMacro x
%else
%define DebugChar(x)
%define LogString(x)
%endif
;--------------------------------------------------------------------------
;
start_reloc:
DebugChar('>')
PrintChar('8')
PrintChar('>')
%if DEBUG
mov al, dl
call print_hex
%endif
;
; Since this code may not always reside in the MBR, always start by
; loading the MBR to kMBRBuffer and LBA1 to kGPTBuffer.
call find_boot; will not return on success
error:
LogString(boot_error_str)
; LogString(boot_error_str)
hang:
hlt
jmp hang
;--------------------------------------------------------------------------
; Find the active (boot) partition and load the booter from the partition.
;
;
find_boot:
;
; Check for boot block signature 0xAA55 following the 4 partition
; entries.
;
cmp WORD [si + part_size * kPartCount], kBootSignature
jne .exit ; boot signature not found.
xor bx, bx; BL will be set to 1 later in case of
; Protective MBR has been found
inc bh; BH = 1. Giving a chance for a second pass
; to boot an inactive but boot1h aware HFS+ partition
; by scanning the MBR partition entries again.
.start_scan:
mov cx, kPartCount ; number of partition entries per table
.loop:
;
; First scan through the partition table looking for the active
; partition.
;
%if DEBUG
mov al, [si + part.type] ; print partition type
call print_hex
%endif
mov eax, [si + part.lba]; save starting LBA of current
mov [my_lba], eax; MBR partition entry for read_lba function
cmp BYTE [si + part.type], 0; unused partition?
je .continue ; skip to next entry
cmp BYTE [si + part.type], kPartTypePMBR; check for Protective MBR
jne .testPass
mov BYTE [si + part.bootid], kPartInactive; found Protective MBR
; clear active flag to make sure this protective
; partition won't be used as a bootable partition.
mov bl, 1; Assume we can deal with GPT but try to scan
; later if not found any other bootable partitions.
.testPass:
cmp bh, 1
jne .Pass2
.Pass1:
cmp BYTE [si + part.bootid], kPartActive; In pass 1 we are walking on the standard path
; by trying to hop on the active partition.
jne .continue
xor dh, dh ; Argument for loadBootSector to skip HFS+ partition
; signature check.
jmp .tryToBoot
.Pass2:
cmp BYTE [si + part.type], kPartTypeHFS; In pass 2 we're going to find a HFS+ partition
; equipped with boot1h in its boot record
; regardless if it's active or not.
jne .continue
mov dh, 1 ; Argument for loadBootSector to check HFS+ partition signature.
DebugChar('*')
;
; Found boot partition, read boot sector to memory.
;
.tryToBoot:
call loadBootSector
jne .continue
jmp SHORT initBootLoader
.continue:
add si, BYTE part_size ; advance SI to next partition entry
loop .loop ; loop through all partition entries
;
; Scanned all partitions but not found any with active flag enabled
; Anyway if we found a protective MBR before we still have a chance
; for a possible GPT Header at LBA 1
;
dec bl
jnz .switchPass2; didn't find Protective MBR before
call checkGPT
.switchPass2:
;
; Switching to Pass 2
; try to find a boot1h aware HFS+ MBR partition
;
dec bh
mov si, kMBRPartTable; set SI to first entry of MBR Partition table
jz .start_scan; scan again
.exit:
ret; Giving up.
;
; Jump to partition booter. The drive number is already in register DL.
; SI is pointing to the modified partition entry.
;
initBootLoader:
DebugChar('J')
%if VERBOSE
LogString(done_str)
%endif
jmp kBoot0LoadAddr
;
; Found Protective MBR Partition Type: 0xEE
; Check for 'EFI PART' string at the beginning
; of LBA1 for possible GPT Table Header
;
checkGPT:
push bx
mov [my_lba], eax; save starting LBA for read_lba function
mov cx, [si + gpth.NumberOfPartitionEntries]; number of GUID Partition Array entries
mov bx, [si + gpth.SizeOfPartitionEntry]; size of GUID Partition Array entry
push bx; push size of GUID Partition entry
;
%if VERBOSE
LogString(gpt_str)
%endif
PrintChar('P')
mov dh, 1 ; partition number to give to boot1h
.gpt_loop:
;PrintChar('1')
mov eax, [si + gpta.PartitionTypeGUID + kGUIDLastDwordOffs]
cmpeax, kAppleGUID; check current GUID Partition for Apple's GUID type
jne.gpt_continue
.gpt_ok:
;PrintChar('2')
;
; Found HFS Partition
;
mov eax, [si + gpta.StartingLBA]; load boot sector from StartingLBA
mov [my_lba], eax
movdh, 1; Argument for loadBootSector to check HFS+ partition signature.
call loadBootSector
jne .gpt_continue; no boot loader signature
mov si, kMBRPartTable; fake the current GUID Partition
mov [si + part.lba], eax; as MBR style partition for boot1h
mov BYTE [si + part.type], kPartTypeHFS; with HFS+ filesystem type (0xAF)
%if VERBOSE
;LogString(test_str)
%endif
PrintChar('!')
mov ecx, [si + gpta.StartingLBA]
jmp SHORT initBootLoader
.gpt_continue:
add si, bx; advance SI to next partition entry
inc dh
loop .gpt_loop; loop through all partition entries
.exit:
;
; Arguments:
; DL = drive number (0x80 + unit number)
; DH = 0 skip HFS+ partition signature checking
; 1 enable HFS+ partition signature checking
; [my_lba] = starting LBA.
;
; Returns:
call load
jc error
ordh, dh
jz.checkBootSignature
.checkHFSSignature:
%if VERBOSE
LogString(test_str)
%endif
;
; Looking for HFSPlus ('H+') or HFSPlus case-sensitive ('HX') signature.
;
movax, [kBoot0LoadAddr + 2 * kSectorBytes]
cmp ax, kHFSPSignature; 'H+'
je.checkBootSignature
cmpax, kHFSPCaseSignature; 'HX'
je.checkBootSignature
;
; Looking for boot1f32 magic string.
;
movax, [kBoot0LoadAddr + kFAT32BootCodeOffset]
cmpax, kBoot1FAT32Magic
jne .exit
.checkBootSignature:
;
; Check for boot block signature 0xAA55
; Check for chameleon boot block signature of boot1h
;
mov di, bx
cmp WORD [di + kSectorBytes - 2], kBootSignature
cmp WORD [di + kSectorBytes - 4], kChameleonBoot1hSignature
.exit:
popa
ret
ret
initBootLoader:
LogString(done_str)
PrintChar('J')
;mov eax,kBoot0LoadAddr
;call print_hex
;mov eax,[kBoot0LoadAddr]
;call print_hex
;push si
;pop eax
;PrintHexEax
;PrintHex(edx)
jmp kBoot0LoadAddr
;--------------------------------------------------------------------------
; read_lba - Read sectors from a partition using LBA addressing.
;
; It pushes 2 bytes with a smaller opcode than if WORD was used
push BYTE 16 ; offset 0-1, packet size
DebugChar('<')
PrintChar('<')
%if DEBUG
mov eax, ecx
call print_hex
jnc .exit
DebugChar('R') ; indicate INT13/F42 error
; PrintChar('R') ; indicate INT13/F42 error
;
; Issue a disk reset on error.
; Clobber list:
; DI
;
log_string:
pusha
pushdi
movsi, log_title_str
callprint_string
;log_string:
; pusha
;
; pushdi
; movsi, log_title_str
; callprint_string
;
; popsi
; callprint_string
;
; popa
;
; ret
popsi
callprint_string
popa
ret
;--------------------------------------------------------------------------
; Write a string to the console.
;
;--------------------------------------------------------------------------
; NULL terminated strings.
;
log_title_strdb 10, 13, 'boot0: ', 0
boot_error_str db 'error', 0
;log_title_strdb 10, 13, 'boot0: ', 0
;boot_error_str db 'err', 0
%if VERBOSE
gpt_strdb 'GPT', 0
test_strdb 'test', 0
;test_strdb 'test', 0
done_strdb 'done', 0
%endif
times 440-($-$$) db 0
pad_table_and_sig:
times 510-($-$$) db 0
times 508-($-$$) db 0
dw kChameleonBoot1hSignature
dw kBootSignature

Archive Download the corresponding diff file

Revision: 2270