ºìÁªLinuxÃÅ»§
Linux°ïÖú

LINUXµÄϵͳÄں˿ռäµÄ±£»¤

·¢²¼Ê±¼ä:2006-04-19 01:10:15À´Ô´:ºìÁª×÷Õß:ABC
¿´ÁËLINUX´úÂë,¸Ð¾õÆä¶ÔÄÚºËÄÚ´æµÄ±£»¤×öµÃ²»ÊǺܺÃ,»¹Óиоõ´ó¼ÒÓÐЩµØ·½Àí½â²»¶Ô(Ö÷ÒªÊÇLINUXµÄ´úÂë¿´ÆðÀ´µÄÑù×ÓºÍʵ¼ÊµÄÑù×Ó²»Ì«Ò»Ñù),ËùÒÔ̸̸ÎÒ¶ÔLINUXϵͳÄں˿ռäµÄ±£»¤ºÍÓû§¿Õ¼äÓëϵͳ¿Õ¼äÊý¾Ý´«µÝµÄ´úÂë¿´·¨.×¢ÒâÎÒ˵µÄ¶¼ÊÇI386Ìåϵ½á¹¹,±ðµÄÌåϵ½á¹¹¿ÉÒÔ¿´ÏàÓ¦µÄ´úÂë,²»¸Ò±£Ö¤½á¹ûÊÇ·ñÊÇÈçÎÒËù˵.
LINUX½¨Á¢½ø³ÌµÄʱºò½¨Á¢ÁËÁ½Ì׶ÎÃèÊö·û,ÔÚÎļþSegment.hÓÐ˵Ã÷.

#ifndef _ASM_SEGMENT_H
#define _ASM_SEGMENT_H

#define __KERNEL_CS 0x10
#define __KERNEL_DS 0x18

#define __USER_CS 0x23
#define __USER_DS 0x2B

#endif

Ò»¸öÓÃÓÚÄں˴úÂë,Ò»¸öÓÃÓÚÓû§´úÂë.ÔËÐÐÄں˴úÂëµÄʱºòÓÃÄں˵ĶÎÃèÊö·ûºÅ¾Í¿ÉÒÔÖ±½Ó·ÃÎÊÓû§¿Õ¼ä,µ«ÔËÐÐÓû§´úÂëµÄʱºòÓû§¶ÎÃèÊö·û²»ÄÜ·ÃÎÊÄں˿ռä,ÕâÊÇÓõı£»¤Ä£Ê½Ò»Ð©»úÖÆ,¾ßÌå´úÂë²»ÔÙ½éÉÜ.²»¶®µÄ¾ÍµÃ¿´¿´½éÉܱ£»¤Ä£Ê½µÄһЩÊé¼®ÁË.
ÔÚÓû§´úÂëµ÷ÓÃϵͳº¯ÊýµÄʱºò,³ÌÐò½øÈëÁËϵͳÄں˴úÂë,ÃèÊö·ûÒ²ÒѾ­Çл»µ½ÁËÄں˵ÄÃèÊö·û,Õâʱ¿ÉÒÔÖ±½Ó·ÃÎÊÓû§¿Õ¼ä»òÕßÄں˿ռ䣬Á½ÕߵIJÎÊýÊý¾Ý´«µÝÒ²ºÜ¼òµ¥£¬¿ÉÒÔÖ±½Ó¿½±´µÈ¡£µ«¿´ÁËLINUX´úÂëµÄ¶¼ÖªµÀ£¬ÏµÍ³º¯Êý´úÂëÀïÃæµÄÓû§¿Õ¼äÓëÄں˿ռä²ÎÊý´«µÝÊÇûÓÐÕâôֱ½Ó¿½±´µÄ£¬ÄÇÊÇΪʲôÄØ£¿´ó¼ÒÏëÒ»Ï룬Óû§µ÷ÓõÄһЩָÕë²ÎÊýµÈ£¬¿ÉÒÔÖ¸ÏòÄں˿ռ䣬Èç¹û²»¼ÓÒÔ¼ì²âÖ±½Ó¿½±´£¬ÄÇôÓû§¿Õ¼ä´úÂë¾Í¿ÉÒÔͨ¹ýϵͳµ÷ÓöÁдÄں˿ռäÁË£¬ÕâÏÔÈ»ÊDz»×¼ÐíµÄ¡£ËùÒÔÄں˴úÂëÀïÃæ¾Í²ÉÓÃÁËͳһµÄһЩº¯Êý£º
copy_from_user/copy_to_userºÍ__generic_copy_from_user/__gerneric_copy_to_userµÈ
£¬¶øÔÚÕâЩº¯ÊýÀïÃæʵÏÖÓû§µ÷Óô«µÝµÄÖ¸ÕëºÏ·¨ÐÔ¼ì²â£¬Óû§²ÎÊýÌṩµÄÖ¸ÕëµÈ²»ÄÜÖ¸Ïòϵͳ¿Õ¼ä£¬ÕâÑù±àдÄں˴úÂëµÄʱºòÖ»Òªµ÷ÓÃÕâЩº¯Êý¾ÍÄÜʵÏÖÁ˶ÔÄں˿ռäµÄ±£»¤£¬±àдҲ±È½Ï·½±ã¡£Õâ¾ÍÌáÐÑ´ó¼Ò×Ô¼º±àдÄں˴úÂëµÄʱºò£¬Ç§Íò²»ÒªÍ¼·½±ãÖ±½ÓÓû§¿Õ¼äÓëÄں˿ռäµÄ²ÎÊý¿½±´£¬ÆäʵÄÇЩCOPYº¯Êý²¢²»ÊÇ˵Óû§¿Õ¼äÓëÄں˿ռäÒªÔõôÇл»²ÅÄÜ¿½±´£¬ÕâµãÎÒ¿´ºÜ¶àÈ˶¼Ã»ÓÐÕæÕýµÄÀí½â¡£
ÎÒÃÇÔÙ×Ðϸ¿´¿´ÄÇЩCOPYº¯ÊýÊÇÔõôʵÏÖµÄÄں˿ռ䱣»¤ÄØ¡£Ô­À´ÊÇÔÚÿ¸ö½ø³ÌµÄ½ø³ÌÊý¾Ý½á¹¹ÀïÃæ±£´æÁËÒ»¸öÓû§¿Õ¼ä·¶Î§£¬ current->addr_limit£¬ÒòΪÄں˿ռäÔÚÓû§¿Õ¼äÉÏÃ棬ËùÒÔÖ»Òª¼òµ¥¼ì²âÓû§´«µÝ²ÎÊý·ÃÎʵĿռäÊDz»ÊÇСÓÚµÈÓÚÕâ¸ö·¶Î§¾ÍÊÇÁË¡£ÏÂÃæÊÇÏà¹ØµÄ¼¸¸öÎļþµÄÏà¹ØÄÚÈÝ£º


