GRUB stage1.S 분석 중 도움 요청합니다~

freestyle의 이미지

     27     /* Absolute addresses
     28        This makes the assembler generate the address without support
     29        from the linker. (ELF can't relocate 16-bit addresses!) */
     30 #define ABS(x) (x-_start+0x7c00)
     31 
     32     /* Print message string */
     33 #define MSG(x)  movw $ABS(x), %si; call message
     34 
     35     /* XXX: binutils-2.9.1.0.x doesn't produce a short opcode for this. */
     36 #define MOV_MEM_TO_AL(x)    .byte 0xa0;  .word x
 
    ...
    ...
 
    160     /* check if LBA is supported */
    161     movb    $0x41, %ah
    162     movw    $0x55aa, %bx
    163     int $0x13
    164 
    165     /*
    166      *  %dl may have been clobbered by INT 13, AH=41H.
    167      *  This happens, for example, with AST BIOS 1.04.
    168      */
    169     popw    %dx
    170     pushw   %dx
    171 
    172     /* use CHS if fails */
    173     jc  chs_mode
    174     cmpw    $0xaa55, %bx
    175     jne chs_mode
    176 
    177     /* check if AH=0x42 is supported if FORCE_LBA is zero */
    178     MOV_MEM_TO_AL(ABS(force_lba))   /* movb ABS(force_lba), %al */
    179     testb   %al, %al
    180     jnz lba_mode
    181     andw    $1, %cx
    182     jz  chs_mode
    183 
    184 lba_mode:
    185     /* save the total number of sectors */
    186     movl    0x10(%si), %ecx
    187 
    188     /* set %si to the disk address packet */
    189     movw    $ABS(disk_address_packet), %si

==========================================================================

현재 178~182라인 분석 중 막혔습니다.

    178     MOV_MEM_TO_AL(ABS(force_lba))   /* movb ABS(force_lba), %al */
    179     testb   %al, %al
    180     jnz lba_mode
    181     andw    $1, %cx
    182     jz  chs_mode

178번 라인은
force_lba의 절대주소를 구해서 마지막 한 바이트를 AL 레지스터로 보내는 매크로입니다.
주석 달린 것도 그렇구요. 아마도 MBR의 값도 그렇고 0x00이 들어가는 것 같습니다.
(이것도 BIOS가 넣어주는 BPB의 하나로 알고 있습니다)

179번 라인은
%al이 0x00이므로 testb 결과 0이 나와서 zf(zero flag)가 set되는 것으로 알고 있습니다.

180번 라인은
jnz(jump not zero)이므로 위에서 zf가 set되어 무시되고 지나갈 것입니다.

181번 라인은
%cx가 161~163번째 라인으로 인해 1, 2, 4 마스크 중 하나의 값을 가질 것으로 예상됩니다.
이것을 1과 and 연산을 하므로, 2나 4 마스크가 들어있다면 연산결과가 0이 되어 zf가 set될 것입니다.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

INT 13h AH=41h: Check Extensions Present
Parameters:
 
Registers 
   AH 41h = function number for extensions check 
   DL drive index (e.g. 1st HDD = 80h) 
   BX 55AAh 
 
Results:
   CF Set On Not Present, Clear If Present 
   AH Error Code or Major Version Number 
   BX AA55h 
   CX Interface support bitmask:
 
1 - Device Access using the packet structure
2 - Drive Locking and Ejecting
4 - Enhanced Disk Drive Support (EDD)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

하지만 저는 이 cx값을 확인하는 방법을 모르겠네요.
182번 라인은
181번 라인의 결과에 의해 chs_mode로 갈지, 또는 lba_mode로 갈지 결정하는
라인입니다.

저는 lba_mode로 가야하는 것 아닌가 하는 생각을 하는데요,
제 생각이나 분석이 틀린 것인지 올바르게 하고 있는 것인지 궁금합니다.

조언 부탁드립니다.(꾸벅)

[참고] 현재 테스트 중인 시스템의 MBR입니다.
배포판은 2.6.23.8-34.fc7이고, 분석 중인 grub 소스는 0.97을 다운로드 했습니다.

