How to Context switching in BeakOS?

EeS 2016.06.22 21:03 조회 수 : 322

저희가 지난 일요일 스터디 때, Context Switching 에서 PC 또는 LR을 출력하였을 때, 서로 다른 Task 에서도 바뀌는 부분이 없어서 혼란스러웠었는데요.
이는 BeakOS 가 Thread 방식 RTOS 인 점과 무관하지 않을까 합니다.

 

우선 Thread 방식이기 때문에 같은 address영역을 공유하는 점을 기억해야 합니다.

이 부분을 기억하고 Context switching 과정을 따라가 보도록 하겠습니다.

 

이에 앞서, 저희가 기억해야 하는 몇 address 값을 적어보겠습니다.

 

40018798 B task0
400187c4 B task1
400187f0 B task2

 

또한 다음에 선택 될 task 를 task1, 현재 task 를 task0 으로 가정합니다.

 

우선 task0 이 잠드는 시점부터 시작하겠습니다.

 

int Task0Main(void *args) {
    while (1) {
        printf("Task : 0\n");
        TaskYield();
    }   

    return 0;
}

 

이 때, TaskYield(); 바로 다음 addr 이 Stack 에 저장되게 됩니다.(lr)

또, 이 상황에서의 fp가 같이 저장됩니다.

(의문점. 분명 ARM스터디 한 책 에선 현대 ARM아키텍쳐에서는 fp를 Stack Frame Pointer 로 사용하지 않는다고 했는데, 실제 코드에선 마치 FP를 사용하는 듯 동작한다.)

 

int TaskYield(void) {
    int flag;
    flag = IntSave();
    TaskDequeue(currentTask);
    TaskEnqueue(currentTask);
    DoScheduling();
    IntRestore(flag);
    return 0;
}   

 

여기서 역시 fp 와 DoScheduling 다음 명령어 주소가 stack 에 저장됩니다.

이때, int flag가 유지됨을 주의하여야 합니다.

 

void DoScheduling(void) {
    struct TaskStruct *current;

    current = currentTask;
    currentTask = TaskSelect();

    if (currentTask == current) {
        return;
    }

    ContextSwitch(current, currentTask);
}

 

여기서, fp와 역시 다음 주소가 스택에 저장됩니다.

이 때, current가 스택에 저장됩니다.

 

