#include <linux/mm.h>/*for get_free_page,put_page*/
#include<linux/sched.h>/*for pointer current,get_base*/
#include<linux/kernel.h>/*上次没有这个出毛病*/
unsigned long RAM[20];/*储存物理地址*/
int sys_shmget(int key)
{
if(!RAM[key])/*如果没有分配物理地址*/
{
RAM[key] = get_free_page();
}
return key;
}
void* sys_shmat(int shmid)
{
unsigned long tmp = get_base(current->ldt[1]) + current->brk;/*获得虚拟地址*/
unsigned long address = RAM[shmid];/*获得物理地址*/
put_page(address, tmp);/*将虚拟地址tmp和物理地址address建立映射*/
return current->brk;/*返回逻辑地址*/
}
#define __LIBRARY__
#include<unistd.h>
#include<stdio.h>
_syscall1(int, shmget,int,key);
_syscall1(int, shmat, int, shmid);
void producer()
{
int shmid = shmget(1);
unsigned long* firstptr = (unsigned long*)shmat(shmid);/*document how many*/
unsigned long* ptr = firstptr + 1;
int i = 0;
*firstptr = 0;
for (i = 0; i < 200; i++)
{
*ptr = i;/*生产*/
ptr++;
*firstptr = i + 1;/*记录生产个数*/
}
}
void consumer()
{
int shmid = shmget(1);
unsigned long* firstptr = (unsigned long*)shmat(shmid);/*document how many*/
unsigned long* ptr = firstptr + 1;
int i = 0;
for (; i < *firstptr; i++)
{
printf("cousume=%d\n", *(ptr + i));
}
}
int main()
{
consumer();
}
int main()
{
producer();
}
一开始producer进程退出,在执行consumer发现分配的那一页内存被释放了
怎么把物理内存和虚拟内存建立起映射关系?
把物理内存地址(页框号)放在虚拟内存所对应的页表的项中
unsigned long put_page(unsigned long page,unsigned long address)/*address:虚拟地址,page:实际地址*/
{
unsigned long tmp, *page_table;
/* NOTE !!! This uses the fact that _pg_dir=0 */
if (page < LOW_MEM || page >= HIGH_MEMORY)
printk("Trying to put page %p at %p\n",page,address);
if (mem_map[(page-LOW_MEM)>>12] != 1)
printk("mem_map disagrees with %p at %p\n",page,address);
page_table = (unsigned long *) ((address>>20) & 0xffc);/*高十位✖4->页目录项地址(从零地址开始)*/
if ((*page_table)&1)/*该页表有效*/
page_table = (unsigned long *) (0xfffff000 & *page_table);/*页表所对应物理页框号*/
else {
if (!(tmp=get_free_page()))
return 0;
*page_table = tmp|7;
page_table = (unsigned long *) tmp;
}
page_table[(address>>12) & 0x3ff] = page | 7;/*10位到20位,页号*/
/* no need for invalidate */
return page;
}