How the Linux kernel analyzes how the operating system works

Source: Internet
Author: User
Tags volatile

How the Linux kernel analyzes how the operating system works

20122137 Sha Yu Ji
Original works reproduced please indicate the source
Linux kernel Analysis MOOC course http://mooc.study.163.com/course/USTC-1000029000

1. Content Description

The inline assembly syntax is as follows:


The specific code is as follows:

(1) Mypcb.h header file

/*

* Linux/mykernel/mypcb.h

* Kernel Internal PCB types

* Copyright (C) mengning

*/

#define MAX_TASK_NUM 4

#define Kernel_stack_size 1024*8

/* Cpu-specific State of this task */

struct Thread {

unsigned long IP;

unsigned long SP;

};

typedef struct pcb{

int pid;

volatile long state; /* -1unrunnable, 0 runnable, >0 stopped */

Char Stack[kernel_stack_size];

/* Cpu-specific State of this task */

struct thread thread;

unsigned long task_entry;

struct PCB *next;

}TPCB;

void My_schedule (void);

(2) MYMAIN.C

/*

* LINUX/MYKERNEL/MYMAIN.C

* Kernel Internal My_start_kernel

* Copyright (C) mengning

*/

#include <linux/types.h>

#include <linux/string.h>

#include <linux/ctype.h>

#include <linux/tty.h>

#include <linux/vmalloc.h>

#include "Mypcb.h"

Tpcbtask[max_task_num];

TPCB *my_current_task = NULL;

volatile intmy_need_sched = 0;

Voidmy_process (void);

void __initmy_start_kernel (void)

{

int pid = 0;

int i;

/* Initialize Process 0*/

Task[pid].pid = pid;

Task[pid].state = 0;/*-1 unrunnable, 0runnable, >0 stopped * *

Task[pid].task_entry = task[pid].thread.ip= (unsigned long) my_process;

TASK[PID].THREAD.SP = (unsignedlong) &task[pid].stack[KERNEL_STACK_SIZE-1];

Task[pid].next = &task[pid];

/*fork More Process */

for (i=1;i<max_task_num;i++)

{

memcpy (&task[i],&task[0],sizeof (TPCB));

Task[i].pid = i;

Task[i].state =-1;

TASK[I].THREAD.SP = (unsignedlong) &task[i].stack[KERNEL_STACK_SIZE-1];

Task[i].next = Task[i-1].next;

Task[i-1].next = &task[i];

}

/* START process 0 by task[0] */

PID = 0;

My_current_task = &task[pid];

ASM volatile (

"Movl%1,%%esp\n\t"/* SETTASK[PID].THREAD.SP to ESP */

"Pushl%1\n\t"/* Push EBP */

"Pushl%0\n\t"/* Push TASK[PID].THREAD.IP */

"Ret\n\t"/* Pop task[pid].thread.ip to eip*/

"Popl%%ebp\n\t"

:

: "C" (Task[pid].thread.ip), "D" (TASK[PID].THREAD.SP)/* input C or D mean%ecx/%edx*/

);

}

Voidmy_process (void)

{

int i = 0;

while (1)

{

i++;

if (i%10000000 = = 0)

{

PRINTK (kern_notice "This isprocess%d-\n", my_current_task->pid);

if (my_need_sched = = 1)

{

my_need_sched = 0;

My_schedule ();

}

PRINTK (Kern_notice "This is process%d +\n", my_current_task->pid);

}

}

}

(3) myinterrupt.c

/*

* LINUX/MYKERNEL/MYINTERRUPT.C

* Kernel Internal My_timer_handler

* Copyright (C) mengning

*/

#include <linux/types.h>

#include <linux/string.h>

#include <linux/ctype.h>

#include <linux/tty.h>

#include <linux/vmalloc.h>

#include "Mypcb.h"

extern TPCB Task[max_task_num];

extern TPCB * MY_CURRENT_TASK;

extern volatile int my_need_sched;

volatile int time_count = 0;

/*

* Called by timer interrupt.

* It runs in the name of currentrunning process,

* So it use kernel stack ofcurrent running process

*/

void My_timer_handler (void)

{

#if 1

if (time_count%1000 = = 0&& my_need_sched! = 1)

{

PRINTK (kern_notice ">>>my_timer_handler here<<<\n");

my_need_sched = 1;

}

Time_count + +;

#endif

Return

}

void My_schedule (void)

