2011-03-06 2 views
24

간단한 부트 로더 작동 방식을 이해하는 데 어려움이 있습니다. 제가 이야기하고있는 부트 로더는 MITs 코스 "Operating Systems Engineering"에서 나온 것입니다.부트 로더 - 프로세서를 보호 모드로 전환

첫째, 내가 당신에게 BIOS가 실행 어셈블리 코드의 조각을 보여주지 : 그것의 모습에서

[f000:fec3] 0xffec3: lidtw %cs:0x7908 
[f000:fec9] 0xffec9: lgdtw %cs:0x7948 
[f000:fecf] 0xffecf: mov %cr0,%eax 
[f000:fed2] 0xffed2: or  $0x1,%eax 
[f000:fed6] 0xffed6: mov %eax,%cr0 
[f000:fed9] 0xffed9: ljmpl $0x8,$0xffee1 

을,이 코드는 인터럽트 테이블과 디스크립터 테이블을 설정하고 보호 모드를 켭니다 .

  1. 왜 BIOS에서 보호 모드 으로 들어가나요? 리얼 모드에서하지 부트 로더 실행해야 (BTW - 은 왜 실제 모드에서 실행해야합니까?)
  2. 를 내가 검색하지만 어디 를 찾을 수 없습니다 정확히 어떻게 ljmpl 명령이 작품과 차이점은 it와 ljmp 사이에서 그리고 정규 jmp-I 은 누군가가 을 올바른 방향으로 가리키면 감사하게 생각합니다.
  3. 왜 우리는 점프를 수행합니까? 이 지침의 목적은 입니까? ... 하지만 우리는 보호 모드로 그 BIOS 스위치를 보았다 - 그것은 프로세서가 리얼 모드에 있음을 말한다

    # Switch from real to protected mode, using a bootstrap GDT 
    # and segment translation that makes virtual addresses 
    # identical to their physical addresses, so that the 
    # effective memory map does not change during the switch. 
    lgdt gdtdesc 
    movl %cr0, %eax 
    orl  $CR0_PE_ON, %eax 
    movl %eax, %cr0 
    
    # Jump to next instruction, but in 32-bit code segment. 
    # Switches processor into 32-bit mode. 
    ljmp $PROT_MODE_CSEG, $protcseg 
    
    1. -

    부트 로더 코드로 이동 혼란 스럽네요.이게 어떻게 가능합니까? ?

  4. 어떻게 32 비트 모드로 전환합니까? 무엇 lgmp 명령 때문에 3235 모드로 마침내 가서 프로세서가 발생합니까?

내가 이해하지 못하는 또 다른 한가지 - 내가 gdb를 부트 로더의 실행을 추적 할 때 다음과 같은 명령이 (즉, 부트 로더 코드에서 LJMP 명령의) 실행되는 것을 볼 :

ljmp $0x8,$0x7c32 
나는 .ASM 파일에서 보았을 때

는하지만 본 다음

ljmp $0xb866,$0x87c32 

완전히 여기 손실 - 명령어가 .ASM 파일 작성 및 실행 명령이 다른 와서 어떻게? 나는 이것이 보호 모드와 관련이 있고 그것이 주소를 어떻게 변환하는지에 대한 직감을 가지고 있지만 실제로 얻지는 못한다.

나는 어떤 도움을 주셔서 감사합니다!

+0

너무 광범위하게 투표하려면 투표가 너무 많습니다. –

답변

