Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kernel.asm difference between xv6 and rv6 #109

Closed
coolofficials opened this issue Aug 10, 2020 · 15 comments
Closed

kernel.asm difference between xv6 and rv6 #109

coolofficials opened this issue Aug 10, 2020 · 15 comments
Assignees

Comments

@coolofficials
Copy link
Collaborator

coolofficials commented Aug 10, 2020

  • xv6
    image

  • rv6
    image

처음에 sp 관련해서 차이가 있고, start의 위치도 달라서 살짝 확인을 해보니,

일단

  • xv6는 바로
    image

timerinit이 오는 반면,

  • rv6에서는 swtch kernelvec timervec등이 나오고 마지막에 위치해야할 trampoline이 일찍 등장합니다.
    image

뭔가 역순으로 assign 하고 있다는 느낌이 강하게 들어서 한 번 확인해보겠습니다.

@coolofficials
Copy link
Collaborator Author

coolofficials commented Aug 10, 2020

trampoline이 일찍 등장하는 이유는 rv6에서 함수들을 조금 더 encapsulation 하여 사용하기 때문인 것 같습니다(추측입니다). 추가적으로 assembly를 조금 더 잘 보기 위해 #[no_mangle]을 최대한 넣는 것이 좋을 것 같습니다.

@coolofficials
Copy link
Collaborator Author

@jeehoonkang ping
어셈블리 확인을 위해 최대한 많은 함수에 #[no_mangle] 을 추가해도 괜찮을까요?

@coolofficials
Copy link
Collaborator Author

@jeehoonkang
Copy link
Member

  • 용이한 디버깅을 위해 nomangle 최대한 넣읍시다.
  • trampoline이 일찍 등장하는건 문제인 것 같네요. 조정해서 제일 뒤로 보낼 수 있는 방법이 잇는지 알아봐주세요

@jeehoonkang
Copy link
Member

  • b5eea10
    방금 커밋을 하나 했는데, stack에 local variable을 하나 만들면 커널이 잘 작동하는 것 같습니다.
    pgroundup 적용 못하던 문제는 local variable이 사라져서 생기는 문제인 것 같습니다.

  • 위를 미루어 보았을 때 kernel stack이 잘 initialize되지 않는 것 같은데, trampoline이 잘 설정되면 해결되는 문제가 아닐까 추측합니다.
    혹시 trampoline이 뭐하는건지 좀더 이해해볼래요?

@coolofficials
Copy link
Collaborator Author

예 알겠습니다. 내일 출근해서 trampoline부터 검토하도록 하겠습니다.

@coolofficials
Copy link
Collaborator Author

  • 교수님 b5eea10 커밋 이후 kernel이 정상 동작하지 않는 것 같습니다. (hart message, booting error)
  • 저는 최신 상태의 riscv branch를 확인했습니다.

@jeehoonkang
Copy link
Member

jeehoonkang commented Aug 10, 2020

  • s01에서 되었었는데 제 local에선 안되었었네요...
  • 잘 이유는 모르겠지만 rust toolchain을 2020-07-26으로 올리니 해결된 것 같습니다. 현재 riscv 브랜치 확인 부탁드려요.

@coolofficials
Copy link
Collaborator Author

동작 확인했습니다.

@jeehoonkang
Copy link
Member

Closing?

@coolofficials
Copy link
Collaborator Author

@jeehoonkang 일단 trampoline은 별도의 issue로 분리했습니다. no_mangle 다른 이슈로 분리하고 어셈블리 한 번 더 확인 후에 closing 하는게 좋을 것 같습니다.

@coolofficials
Copy link
Collaborator Author

coolofficials commented Aug 13, 2020

여전히 변경점들이 해소된게 많이 보이지 않아서 아직 closing 할 수 없을 것 같습니다. 적어도 #143 을 적용하고 #125 를 해결한 후에 다시 asm을 비교 확인해야 할 것 같습니다.

@kimjungwow
Copy link
Collaborator

요약 : xv6와 rv6에서 trampoline의 주소가 다른 것은 Makefile의 OBJS가 다르게 정의되기 때문인 것 같습니다.

  • 시원님께서 말씀하신대로, xv6와 rv6에서 각각 make qemu 실행 후 kernel.asm을 비교하면, 각각 아래의 순서로 assign이 됩니다.
    • xv6에서는 _entry, junk, timerinit, start, consoleread
    • rv6에서는 _entry, junk, swtch, kernelvec, timervec, trampoline
  • 이는 Makefile에서 OBJS를 정의하는 방법이 다르기 때문인 것 같습니다.
  • xv6의 Makefile에서는 아래와 같이 OBJS를 정의합니다.
