怎么样复制linux的内核,Linux内核中memcpy和memmove函数的区别和实现

Kernel version:2.6.32

CPU architecture:ARM

•memcpy是把src指向的对象中的size个字符拷贝到dest所指向的对象中,返回指向结果对象的指针.

•memmove也是把src指向的对象中的size个字符拷贝到dest所指向的对象中,返回指向结果对象的指针,但这两个函数在处理内存区域重叠的方式不同.

注意memmove这个函数名称中有"move"这个单词,而实际上src处的数据仍然还在,并没有真的被"移动"了!这个函数名称有它的历史原因,是因为有了memcpy函数后,发现这个函数有问题,又发明了另一个没有问题的memcpy函数,但为了爆出兼容性依然保留了memcpy函数,而将新版本的memcpy函数改名为memmove函数.

内存重叠问题是指目的地址的内存空间的首地址,包含在源内存空间中,这两段内存空间有了交集,因而在使用memcpy进行内存复制操作时,这段重叠的内存空间会被破坏.这种情况在应用程序级代码中一般不会出现的,而在驱动或内核级代码中要十分小心,尽量使用memmove函数.

memcpy对内存空间有要求的,dest和src所指向的内存空间不能重叠,否则复制的数据是错误的.下面具体讲解一下这个错误是如何产生的.

如果内存空间布局入下图所示:

1bcccbd5ffabdcf3df5b1f410eb9ba80.gif

src所指向的内存空间后面部分数据被新拷贝的数据给覆盖了(也就是dest<=src+size).所以拷贝到最后,原来的数据肯定不是原来的数据,拷贝的数据也不是想要的数据,使用memcpy函数可以得到错误的结果.

再者,如果内存空间布局入下图所示:

4dc10fe37b2321cdb8919d80d29af263.gif

虽然原来的数据不再是原来的数据(dest+size>=src),但拷贝的数据是原来的数据,使用memcpy函数可以得到正确的结果.因此,在使用memcpy这个函数之前,还需要做一个判断,如果dest<=src你才能使用这个函数不过完全没有必要,你直接使用memmove函数就可以了.memmove在拷贝之前就做了一个判断,如果dest <= src,就按照memcpy的思路拷贝,如果dest>src怎么办呢,看函数,它是从后面往前拷贝,这样就能正确拷贝数据了.根据上面的分析,理解下面的代码应该是一件很容易的事情.

551 #ifndef __HAVE_ARCH_MEMCPY

552 /**

553  * memcpy - Copy one area of memory to another

554  * @dest: Where to copy to

555  * @src: Where to copy from

556  * @count: The size of the area.

557  *

558  * You should not use this function to access IO space, use memcpy_toio()

559  * or memcpy_fromio() instead.

560  */

561 void *memcpy(void *dest, const void *src, size_t count)

562 {

563        char *tmp = dest;

564        const char *s = src;

565

566        while (count--)

567                *tmp++ = *s++;

568        return dest;

569 }

570 EXPORT_SYMBOL(memcpy);

571 #endif

572

573 #ifndef __HAVE_ARCH_MEMMOVE

574 /**

575  * memmove - Copy one area of memory to another

576  * @dest: Where to copy to

577  * @src: Where to copy from

578  * @count: The size of the area.

579  *

580  * Unlike memcpy(), memmove() copes with overlapping areas.

581  */

582 void *memmove(void *dest, const void *src, size_t count)

583 {

584        char *tmp;

585        const char *s;

586

587        if (dest <= src) {

588                tmp = dest;

589                s = src;

590                while (count--)

591                        *tmp++ = *s++;

592        } else {

593                tmp = dest;

594                tmp += count;

595                s = src;

596                s += count;

597                while (count--)

598                        *--tmp = *--s;

599        }

600        return dest;

601 }

602 EXPORT_SYMBOL(memmove);

603 #endif0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值