24
  1. 일부 BIOS 구현은 부트 로더에 들어가기 전에 보호 모드로 들어갑니다. 대부분은 그렇지 않습니다. BIOS가 짧은 기간 동안 보호 모드로 전환하고 부트 로더로 이동하기 전에 다시 전환되어 보호 모드의 이점 (예 : 기본 주소 크기 인 32 비트)을 사용할 수 있습니다. 부트 로더가 리얼 모드에 있어야하는 이유는 대부분의 BIOS 기능이 리얼 모드에서만 작동하므로 리얼 모드에서 사용해야합니다.

  2. ljmp는 점프 할 주소 외에 전환 할 코드 세그먼트를 지정합니다. 그들은 너무 유사하여 (적어도 GAS에서) 어셈블러는 2 피연산자가있는 jmp를 ljmp로 전환합니다.

  3. ljmp는 cs 레지스터를 변경하는 유일한 방법 중 하나입니다. cs 레지스터는 GDT의 코드 세그먼트에 대한 선택기를 포함해야하므로 보호 모드를 활성화하려면이 작업을 수행해야합니다. (궁금한 점이 있으시면, cs를 변경하는 다른 방법은 원거리 전화, 원거리 복귀 및 인터럽트 리턴입니다.)

  4. 항목보기 1. BIOS가 리얼 모드로 전환되었거나이 부트 로더가 BIOS.

  5. 3을 참조하십시오. cs가 32 비트 코드 세그먼트를 지정하도록 변경되므로 프로세서는 32 비트 모드로 전환됩니다.

  6. .asm 파일을 살펴보면 주소 크기가 32 비트 인 것처럼 해석되지만 GDB에서는 주소 크기가 16 비트 인 것처럼 해석합니다. 명령의 주소에있는 데이터는 0xEA 32 7C 08 00 66 B8이됩니다. EA는 long jump opcode입니다. 32 비트 주소 공간에서 주소는 0x87C32의 주소에 대해 다음 4 바이트를 사용하여 지정되지만 16 비트 주소 공간에서는 0x7C32의 주소에 대해 2 바이트 만 사용됩니다. 주소 뒤의 2 바이트는 요청 된 코드 세그먼트를 지정하며 32 비트 모드에서는 0xB866이고 16 비트 모드에서는 0x0008입니다. 0x66 B8은 16 비트 즉시 값을 ax 레지스터로 이동하는 다음 명령어의 시작입니다. 보호 모드 용 데이터 세그먼트를 설정하는 것이 좋습니다.

+3

굉장 - 당신은 정말로 나를 위해 일들을 명확히했습니다, 감사합니다! – s0li

2

왜 BIOS에서 보호 모드로 전환합니까? 부트 로더가 리얼 모드에서 실행되면 안됩니다. (btw - 왜 리얼 모드에서 실행해야합니까?)

보호 모드는 단순히 리얼 모드보다 많은 기능을 제공합니다. 인텔 CPU의 보호 기능 권한 메커니즘 (http : // en.wikipedia.org/wiki/Ring_(computer_security), 32 비트 모드 실행 등

ljmpl 명령의 작동 방식을 정확히 검색했지만 찾지 못했으며 ljmp와 일반 jmp의 차이점이 있습니다. - 누군가가 올바른 방향을 가르키면 감사 할 것입니다.

ljmpl과 ljmp는 문맥 상 동일합니다.

왜 우리는 점프를 수행합니까? 이 교육의 목적은 무엇입니까?

: 인텔 매뉴얼에 문서화,뿐만 아니라 아래의 코드에 인라인 설명 된대로

는 .. 진짜-에 보호 전환을

필요합니다, 그것은 여기에 스테이지 2의 부트 로더에서 구현 http://src.illumos.org/source/xref/illumos-gate/usr/src/grub/grub-0.97/stage2/asm.S#real_to_prot

974 /* load the GDT register */ 
975 DATA32 ADDR32 lgdt gdtdesc 
976 
977 /* turn on protected mode */ 
978 movl %cr0, %eax 
979 orl $CR0_PE_ON, %eax 
980 movl %eax, %cr0 
981 
982 /* jump to relocation, flush prefetch queue, and reload %cs */ 
983 DATA32 ljmp $PROT_MODE_CSEG, $protcseg 
984 

유 볼 수 있듯이, 각 코드 부분은 함수를 갖고, LJMP 플러시 본질적 O 인 인텔 프리젠 테이션에서 필요한대로 프리 페치 큐를 어디에서 기억하는지 알 수 없습니다.

관련 문제