OBJS = \
  $K/entry.o \
  $K/start.o \
  $K/console.o \ 
   .. 생략
  • 따라서 xv6의 kernel.asm에서는 아래와 같은 순서로 assign 됩니다.
    • entry.S에서 정의된 _entry, _junk
    • start.c에서 정의된 timerinit(), start()
    • console.c에서 정의된 consoleread(), consputc()
  • 하지만 rv6의 Makefile에서는 아래와 같이 OBJS를 정의합니다.
OBJS = \
  $K/entry.o \
  $K/swtch.o \
  $K/trampoline.o \
  $K/kernelvec.o \
  $(KR)/target/$(RUST_TARGET)/$(RUST_MODE)/librv6_kernel.a
  • 따라서 rv6의 kernel.asm에서는 아래와 같은 순서로 assign 됩니다.
    • entry.S에서 정의된 _entry, _junk
    • swtch.S에서 정의된 swtch
    • kernelvec.S에서 정의된 kernelvec, timervec
    • trampoline.S에서 정의된 trampoline, userret
    • 이후 Rust 소스 코드 및 core에서 정의된 함수들
  • rv6의 kernel.asm에서 이상한 점
    • OBJS 정의 시 kernelvec.otrampoline.o보다 뒤에 있지만 kernel.asm에서는 나오지 않음
    • trampoline.S에서 정의된 uservec의 주소는 kernel.asm에 나오지 않음

rv6와 xv6의 kernel.asm 속 trampoline 주소가 다른 것이 이 이유가 맞다면, 이 이슈는 closing해도 좋다고 생각합니다.

하지만 rv6의 kernel.asm에서 이상한 점 2가지는 이슈로 새로 만들지 의견 여쭙고 싶습니다.

@jeehoonkang
Copy link
Member

먼저 OBJS 상의 순서가 semantics, correctness에 영향을 주는지 궁금합니다.
만일 trampoline, kernelvec을 가장 뒤에 놓는게 의도라면 우리도 그걸 따라가야 합니다.

이상한점 2가지: rv6 개발에 큰 지장이 없다면 굳이 논의하지 않아도 되지 않을까 합니다. 정우님께서 판단 부탁드립니다.

@kimjungwow
Copy link
Collaborator

요약 : trampoline을 virtual address space의 꼭대기에 위치시키는 xv6의 의도를 rv6가 잘 따르는 것으로 보여, 이 이슈는 닫겠습니다.

  • 아래 그림과 같이 xv6에서는 trampolinevirtual address space의 꼭대기에 위치시킵니다.
    image
  • proc.rs::proc_pagetable()에서 TRAMPOLINETRAPFRAME (virtual address)trampolinetrapframe의 주소 (physical address) 에 매핑시킵니다.

    rv6/kernel-rs/src/proc.rs

    Lines 442 to 469 in f7e431a

    /// Create a page table for a given process,
    /// with no user pages, but with trampoline pages.
    pub unsafe fn proc_pagetable(p: *mut Proc) -> PagetableT {
    // An empty page table.
    let pagetable: PagetableT = uvmcreate();
    // Map the trampoline code (for system call return)
    // at the highest user virtual address.
    // Only the supervisor uses it, on the way
    // to/from user space, so not PTE_U.
    mappages(
    pagetable,
    TRAMPOLINE,
    PGSIZE,
    trampoline.as_mut_ptr() as usize,
    PTE_R | PTE_X,
    );
    // Map the trapframe just below TRAMPOLINE, for trampoline.S.
    mappages(
    pagetable,
    TRAPFRAME,
    PGSIZE,
    (*p).tf as usize,
    PTE_R | PTE_W,
    );
    pagetable
    }
  • 이 때 TRAMPOLINE은 다음과 같이 virtual address space의 꼭대기를 나타냅니다.

    rv6/kernel/memlayout.h

    Lines 50 to 52 in f7e431a

    // map the trampoline page to the highest address,
    // in both user and kernel space.
    #define TRAMPOLINE (MAXVA - PGSIZE)

    /// map the trampoline page to the highest address,
    /// in both user and kernel space.
    pub const TRAMPOLINE: usize = MAXVA.wrapping_sub(PGSIZE);
  • xv6와 rv6의 kernel.asm에서 trampoline의 physical address가 다르더라도, 똑같이 xv6의 의도대로 virtual address space의 꼭대기와 매핑되기 때문에 이 이슈는 닫아도 좋을 것 같습니다.
  • 추가적인 논의가 필요하면 언제든 이슈를 re-open 해주세요!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants