标题: ARM Linux 进程调度(3) [打印本页]
作者: linuxarm 时间: 2006-5-24 23:04 标题: ARM Linux 进程调度(3)
switch_mm中是进行页表的切换,即将下一个的pgd的开始物理地址放入CP15中的C2
寄存器。进程的pgd的虚拟地址存放在task_struct结构中的pgd指针中,通过
__virt_to_phys宏可以转变成成物理地址。
static inline void
switch_mm(struct mm_struct *prev, struct mm_struct *next,
struct task_struct *tsk, unsigned int cpu)
{
if (prev != next)
cpu_switch_mm(next->pgd, tsk);
}
#define cpu_switch_mm(pgd,tsk) cpu_set_pgd(__virt_to_phys((unsigned long)(pgd)
))
#define cpu_get_pgd() \
({ \
unsigned long pg; \
__asm__("mrc p15, 0, %0, c2, c0, 0" \
: "=r" (pg)); \
pg &= ~0x3fff; \
(pgd_t *)phys_to_virt(pg); \
})
switch_to()完成进程上下文的切换,通过调用汇编函数__switch_to
完成,其实现比较简单,也就是保存prev进程的上下文信息,该上下文信息由
context_save_struct结构描述,包括主要的寄存器,然后将next
的上下文信息读出,信息保存在task_struct中的thread.save中TSS_SAVE标识了thread.
save在task_struct中的位置。
/*
* Register switch for ARMv3 and ARMv4 processors
* r0 = previous, r1 = next, return previous.
* previous and next are guaranteed not to be the same.
*/
ENTRY(__switch_to)
stmfd sp!, {r4 - sl, fp, lr} @ Store most regs on
stack
mrs ip, cpsr
str ip, [sp, #-4]! @ Save cpsr_SVC
str sp, [r0, #TSS_SAVE] @ Save sp_SVC
ldr sp, [r1, #TSS_SAVE] @ Get saved sp_SVC
ldr r2, [r1, #TSS_DOMAIN]
作者: linuxarm 时间: 2006-5-24 23:04
/*
* Returns amount of memory which needs to be reserved.
*/
long ed_init(long mem_start, int mem_end)
{
int i,
ep;
short tshort,
version,
length,
s_ofs;
if (register_blkdev(EPROM_MAJOR,"ed",&ed_fops)) {
printk("EPROMDISK: Unable to get major %d.\n", EPROM_MAJOR);
return 0;
}
blk_dev[EPROM_MAJOR].request_fn = DEVICE_REQUEST;
for(i=0;i< 4) {
printk("EPROMDISK: Length (%d) Too short.\n", length);
return 0;
}
ed_length = length * 512;
sector_map = ep + 6;
sector_offset = ep + s_ofs;
printk("EPROMDISK: Version %d installed, %d bytes\n", (int)version, ed_length);
return 0;
}
int get_edisk(unsigned char *buf, int sect, int num_sect)
{
short ss, /* Sector start */
tshort;
int s; /* Sector offset */
for(s=0;s0;) {
sock = bp / EPROM_SIZE;
page = (bp % EPROM_SIZE) / EPAGE_SIZE;
offset = bp % EPAGE_SIZE;
nb = (len+offset)>EPAGE_SIZE?EPAGE_SIZE-(offset%EPAGE_SIZE):len;
cr1 = socket[sock] | ((page << 4) & 0x30) | 0x40; /* no board select for now */
cr2 = (page >> 2) & 0x03;
outb((char)cr1,CONTROL_REG1);
outb((char)cr2,CONTROL_REG2);
memcpy(buf+bofs,(char *)(EPROM_WINDOW + offset),nb);
len -= nb;
bp += nb;
bofs += nb;
}
return 0;
}
med.c代码如下:
/* med.c - make eprom disk image from ramdisk image */
#include
#include
#include
#define DISK_SIZE (6291456)
#define NUM_SECT (DISK_SIZE/512)
void write_eprom_image(FILE *fi, FILE *fo);
int main(int ac, char **av)
{
FILE *fi,
*fo;
char fin[44],
fon[44];
if (ac > 1) {
strcpy(fin,av[1]);
} else {
strcpy(fin,"hda3.ram");
}
if (ac > 2) {
strcpy(fon,av[2]);
} else {
strcpy(fon,"hda3.eprom");
}
fi = fopen(fin,"r");
fo = fopen(fon,"w");
if (fi == 0 || fo == 0) {
printf("Can't open files\n");
exit(0);
}
write_eprom_image(fi,fo);
fclose(fi);
fclose(fo);
}
void write_eprom_image(FILE *fi, FILE *fo)
{
char *ini;
char *outi; /* In and out images */
short *smap; /* Sector map */
char *sp;
char c = 0;
struct {
unsigned short version;
unsigned short blocks;
unsigned short sect_ofs;
} hdr;
int ns,
s,
i,
fs;
ini = (char *)malloc(DISK_SIZE); /* Max disk size is currently 6M */
outi = (char *)malloc(DISK_SIZE); /* Max disk size is currently 6M */
smap = (short *)malloc(NUM_SECT*sizeof(short));
if (ini == NULL || outi == NULL || smap == NULL) {
printf("Can't allocate memory \n");
exit(0);
}
if (DISK_SIZE != fread(ini,1,DISK_SIZE,fi)) {
printf("Can't read input file \n");
exit(0);
}
memcpy(outi,ini,512); /* Copy in first sector */
smap[0] = 0;
ns = 1; /* Number of sectors in outi */
for(i=1;i
参考书目:
[1]《GNU/Linux编程指南》 (美)K.Wall,M.Watson 清华大学出版社 1999
[2] 《Linux实用指南》 (美)诺顿、格蕾菲斯著 翟大昆等译 机械工业出版社 1999
[3]《嵌入式系統 -- 使用 C 与 C++》 Michael Barr 美商欧莱礼 1999
[4] 《LINUX操作指南》 本社 人民邮电出版社 1999
[5] 《Linux 实用大全》 杨文志编著 北京清华大学出版社 1999
[6] 《单片机与嵌入式系统应用》 何立民 北京航空航天大学出版社 1999
[7] 《Linux内核源代码分析》 (美)马克斯韦尔 机械工业出版社 2000
[8] 《UNIX操作系统设计与实现》 陈华瑛、李建国 电子工业出版社出版 1999
参考文献:
[1]《frambuffer howto》 Geert Uytterhoeven www.linuxdoc.org 1998
[2] 《RTAI Beginner Guide》Emanuele Bianchi www.rtai.org
[3] 《Booting Linux from EPROM》 Dave Bennett www.linuxjournal.com
[4]《ramdiskhowto》 Paul Gortmaker www.linuxdoc.org 1995
[5]《kernelhowto》 Juan-Mariano de Goyeneche www.linuxdoc.org 2000
[6] 《Embedded Linux Howto》 Sebastien Huet www.linux-embedded.com 2000
[7]《lilohowto》 m.skoric www.linuxdoc.org 2001
[8]《linux from scratch howto》 Gerard Beekmans www.linux-embedded.com 2000
[9]《glibc2howto》 Eric Green www.linux.com 1998
[10] 《Kernel Jorn》Alessandro Rubini & Georg Zezchwitz 《Linux Journal》1996
[11]《rtlinux doc》 Michael Barabanov www.rtlinux.com 2001
[12]《the linux boot disk howto》 Tom Fawcett www.linux-embedded.com 2000
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) |
Powered by Discuz! 7.0.0 |