new call-gate, cs, ds 추가관련 질문입니다.

조성현 2008.05.31 02:43 조회 수 : 5998 추천:42

안녕하세요?

제가 리눅스 커널을 공부한지 얼마안되어서;; 이 곳 자료를 많이 참조하면서 공부하고 있습니다 :)
이점에서 정말 감사드리고요. 저도 서울 지역에 거주하게 될 경우, 꼭 스터디에 참석하도록 하겠습니다.~

그리고 초면에 이렇게 질문 드리는 것은 예의가 아닌데, 마땅히 질문할 곳이 있지 않아서 이렇게 글을 적습니다. (백창우님 개인적으로 존경함, 멤버십에서 OS 과제, 필수 유틸리티 등으로 인해)

일단, 본론을 말씀드리자면, 제가 Kernel(DPL:0)과 User(DPL:3) 사이에 뭔가를 새로 집어넣고, 그 곳의 코드를 User(DPL:3)에서 실행토록 하는 것입니다. 물론, 거대한 프로젝트를 위한 테스트 작업 수준입니다.

현재까지 진행 상황은 kernel 2.6.24.4를 받아서 소스의 arch/x86/kernel/cpu/common.c 파일에서 gdt_page가 선언되어 있는 곳에 제가 원하는 새로운 Segment 정의를 했습니다.(물론, include/asm-x86/segment_32.h에 선언되어 있는 GDT 번호를 살펴본 후에, 사용되어 있지 않은(unused) 번호를 사용하고 있습니다. 이것은 제가 비어있다고 여기는 것으로, 실제는 모르겠네요;; 일단, 12,13번이 Kernel code, data segment로 할당되어 있고, 등등 적혀 있는데, 저는 28,29,30번을 사용했습니다.)

header 파일에서의 정의는 아래와 같이 추가하였습니다.
-------------------------------------------------------------------------
#define GDT_ENTRY_VM_BASE 28

#define GDT_ENTRY_VM_CS (GDT_ENTRY_VM_BASE + 0)
#define __VM_CS (GDT_ENTRY_VM_CS * 8 + 3)

#define GDT_ENTRY_VM_DS (GDT_ENTRY_VM_BASE + 1)
#define __VM_DS (GDT_ENTRY_VM_DS * 8 + 3)

#define GDT_VM_CALLGATE 30
#define __VM_CALLGATE (GDT_VM_CALLGATE * 8 + 3)
-------------------------------------------------------------------------
위를 보시면 아시겠지만, + 3을 한 이유는 User Code에서 수행할 수 있도록 한 것입니다. 일단, 테스트 후에 DPL = 1 권한으로 변경할 예정입니다.(처음부터 1로 했었는데, 아예 접근 에러가 나서... 다시 이렇게 한 것입니다.) 이름은 그냥 VM이라고 임시로 했습니다.;;

그러면, 다시 gdt_page 테이블로 와서, 맨 마지막에
-------------------------------------------------------------------------
    [GDT_ENTRY_VM_CS] = { 0x0000ffff, 0x00cffa00 }, /* vm 4GB code */
    [GDT_ENTRY_VM_DS] = { 0x0000ffff, 0x00cff200 }, /* vm 4GB data */
    /* 계산을 위한 참고 사항입니다.
    <call-gate vm-user>
        .word 0x0000                routine offset 15~0
        .word __VMCODE_CS           code segment selector
        .word 0xec00                P:1,DPL:11,0,type:1100(Call-gate)
        .word 0x0000                routine offset 31~16
    <temp code>
        _VM_CS = 28*8 + 1 = 225(0xe1)
        0x0000 0x00e0 0xec00 0x0000 (word)
        00 00 e0 00 00 ec 00 00 (byte)
        0x00e00000 0x0000ec00 (dword)
    */
    [GDT_VM_CALLGATE] = { 0x00e30000, 0x0000ec00 }
-------------------------------------------------------------------------
그러면, 부팅할 때, 저절로 lgdt 명령에 의해서 읽어지는 것 같더군요. 제 소견으로는 부팅시 cpu_init() 함수가 호출되는데, switch_to_new_gdt() 함수가 호출되는 것으로 보이며, 관련된 값으로 GDT_SIZE가 있는데, 이것은 gdt_page 테이블 전체를 읽어들이는 것으로 보입니다.

제가 질문 드리고자 하는 것은 이제부터입니다. ;; 조금만 참고 읽어주시면 감사하겠습니다.

아래 코드는 이 arch/x86/kernel/cpu/common.c 파일에서 cpu_init() 함수의 내용에서 switch_to_new_gdt()가 호출되고 나서 바로 수행토록 한 것입니다. 근데, 아래 소스를 집어넣으면 부팅시에 멈춰버리는 현상이 있습니다.
-------------------------------------------------------------------------
    load_idt(&idt_descr);
    switch_to_new_gdt();

