Q&A 게시판

리눅스 커널에 대한 Q&A 게시판 입니다. (비밀글 체크는 꼭 필요한 경우에만)

context_change

작성자
김인용
작성일
2018-12-31 03:20
조회
484
안녕하세요

지금 헷갈리는게 있어서 그런데

check_and_switch_context()함수에서

cpu_set_reserved_ttbr0() 함수를 호출하는데, 유저->커널로 변경시 자동으로 ttbr0->ttbr1으로 변경되는 것 아닌가요?

굳이 이렇게 일부러 세팅을 하는 이유가 궁금하네요 ....

리눅스에서 ttbr1이 커널의 tlb를 가리키는게 맞지요?
전체 6
  • 2018-12-31 10:24
    안녕하세요?

    먼저 답변을 드리자면 32bit arm 리눅스에서는 유저 모드에 있든 커널 모드에 있든 ttbr0 만을 사용합니다.

    mm 스위칭 속도를 보다 빠르게 동작시키기 위해 메모리 대신 ttbr1을 사용하고 있습니다.

    참고로 ttbr1에는 커널용 글로벌 페이지 테이블의 물리 주소를 기억하고 있습니다.

  • 2018-12-31 16:12
    답변 감사드립니다. 그럼 변경 후엔 ttbr1을 사용하게 되면 앞으로도 계속 사용하게 되는거 아닌가요 ./
    유저 모드에 있든 커널 모드에 있든 ttbr0 만을 사용 한다는 말이 아니게 되는거 아닌가요? SWITCH_TO에서 다시 바꾸나요 ?

  • 2018-12-31 18:57
    32bit arm 커널에서는 64bit arm 커널과 다르게 유저 태스크용 페이지 테이블과 커널용 페이지 테이블을 따로 따로 만들지 않습니다..

    참고로 유저 태스크가 생성될 때 마다 4G를 관리할 수 있는 페이지 테이블 pgd가 배정됩니다.
    그런데 이 pgd는 아래 영역은 유저 영역을 담당하고, 윗 부분은 커널 영역을 담당합니다.

    그런데 커널로 진입하여 매핑이 변경되는 경우가 발생하면 일단 글로벌(init) 페이지 테이블을 변경하고 변경되었다는 시퀀스 번호를 갱신합니다.
    이 후로 각 유저 태스크에 진입할 때 마다 시퀀스 번호와 다른 경우 커널용 글로벌 페이지 테이블이 변경이 이루어졌음을 글로벌 페이지 테이블에서 변경된 부분들을 복제하여 유저용 페이지 테이블의 커널 엔트리 부분에 해당하는 영역을 갱신하게 합니다.

    ---------

    arm 커널은 ttbr1을 그냥 조금 빠른 4바이트 메모리로 이용합니다. (물론 다른 용도로 사용하는 경우도 있습니다만...)
    (실제 ttbr1이 아무런 영향도 끼치지 않게 사용하고 있습니다. 그냥 커널용 글로벌 페이지 테이블의 물리 주소만을 보관하고 있습니다)

    ---------- (부팅 후 3개의 태스크를 생성한 경우 예)


    커널이 부팅한 후 static하게 구성된 커널용 글로벌 페이지 테이블을 처음에 사용합니다.

    그러다가 3개의 유저 태스크를 생성하게 되면 각 유저 태스크에 해당하는 3개의 페이지 테이블을 만드는데,
    커널 영역에 해당하는 글로벌 페이지 테이블 엔트리들을 각 유저 태스크용 테이블의 커널영역에 복사합니다.

    이 후 ttbr0은 유저A -> 유저B -> 유저C 페이지 테이블을 반복하여 운영합니다.
    (처음에만 글로벌 페이지 테이블을 사용하고, 유저 테이블이 만들어져서 동작한 후에는 커널 페이지 테이블 매핑 관리만을 위해서 운용됩니다.)

    ttbr0가 유저 모드에 있든 커널 모드에 있든 한 개의 페이지 테이블만을 스위칭하며 가리킵니다.

  • 2018-12-31 22:57
    유익한 정보 정말 감사드립니다. 제가 생각했던 것과 동작은 비슷하네요 (처음에는 init_mm->pgd만을 사용하는 건 아닐까 착각했었는데 역시 새로 만들어서 ttbr0을 변경시키는군요)

    그런데 궁금한 점이 page구조체들을 4g만큼 가리키도록 처음에 만들잖아요
    page_fault시 pgd를 수정하면서 물리주소를 가리키는 page 구조체를 수정할텐데 어차피 물리주소페이지는 겹치지 않으니깐
    vma의 flag와 tlb의 flag만 변경하는게 맞는거죠 ?
    최초에 os공부했을 때는 모든 프로세스마다 page 구조체를 가져야 하는게 아닐까 생각했는데 리눅스소스를 보면 볼수록 제가 말한대로 동작하는거 같아서요

  • 2019-01-01 21:25
    shared memory와 파일등이 물리메모리에 할당되면 해당 페이지들은 여러 태스크에서 공유될수 있음을 고려하시시 바랍니다. 즉 1개의 물리페이지는 여러 개의 vma에 포함될 수 있슴니다. 또한 그 물리 페이지는 각 태스크에서 공유될 수 있으므로 각 유저 페이지 테이블에 매핑돱니다.
    참고로 page 구조체는 태스크 수와 관계없이 물리 페이지 수 만큼 존재합니다.

  • 2019-01-02 10:35
    마지막 질문하신 답변에 대해 덧붙입니다.
    페이지 fault 시 vma의 flag 등을 갱신하는 것이 맞습니다.
    그런데 tlb flag는 어떤 의미인지 잘 이해가 안됩니다.
    tlb는 페이지테이블 엑세스를 빠르게하기 위한 h/w 캐시이고, 리눅스 커널에서는 flush등의 필요 여부를 관리하는데, 그것을 말씀하시는 것이라면 맞습니다.