{

TPCB * NEXT;

TPCB * PREV;

if (My_current_task = = NULL

|| my_current_task->next== NULL)

{

Return

}

PRINTK (Kern_notice ">>>my_schedule<<<\n");

/* Schedule */

Next =my_current_task->next;

prev = My_current_task;

if (next->state = = 0)/* -1unrunnable, 0 runnable, >0 stopped * *

{

/* Switch to Next process */

ASM volatile (

"PUSHL%%ebp\n\t"/* Save EBP */

"Movl%%esp,%0\n\t"/*save ESP */

"Movl%2,%%esp\n\t"/* Restore ESP */

"Movl $1f,%1\n\t"/* Save EIP */

"Pushl%3\n\t"

"Ret\n\t"/* Restore EIP */

"1:\t"/* Next process start here */

"Popl%%ebp\n\t"

: "=m" (PREV->THREAD.SP), "=m" (PREV->THREAD.IP)

: "M" (NEXT->THREAD.SP), "M" (NEXT->THREAD.IP)

);

My_current_task = Next;

PRINTK (kern_notice ">>>switch%d to%d<<<\n", prev->pid,next->pid);

}

Else

{

next->state = 0;

My_current_task = Next;

PRINTK (kern_notice ">>>switch%d to%d<<<\n", prev->pid,next->pid);

/* Switch to New process */

ASM volatile (

"PUSHL%%ebp\n\t"/* Save EBP */

"Movl%%esp,%0\n\t"/*save ESP */

"Movl%2,%%esp\n\t"/* Restore ESP */

"Movl%2,%%ebp\n\t"/* Restore EBP */

"Movl $1f,%1\n\t"/* Save EIP */

"Pushl%3\n\t"

"Ret\n\t"/* Restore EIP */

: "=m" (PREV->THREAD.SP), "=m" (PREV->THREAD.IP)

: "M" (NEXT->THREAD.SP), "M" (NEXT->THREAD.IP)

);

}

return;

}

2. Code Analysis
Here I only do the key analysis, such as the more difficult to understand the process of initialization, switching a few pieces of assembly code.
Initialization environment settings for the first process:

ASM volatile (

"Movl%1,%%esp\n\t"/* The stack value of the process is stored in the system stack */

"PUSHL%1\n\t"/* Put the current EBP register value in the stack */

"PUSHL%0\n\t"/* Put the current process's EIP into the stack */

The "ret\n\t"/*ret command just lets the process EIP in the stack be saved in the EIP register */

"Popl%%ebp\n\t"

:

: "C" (Task[pid].thread.ip), "D" (TASK[PID].THREAD.SP)

);

Process Dispatch Code:

if (next->state = = 0)/*next->state = = 0 corresponding process the next corresponding process has been executed */

{//row process dispatch key code

ASM volatile (

"Pushl%%ebp\n\t"/* Save the current EBP to the stack */

"Movl%%esp,%0\n\t"/* Save the current process stack pointer to the current process TCB */

"Movl%2,%%esp\n\t"/* Saves the ESP value of the next process to the ESP register */

"Movl $1f,%1\n\t"/* Saves the EIP value of the current process and will be executed at 1 after the next recovery process */

"PUSHL%3\n\t"/* Save the new EIP in the stack */

"Ret\n\t"/* Save EIP to EIP Register */

"1:\t"/* Next Process Execution Location */

"Popl%%ebp\n\t"/* Restore the value of EBP */

: "=m" (PREV->THREAD.SP), "=m" (PREV->THREAD.IP)

: "M" (NEXT->THREAD.SP), "M" (NEXT->THREAD.IP)

);

My_current_task = Next;

PRINTK (kern_notice ">>>switch%d to%d<<<\n", prev->pid,next->pid);

}

else/* Indicates that next the process is executed for the first time */

{

next->state = 0;

My_current_task = Next;

PRINTK (kern_notice ">>>switch%d to%d<<<\n", prev->pid,next->pid);

/* Switch to New process*/

ASM volatile (

"Pushl%%ebp\n\t"/* Save current process EBP */

"Movl%%esp,%0\n\t"/* Save current process ESP */

"Movl%2,%%esp\n\t"/* Reload esp*/

"Movl%2,%%ebp\n\t"/* Reload EBP */

"Movl$1f,%1\n\t"/* Save current EIP Register value */

"Pushl%3\n\t"/* Put the EIP of the upcoming process into the stack */

"Ret\n\t"/* Reload eip*/

: "=m" (PREV->THREAD.SP), "=m" (PREV->THREAD.IP)

: "M" (NEXT->THREAD.SP), "M" (NEXT->THREAD.IP)

);

}

3. Test




4. Summary
This trial experiment requires the implementation of multi-channel process, the focus is on the process of switching, process execution, when the time slices need to process switching, the current process execution environment needs to be saved, the next time the process is scheduled, the process needs to restore the execution environment.

How the Linux kernel analyzes how the operating system works

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.