/**************************************
* Add my code [by ntames8]           *
**************************************/
/*
    Selector
    0x60 : kernel code
    0x68 : kernel data
    0xe3 : vm code
    0xeb : vm data
    0xf3 : call-gate
*/
    printk(KERN_INFO "-_- mycode startn");
    buff = kmalloc(1024, GFP_KERNEL);
    if (buff != NULL)
    {
        asm(
        // it copys from vm_test to vm_code area(buff)
            "pusha;"
            "leal vm_test,%%eax;"
            "movl %%eax,%0;"
            "push %%ds;"
            "push %%es;"
            : "=m" (addr));
        printk(KERN_INFO "vm_test addr in kernel = %8pn", addr);
        asm(
            //일단 DS로 할당해봄. 원래는 CS로 해야함.
            "movl $0xeb,%%eax;"     // __VM_DS = 0xe9
            "mov %%ax,%%es;"
            "leal vm_test,%%esi;"
            "leal %0,%%eax;"
            "movl (%%eax),%%edi;"   // edi <= buff(kmalloc)
            "movl $(vm_end-vm_test),%%ecx;"
            "rep;"
            "movsb;"
            "jmp vm_end;"

            "vm_test:"
            "pusha;"
            "movl $0x4,%%eax;"
            "movl $0x1,%%ebx;"      // unsigned int
            "leal str_hello,%%ecx;" // const char*
            "movl $14,%%edx;"       // size_t
            "int $0x80;"
            "popa;"
            "lret;"
            "str_hello:"
            ".string "Hello world!n";"
            "vm_end:"
            "pop %%es;"
            "pop %%ds;"
            "popa;"
            : // no output
            : "m" (buff));
        printk(KERN_INFO "vm_test addr as buff in vm_ds = %8pn", addr);
    }
    else
    {
        printk(KERN_INFO "no kmalloc");
    }
    printk(KERN_INFO "-_- mycode endn");
/******************
* End            *
******************/
-------------------------------------------------------------------------

부팅시 Uncompressing Linux... OK, booting the kernel.이라는 메시지가 나온 후에 그냥 멈춰있는 상태입니다.

이 메시지는 arch/x86/boot/compressed/misc_32.c 파일의 decompress_kernel() 함수에서 gunzip()하고 나서 나오는 메시지군요.;;;

혹시 제가 잘못한 것이 무엇인지 알 수 있을까요?? 커널에 임의의 코드를 심어놓고 작동하게 하는 데, 제한적인 요소가 어떤 것들이 있는지 알 수 있을까요?;;

제가 간단하게 살펴보니, 리눅스 커널이 하나의 페이지에 올라와서 수행된다는 말이 있던데, 혹시 페이지에 관련된 메모리 제한(제약) 때문인가요? 페이지를 제가 새로 생성해야하나요?

저도 혹시나 해서 kmalloc()함수로 할당해본 것이거든요.(할당하든 안하든 똑같은 에러입니다.)

제가 페이징이 어떻게 이루어지고, 정확하게 모르는 상황이라, 어느 쪽으로 접근하면 답을 알 수 있는지라도 알려주시면 감사하겠습니다. __;

이 작업을 하면서 제가 틈틈히 기록하는 공간은 http://linu.sarang.net/wiki/?%EB%A6%AC%EB%88%85%EC%8A%A4%EC%BB%A4%EB%84%90 으로 혹시나 모르시는 내용이 있으시면 이 쪽을 살펴보시면 될 것 같아요. 여기에 리플로 다시 재질문 하셔도 되고요.;;

말이 많았네요. 아, 참고로, 위에서 작성된 어셈블리어 프로그램은 유저 레벨에서 어느 정도 검증된 상태입니다. 코드상 에러보다는, 코드 자체가 커널 부팅 과정에 포함되어 있는 상황에 초점을 더 맞춰주셨으면 합니다.;;;

그러면 여기까지 읽어주신 것만으로도 감사드립니다. __; -- 2008-05-31 02:43 wbhacker
번호 제목 글쓴이 날짜 조회 수
공지 [공지] 프로그래밍 관련 Q&A 게시판 입니다. woos 2016.04.09 22253
38 sleep과 재진입가능 함수. [1] 김기욱 2008.11.15 9159
37 ramdisk 는 물리적으로 연속적인 메모리인가요?? [10] 신철수 2008.11.06 6330
36 [질문] printf 소스는 어디에 있나요? [1] 손성원 2008.09.23 10914
35 hypervisor 위에서 돌아가는 guest에서 vt-x 를 사용할 수 없나요? [1] 남현우 2008.09.11 6896
34 [질문] 리눅스 서버 구축 [3] 맥주 2008.08.08 5869
33 커널 hang 걸렸을 때 관련정보 볼 수 잇는 방법이 있을까요?? [2] 신철수 2008.08.06 7879
32 리눅스 커널 디버깅 (kdb) 질문 있습니다!!!!! [2] 조성훈 2008.07.09 8836
» new call-gate, cs, ds 추가관련 질문입니다. [2] 조성현 2008.05.31 5998
30 추가질문. User와 Kernel 중간 영역에 코드 삽입 [1] 조성현 2008.06.18 6938
29 XEN 스케쥴링 관련하여 질문 좀 부탁드리겠습니다... 장형근 2008.04.30 6942
28 [re] XEN 스케쥴링 관련하여 질문 좀 부탁드리겠습니다... 박세율 2008.07.05 7752
27 ^^ 안녕하세요. pmd_large() 함수 질문입니다. [3] 박종섭 2008.04.10 7440
26 [질문] 세미나관련..공유라이브러리 [3] 박은병 2008.04.08 6840
25 Kernel 분석 5기 멤버 모집은 언제쯤 하시는 지요 ?? [2] 석헌영 2008.04.06 5784
24 백창우님, 질문 있습니다~ [2] 김기태 2008.04.06 6818
23 [질문] 스터티 참가 문의 [1] 김연찬 2008.04.03 5835
22 [질문] 쓰 레 드 ...... [4] 박은병 2008.03.28 6749
21 USB host 관련 porting 이나 non bus type 으로 작업 해보신 분 계신가요? [3] 신철수 2008.02.27 7301
20 이 문서 가지고 계시는 분 리형중 2008.02.25 6099
19 혼자서 커널공부하는데 조언을 부탁드립니다. [2] 김현중 2008.02.09 7800
XE Login