Îļþ uaccess.h£º
#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })

#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF)
#define USER_DS MAKE_MM_SEG(PAGE_OFFSET)

#define get_ds() (KERNEL_DS)
// È¡µÃÄں˿ռ䷶Χ YRG
#define get_fs() (current->addr_limit)
// È¡µÃÓû§¿Õ¼ä·¶Î§ YRG
#define set_fs(x) (current->addr_limit = (x))
// ÉèÖÃÓû§¿Õ¼ä·¶Î§ YRG

Îļþ processor.h £º
typedef struct {
unsigned long seg;
} mm_segment_t;

Îļþ page.h £º
include

#define __PAGE_OFFSET (PAGE_OFFSET_RAW)

#define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)

Îļþpage_offset.h£º
#include
#ifdef CONFIG_1GB
#define PAGE_OFFSET_RAW 0xC0000000
#elif defined(CONFIG_2GB)
#define PAGE_OFFSET_RAW 0x80000000
#elif defined(CONFIG_3GB)
#define PAGE_OFFSET_RAW 0x40000000
#endif
// Õâ¸öÏÔÈ»¿ÉÒÔÅäÖÃÓû§¿Õ¼äÓëϵͳ¿Õ¼ä´óС YRG

´ó¼Ò¿´ÄÇget_ds()¡¢get_fs()¡¢set_fs()µÈº¯Êý¿ÉÄܲ»ÊÇÄã¸Õ¿´µ½Ê±ÏëµÄÄÇôһ»ØÊ°ɣ¿ËûÃÇ¿´À´ºÃÏóÊÇ·ÃÎÊ»òÕßÉèÖöΣ¬ÆäʵֻÊÇ·ÃÎÊ»òÕßÉèÖÃÒ»¸ö½ø³Ì±äÁ¿°ÕÁË¡£