void ContextSwitch(struct TaskStruct *currentTask, struct TaskStruct *nextTask) {
    struct ContextFrame *ctx = (struct ContextFrame *)nextTask->stackPoint;
unsigned int tmp;
 

이제 컨텍스트 스위칭을 하는 위치 입니다.

이 때, 넘겨받은 인자값을 스택에 저장하므로 주의하여야 합니다.

 

여기까지 왔을 때, 스택은 아래와 같이 생겼습니다.

 

Task : 0
sp = 400197fc
400197fc: 0x400187ec r1
40019800: 0x400187c0 r0
40019804: 0x400197fc tmp
40019808: 0x4001a7b4 struct
4001980c: 0x40019820 fp
40019810: 0x4001164c lr (DoScheduling)
40019814: 0x00000000 dumy
40019818: 0x400187c0 str
4001981c: 0x40019830 fp
40019820: 0x40011a4c lr (TaskYield)
40019824: 0x40011db8 flag
40019828: 0x00000000 dumy
4001982c: 0x40019840 fp
40019830: 0x40011b44 lr
40019834: 0x00000000
40019838: 0x00000000
4001983c: 0x00000000
40019840: 0x4001198c
40019844: 0x00000000
40019848: 0x00000000

 

이제, 만약 컨택스트스위칭 과정 없이 각 함수를 빠져나온다면, 

최종적으로 40019830: 0x40011b44 lr 이 pc 가 됩니다.

 

이는, Task0Main에서 TaskYield 다음 위치 입니다.

40011b24 <Task0Main>:
40011b24:   e92d4800    push    {fp, lr}
40011b28:   e28db004    add fp, sp, #4
40011b2c:   e24dd008    sub sp, sp, #8
40011b30:   e50b0008    str r0, [fp, #-8] 
40011b34:   e3010db8    movw    r0, #7608   ; 0x1db8
40011b38:   e3440001    movt    r0, #16385  ; 0x4001
40011b3c:   ebfffcf0    bl  40010f04 <printf>
40011b40:   ebffffb0    bl  40011a08 <TaskYield>
40011b44:   eafffffa    b   40011b34 <Task0Main+0x10>

 

하지만, 컨택스트 스위칭을 하므로, sp가 Task1 의 sp로 변경됩니다.

이 때, Task1 은 Task0과 같은 과정을 거쳐서 해당 위치에 한 번 진입한 적이 있음을 예측 가능합니다.

따라서, Task1 의 스택은 위와 같은 구조입니다.

 

lr = 4001a7fc
4001a7fc: 0x40018818  r1
4001a800: 0x400187ec  r0
4001a804: 0x4001a7fc  tmp
4001a808: 0x4001b7b4  struct
4001a80c: 0x4001a820  fp
4001a810: 0x4001164c  lr (DoScheduling)
4001a814: 0x00000000  dumy
4001a818: 0x400187ec  str
4001a81c: 0x4001a830  fp
4001a820: 0x40011a4c  lr (TaskYield)
4001a824: 0x40011dc4  flag
4001a828: 0x00000000  dumy
4001a82c: 0x4001a840  fp
4001a830: 0x40011b68  lr
4001a834: 0x00000000
4001a838: 0x00000000
4001a83c: 0x00000000
4001a840: 0x4001198c
4001a844: 0x00000000
4001a848: 0x00000000

 

이 때, 최종적으로 pc 가 되는 주소는 4001a830: 0x40011b68 입니다.

이는, Task1Main 에서 TaskYield 다음 주소 입니다.

 

40011b48 <Task1Main>:
40011b48:   e92d4800    push    {fp, lr}
40011b4c:   e28db004    add fp, sp, #4
40011b50:   e24dd008    sub sp, sp, #8
40011b54:   e50b0008    str r0, [fp, #-8] 
40011b58:   e3010dc4    movw    r0, #7620   ; 0x1dc4
40011b5c:   e3440001    movt    r0, #16385  ; 0x4001
40011b60:   ebfffce7    bl  40010f04 <printf>
40011b64:   ebffffa7    bl  40011a08 <TaskYield>
40011b68:   eafffffa    b   40011b58 <Task1Main+0x10>

 

BeakOS 는 위와 같은 과정을 통해 Context Switching 을 하게 됩니다.

 

감사합니다.

번호 제목 글쓴이 날짜 조회 수
27 2019년에 os 개발스터디 진행이 불가능한가요? mzk8086 2019.07.01 219
26 OS개발 스터디 파하였나요? [1] 천재깔창 2017.07.31 676
25 중단되었나요? 천재깔창 2017.07.16 325
24 [아키텍쳐/운영체제] 4주차(20170604) 스터디 로그 목태양 2017.06.04 249
23 [아키텍쳐/운영체제] 4주차(20170604) 스터디 장소 공지 목태양 2017.06.01 66
22 [아키텍쳐/운영체제] 3주차(20170528) 스터디 로그 목태양 2017.05.28 84
21 [아키텍쳐/운영체제] 3주차(20170528) 스터디 장소 공지 [1] 목태양 2017.05.25 56
20 [아키텍쳐/운영체제] 2주차(20170521) 스터디 로그 [1] 목태양 2017.05.21 99
19 [아키텍쳐/운영체제] 서울창조경제혁신센터 예약 반려 [3] allan 2017.05.22 114
18 [아키텍쳐/운영체제] 2주차(20170521) 스터디 장소 공지 [7] 목태양 2017.05.19 135
17 [아키텍쳐/운영체제] 2주차 스터디 장소 관련 [7] 목태양 2017.05.17 94
16 [아키텍쳐/운영체제] 2주차 스터디 참석 여부 반영 부탁드립니다. [2] 목태양 2017.05.15 95
15 [아키텍쳐/운영체제] 1주차(20170514) 스터디 로그 [3] 목태양 2017.05.14 232
14 GIT 공부 자료들 [6] EeS 2016.07.12 810
13 아 죄송합니다. qtopia 2016.08.08 246
» How to Context switching in BeakOS? [1] EeS 2016.06.22 322
11 ubuntu 에서 baekos 를 QEMU 로 돌리기 위한 삽질기(1) [3] EeS 2016.05.10 1267
10 ARM Instruction 임시값 로드 관련. titititi 2016.05.29 190
9 qemu에서 s5pc210의 entry가 0x40010000 번지인 이유 [3] 아이엠푸 2016.05.08 417
8 이번 주 스터디 장소입니다. [1] 옹알이 2016.05.07 233
XE Login