/* system.h
*I don't mean to write the whole OS kernel.I just want to put what I have
*already learned into practice.But what will it be end up looking like.
*I don't know.ALA I have some free time,I will write something.Just like
*linus once said,"Just for fun".I don't care what this small ugly codes
*will be capable of,or does it worth something.I just write it for fun,
*and for practice.
* 10 / 13 / 2010 liangtao
* E-mail:liangtao90s@gmail.com
*/
#ifndef _SYSTEM_H
#define _SYSTEM_H
#include
#ifndef __ASM__
#include
#define cli() asm("cli":::"memory");
#define sti() asm("sti":::"memory")
#define __SET_SEG(SEGMENT, val) \
asm volatile("movw %0, %%" #SEGMENT " "::"r"(val):"memory")
#define set_fs(val) __SET_SEG(fs, val)
#define set_gs(val) __SET_SEG(gs, val)
#define move_to_user_mode() \
asm volatile("movl %%esp, %%eax\n\t" \
"pushl $0x33\n\t" \
"pushl %%eax\n\t" \
"pushfl\n\t" \
"pushl $0x2b\n\t" \
"pushl $1f\n" \
"iret\n" \
"1: movw $0x33, %%ax\n\t"\
"movw %%ax, %%ds\n\t" \
"movw %%ax, %%fs\n\t" \
"movw %%ax, %%gs\n":::"ax")
struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *next);
/*
* speaking of switch_to a a newly forked process.the next-regs.eip
* should be "ret_from_fork".So, we push it's eip onto it's kernel
* mode stack, then push the param that needed by __switch_to.
* i don't know how to pass the param directly by registers.
* once i get it,i will fix it.it's a little bit awkward.
* so when in the func, add esp by 8,then return.this will
* pop out the eip.So next stop the newly forked process will be
* at is "ret_from_fork"
* !!!this seems to be too much.as i always get a little confused...-_-
*/
/*
* it seems that if we want to pass the param by the stack.
* here just push two param onto the stack and jump to __switch_to()
* won't work!!!haaa...there should be a return address on the stack
* when __switch_to() excutes,at least the compiler thinks so.
* so push whatever onto the stack.But must add esp by 4 when
* return from the __switch_to().Don't ask me why...
*/
#define switch_to(prev,next) \
asm volatile("movl %%esp, %0\n\t" \
"movl $1f, %1\n\t" \
"movl %2, %%esp\n\t" \
"pushl %3\n\t" \
"pushl %%edx\n\t" \
"pushl %%eax\n\t" \
"pushl $0\n\t" \
"jmp __switch_to\n" \
"1:" :"=m"(prev->regs.esp0), "=m"(prev->regs.eip) \
:"m"(next->regs.esp0), "m"(next->regs.eip), \
"a"(prev), "d"(next))
static inline int in_user_mode(void)
{
int cs;
asm("movw %%cs, %0":"=m"(cs));
if((cs & 3) == 3)
return 1;
else
return 0;
}
#endif
#endif
阅读(2938) | 评论(0) | 转发(0) |