1. leaq _text(%rip), %rdi 에서 %rdi에는 어떤 값이 들어가는가

 

정답은 0x1000000이 들어가는게 맞습니다

 

소스 바로 윗부분을 보면

leaq _text(%rip), %rax

shrq $MAX_PHYSMEM_BITS, %rax

jnz bad_address

이런 코드가 있는데 만약 첫줄 %rax에 0xFFFFFFFF80000000이 들어가게 되면 bad_address로 점프하게 됩니다

우리가 주석까지 달았는데 아무도 알아차리지 못했네요 ㅋㅋ

 

 

2.

leaq _text(%rip), %rbp

subq $_text - __START_KERNEL_map, %rbp

 

첫줄에서 %rbp는 0x1000000 이고

두번째 줄의 $_text는 0xFFFFFFFF80000000 이라 결국 %rbp에는 0이 들어간다는 가설이 있었습니다

%rbp는 커널이 relocate 된 경우에만 의미있는 값을 가지게 되기 때문

 

 

 

일단 1번을 토대로 메모리맵을 대충 그려보았는데 상당히 깔끔한 그림이 나왔습니다

 

 

우리가 고민했던 코드는 주석에도 나와있듯이 switchover를 위해

커널의 _text 부터 _end까지를 1:1로 매핑하는 페이지 테이블을 새로 설정해 주는 것입니다

 

early_level4_pgt의 앞쪽 부분은 level4로 이용하고

64개의 early_dynamic_pgts들 중

첫번째 early_dynamic_pgts는 level3,

두번째 early_dynamic_pgts는 level2처럼 사용합니다

 

따라서 실제 커널이 들어있는 페이지 프레임 주소가 저장되는 곳은 두번째 early_dynamic_pgts 입니다

 

그런데 커널이 relocate된 경우 그냥 엔트리를 설정해주면 테이블의 boundary를 넘어가는 문제가 생길 수가 있습니다

(early_level4_pgt는 앞에서 주소값이 46비트가 넘어가는지 미리 체크해주기 때문에 테이블의 크기를 넘지 않습니다)

 

그래서 이 경우 마치 큐처럼 테이블의 가장 마지막 엔트리에 다다르게 되면 첫번째 엔트리로 돌아가서

계속해서 매핑을 해주게 됩니다

이 부분이 주석에서 wraparound어쩌구 하던 부분인 것 같습니다

 

커널 코드가 들어있는 물리주소가 1G boundary를 넘게 되면 두번째 early_dynamic_pgts 가 순환하게 되고

커널 시작 주소(_text)가 512G boundary에 걸치게 되면 첫번째 early_dynamic_pgts 가 순환하게 됩니다

 

 

그 아래 코드는 위에서 했던것 처럼 level2_kernel_pgt에도 %rbp를 더해주는 작업을 하게 됩니다

 

 

#PF handler 부분은 아직 못찾아봤습니다 ㅋㅋ

 

 

자세한 내용은 다음주에 같이 생각해보는게 좋을 것 같습니다

 

그럼 좋은 주말 보내세요!

 

 

XE Login