[root@2KW stage1]# dd bs=512 count=1 if=/dev/sda | od -Ax -tx1z -v
1+0 records in
1+0 records out
000000 eb 48 90 d0 bc 00 7c fb 50 07 50 1f fc be 1b 7c  >.H....|.P.P....|<
000010 bf 1b 06 50 57 b9 e5 01 f3 a4 cb be be 07 b1 04  >...PW...........<
000020 38 2c 7c 09 75 15 83 c6 10 e2 f5 cd 18 8b 14 8b  >8,|.u...........<
000030 ee 83 c6 10 49 74 16 38 2c 74 f6 be 10 07 03 02  >....It.8,t......<
000040 80 00 00 80 dd 59 00 00 00 08 fa 90 90 f6 c2 80  >.....Y..........<
000050 75 02 b2 80 ea 59 7c 00 00 31 c0 8e d8 8e d0 bc  >u....Y|..1......<
000060 00 20 fb a0 40 7c 3c ff 74 02 88 c2 52 be 7f 7d  >. ..@|<.t...R..}<
000070 e8 34 01 f6 c2 80 74 54 b4 41 bb aa 55 cd 13 5a  >.4....tT.A..U..Z<
000080 52 72 49 81 fb 55 aa 75 43 a0 41 7c 84 c0 75 05  >RrI..U.uC.A|..u.<
000090 83 e1 01 74 37 66 8b 4c 10 be 05 7c c6 44 ff 01  >...t7f.L...|.D..<
0000a0 66 8b 1e 44 7c c7 04 10 00 c7 44 02 01 00 66 89  >f..D|.....D...f.<
0000b0 5c 08 c7 44 06 00 70 66 31 c0 89 44 04 66 89 44  >\..D..pf1..D.f.D<
0000c0 0c b4 42 cd 13 72 05 bb 00 70 eb 7d b4 08 cd 13  >..B..r...p.}....<
0000d0 73 0a f6 c2 80 0f 84 ea 00 e9 8d 00 be 05 7c c6  >s.............|.<
0000e0 44 ff 00 66 31 c0 88 f0 40 66 89 44 04 31 d2 88  >D..f1...@f.D.1..<
0000f0 ca c1 e2 02 88 e8 88 f4 40 89 44 08 31 c0 88 d0  >........@.D.1...<
000100 c0 e8 02 66 89 04 66 a1 44 7c 66 31 d2 66 f7 34  >...f..f.D|f1.f.4<
000110 88 54 0a 66 31 d2 66 f7 74 04 88 54 0b 89 44 0c  >.T.f1.f.t..T..D.<
000120 3b 44 08 7d 3c 8a 54 0d c0 e2 06 8a 4c 0a fe c1  >;D.}<.T.....L...<
000130 08 d1 8a 6c 0c 5a 8a 74 0b bb 00 70 8e c3 31 db  >...l.Z.t...p..1.<
512 bytes (512 B) copied, 8.4306e-05 s, 6.1 MB/s
000140 b8 01 02 cd 13 72 2a 8c c3 8e 06 48 7c 60 1e b9  >.....r*....H|`..<
000150 00 01 8e db 31 f6 31 ff fc f3 a5 1f 61 ff 26 42  >....1.1.....a.&B<
000160 7c be 85 7d e8 40 00 eb 0e be 8a 7d e8 38 00 eb  >|..}.@.....}.8..<
000170 06 be 94 7d e8 30 00 be 99 7d e8 2a 00 eb fe 47  >...}.0...}.*...G<
000180 52 55 42 20 00 47 65 6f 6d 00 48 61 72 64 20 44  >RUB .Geom.Hard D<
000190 69 73 6b 00 52 65 61 64 00 20 45 72 72 6f 72 00  >isk.Read. Error.<
0001a0 bb 01 00 b4 0e cd 10 ac 3c 00 75 f4 c3 00 00 00  >........<.u.....<
0001b0 00 00 00 00 00 00 00 00 44 ca 44 ca 00 00 80 01  >........D.D.....<
0001c0 01 00 83 fe 3f 0c 3f 00 00 00 8e 2f 03 00 00 00  >....?.?..../....<
0001d0 01 0d 8e fe ff ff cd 2f 03 00 29 10 c2 04 00 00  >......./..).....<
0001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  >................<
0001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa  >..............U.<
000200
grassman의 이미지

다만 최근 하드웨어의 경우 항상 LBA를 사용하겠죠.
INT 13h, AH=41h 서비스의 결과값은 아마 LSB가 1이 될 겁니다.
다만 일부 BIOS가 그걸 정확하게 설정하지 않는 경우가 있을 것이므로 force_lba라는
변수값을 두어 grub에서 강제 설정할 수 있게 해 둔 겁니다. (BPB와는 무관합니다)

지금은 BIOS 제조사가 그다지 많지 않지만 예전에는 다양한 BIOS가 존재했고
그 BIOS들의 구현방식도 제각각인지라 최소한의 예외 상황을 따지다 보니 저렇게
코드가 길어진겁니다. 그냥 현재의 하드웨어에 대해서만 고려했다면 저것보다는
짧게 끝날겁니다.

freestyle의 이미지

제가 아둔해서인지 grassman님의 답글을 보고도 아직 의문점이 남습니다.
특히

Quote:
INT 13h, AH=41h 서비스의 결과값은 아마 LSB가 1이 될 겁니다.

이 부분에서 어떤 결과값을 말씀하시는 건지 모르겠습니다.

제가 이해한 것이 맞는지 지도해 주세요..;
161~163 라인의 인터럽트 결과값으로 chs_mode로 들어갈지 말지 분석하는 내용이 있는데요,
다른 비교문들은 정상동작을 의미하는 값들이 와서 통과했다고 보고 cx만 놓고 봤을 때

Bit(s)   Description
0     Extended disk access functions (AH=42H, 43H, 44H, 47h and 48H) supported.                
1     Removable drive controller functions (AH=45H, 46H, 48H, 49H, and INT15/AH =52H) supported.
2     Enhanced disk drive (EDD) functions (AH=48H and AH=4EH) supported. Extended drive parameter table is valid.
3-15  Reserved (0)

이것에 따라 removable만 아니면 cx에는 0x01이 아닌 값이 들어가 있게 되고,

    181     andw    $1, %cx
    182     jz  chs_mode

zf가 SET되지 않으니 chs_mode로 점프하지 않고 다음 라인을 실행한다.

이 때 다음 라인은 lba_mode: 태그로 시작하는 부분이고
그래서 lba_mode로 안전하게 진입한다... 맞나요?

참, 그리고 추가 질문이요.
부팅과정에서 각 레지스터의 값을 보고 싶으면 어떻게 해야 하나요?
-----------------------
Go to the U-City

----------------------------------------------------------------------------------------
Don't Feed the Trolls!
----------------------------------------------------------------------------------------

grassman의 이미지

"INT 13h, AH=41h 서비스의 결과값은 아마 LSB가 1이 될 겁니다." 라고 한 것은
결과로 반환되는 cx의 값에서 Bit 0이 1로 설정된다는 뜻입니다.

Bit(s)   Description
0     Extended disk access functions (AH=42H, 43H, 44H, 47h and 48H) supported.                
1     Removable drive controller functions (AH=45H, 46H, 48H, 49H, and INT15/AH =52H) supported.
2     Enhanced disk drive (EDD) functions (AH=48H and AH=4EH) supported. Extended drive parameter table is valid.
3-15  Reserved (0)

위에서 0, 1, 2는 Bit 입니다. 즉, 위의 값은 각각 독립된 Bit에 설정한 값입니다. Removable 속성이 있다면 Bit 1이 1로 설정되고 이것은 Bit 0의 설정과는 무관한 값입니다.

andw $1, %cx 연산은 cx의 Bit 0이 1인지 검사하는 부분입니다. cx의 Bit 0이 1일 경우 아래에 있는 jz chs_mode는 동작하지 않게 됩니다. (and의 결과가 0이 될 경우에만 ZF가 설정됩니다)

부팅과정의 레지스터 값을 보려면 Virtual Box등의 에뮬레이터를 사용해도 되고 구 버전의 Softice를 사용할 수도 있습니다. 현재 상황에서 Softice는 구하기도 힘들고 설정하기에도 까다로우므로 Virtual Box 등의 디버깅 기능을 활용해 보는 것이 좋을 겁니다.

freestyle의 이미지

6시간 넘게 이 부분만 갖고 헤매다가
얼렁뚱땅 결론 내리고 도망치듯 빠져 나오려는데
올바른 분석결과를 제시해 주셔서 감사합니다. ^^

뭐 그 다다음 줄부터 또 헤매는 중이지만, 하나하나 알아갈 때마다
속도가 붙는 게 느껴집니다. 아주 쬐끔이지만 ;;

grassman님 다시 한 번 감사드립니다.
---------------------------------------
Go to the U-City

----------------------------------------------------------------------------------------
Don't Feed the Trolls!
----------------------------------------------------------------------------------------

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.