Äã¿´ÄÇЩCOPYº¯ÊýʹµÃ´«µÝµÄһЩ²ÎÊýÖ»ÄÜÊÇÖ¸ÏòÓû§¿Õ¼ä£¬ÄÇôÄں˴úÂë¶ÔϵͳһЩº¯ÊýµÄµ÷ÓÃÔõô°ìÄØ£¬ÒòΪÄÇʱµÄ²ÎÊý¶¼ÔÚÄں˿ռäÀïÃæѽ¡£Äã×Ðϸ¿´¿´ÉÏÃæ²»ÊÇÓиöset_fs(x)µ÷ÓÃÂð£¬ÄǾÍÊÇÉèÖÃÕâ¸öÓû§¿Õ¼äÏÞÖƵĵ÷Óã¬Ö»ÒªÁÙʱÉèÖÃÓû§¿Õ¼äÏÞÖÆΪÄں˿ռäµÄ·¶Î§£¬µ÷ÓÃÍêÁ˹ýºó»Ö¸´¾ÍÊÇÁË¡£ÄãÔÙ¿´ÏÂÃæ´úÂë¾Í¶ÔÄǼ¸¸öset_fs()µÄ×÷ÓÃÇå³þÁË°É¡£

->filename is in our kernel space

unsigned long old_fs_value = get_fs();

set_fs(get_ds()); /* after this we can access the user space data */
open(filename, O_CREAT|O_RDWR|o_EXCL, 0640);
set_fs(old_fs_value); /* restore fs... */

ºÃÁË£¬Ô­Àí½²ÍêÁË£¬´úÂë´ó¼ÒÒ²¿´Ã÷°×ÁË£¬ÎÒÃÇÔÙ¿´¿´ÕâÖÖ±à³ÌºÃ²»ºÃÄØ£¿ÆäʵÕâÖÖ±à³ÌÏÔÈ»²»ºÃ¡£ ȱµãÈçÏ£º

1¡¢»¹Ã»ÓÐÐγÉͳһµÄ±£»¤·½Ê½£¬¶ÔÄں˿ռäµÄ±£»¤²»ºÃ¡£Äں˴úÂë±à³Ì²»×¢ÒâµÄ»°¾Í¿ÉÄÜʹµÃÓû§³ÌÐòÍ»ÆÆÄں˿ռäµÄ±£»¤¡£Õâµã±àдÄں˴úÂëµÄͬ־һ¶¨µÃ×¢ÒâÓû§¿Õ¼äÓëϵͳ¿Õ¼äµÄ¿½±´Ò»¶¨µÃÓÃÄÇЩCOPYº¯Êý£¬²»Òª×Ô¼º¼òµ¥µÄÖ±½Ó¿½±´¡£

2¡¢Äں˴úÂë¶Ôϵͳº¯Êýµ÷ÓÃʱÉèÖÃÓû§¿Õ¼äÏÞÖƲ»ºÃ¡£ÕâµãÈç¹ûÉèÖÃÁËÄĸö½ø³ÌµÄÓû§¿Õ¼äÏÞÖÆ»¹Ã»ÓÐÉèÖûØÈ¥µÄʱºòÈç¹û½ø³ÌÓû§´úÂëµÃµ½ÔËÐУ¨Ó¦¸Ã²»Ì«¿ÉÄÜ°É£©ÄÇô¾ÍÍ»ÆÆÁËÄں˿ռäÏÞÖÆ¡£»¹ÓÐÈç¹ûÄں˴úÂë²»×¢ÒâÍüÁ˻ָ´Óû§¿Õ¼äÏÞÖÆÄÇôҲʹµÃÄں˿ռ䱣»¤Ê§Ð§¡£

ÆäʵÓкõİ취£¬ÊµÏÖÒ²ºÜ¼òµ¥¡£¾ÍÊÇÓÃÒ»¸öÄÚºËÈ«¾Ö±äÁ¿±£´æÓû§¿Õ¼ä·¶Î§£¬Õâ¸öÆô¶¯µÄʱºò¸ù¾ÝÅäÖüÆËãºÃ£¬Äں˵÷ÓõÄʱºò¿ÉÒԺܷ½±ãµÄÒýÓÃÕâ¸ö±äÁ¿¶ÔÓû§´úÂëµÄµ÷ÓòÎÊýʵÏÖ¼ì²â£¬ÓÃÁíÒ»¸öÄÚºËÈ«¾Ö±äÁ¿À´Çø·Ö³ÌÐòÊÇÔÚÄÚºË̬»¹ÊÇÓû§Ì¬ÔËÐУ¬Èç¹ûÔÚÄÚºË̬ÔÙµ÷ÓÃϵͳº¯Êý¾Í¿ÉÒÔ²»Óüì²âϵͳµ÷ÓõIJÎÊýÊÇÔÚÄں˿ռ仹ÊÇÓû§¿Õ¼ä¡£ÕâÑù¾Í¿ÉÒÔ±ÜÃâÐÞ¸ÄÄǸöÈ«¾Ö±äÁ¿µÄÂé·³¡£
ÎÄÕÂÆÀÂÛ

¹²ÓÐ 0 ÌõÆÀÂÛ