Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
$B%a%b%j4IM}(B
[go: Go Back, main page]

$B%a%b%j4IM}(B

					2024$BG/(B01$B7n(B17$BF|(B
$B>pJs2J3XN`(B $B%*%Z%l!<%F%#%s%0%7%9%F%`(B II

                                       $BC^GHBg3X(B $B%7%9%F%`>pJs7O(B 
                                       $B?7>k(B $BLw(B
                                       <yas@cs.tsukuba.ac.jp>

$B$3$N%Z!<%8$O!" https://www.coins.tsukuba.ac.jp/~yas/coins/os2-2023/2024-01-17
$B$"$k$$$O!" https://www.coins.tsukuba.ac.jp/~yas/
https://www.cs.tsukuba.ac.jp/~yas/

$B"#:#F|$NBg;v$JOC(B

$B"#%a%b%j4IM}(B

$B"!L\I8(B

struct page$B$X$N%]%$%s%?$,F@$i$l$?>l9g!"%a%b%j$O3d$jEv$F$i$l$F$$$k$,!"O@(B $BM}%"%I%l%9ITL@$J$N$G!"$=$N$^$^$G$O%W%m%0%i%`$G%"%/%;%9$G$-$J$$!#O@M}%"(B $B%I%l%9$,I,MW$J$i!"(Bvoid *page_address(page)$B$r;H$C$F(B struct page$B$X$N%]%$(B $B%s%?$+$i%"%/%;%92DG=$JO@M}%"%I%l%9$rF@$k$3$H$,$G$-$k!#(B

$B

  • __free_pages(page,order)
  • free_pages(addr, order)
  • free_page(addr)
    linux-6.6.9/include/linux/gfp.h
     280:	#define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
    
     177:	struct page *__alloc_pages(gfp_t gfp, unsigned int order, int preferred_nid,
     178:	                nodemask_t *nodemask);
    
     289:	extern unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order);
     290:	extern unsigned long get_zeroed_page(gfp_t gfp_mask);
    
     302:	extern void __free_pages(struct page *page, unsigned int order);
     303:	extern void free_pages(unsigned long addr, unsigned int order);
    
     320:	#define free_page(addr) free_pages((addr), 0)
    

    $B"!(Bgfp_t gfp_mask

    __get_free_pages(), alloc_pages(), alloc_page() $B$d!"(B $B8e=R$9$k(B kmalloc() $B$G$O!"(B gfp_t $B$N%U%i%0(B(gfp_mask) $B$H$7$F!"

    linux-6.6.9/include/linux/gfp_types.h
    $B7?(B $B@bL@(B
    GFP_ATOMIC $B9bM%@hEY!#%9%j!<%WIT2D!#3d9~$_=hM}$NA0H>(B($B3d$j9~$_%O%s%I%i!"(Btop half)$B$d8eH>(B(bottom half)$B$G;H$&!#(B
    GFP_KERNEL $B%+!<%M%kMQ%a%b%jDL>o$NJ}K!!#%9%j!<%W2D!#%f!<%6!&%W%m%;%9$N%3%s%F%-%9%H$G;H$&!#(B
    GFP_NOIO $B%9%j!<%W2D!"F~=PNOIT2D!#(B
    GFP_NOFS $B%9%j!<%W2=!"F~=PNO2D!"%U%!%$%kA`:nIT2D!#%U%!%$%k%7%9%F%`$N$N%U%!%$%k%7%9%F%`$NA`:n$r3+;O$7$J$$(B)$B!#(B
    GFP_USER $B%f!<%66u4VMQ$N%a%b%j$NDL>o$NJ}K!!#%9%j!<%W2D!#(B
    GFP_HIGHUSER HIGHMEM$B%>!<%s$+$i$N3dEv$F!#%9%j!<%W2D!#(B
    GFP_DMADMA$B%>!<%s$+$i$N3dEv$F!#%G%P%$%9!&%I%i%$%PEy$,;H$&!#(B
    GFP_DMA32DMA32$B%>!<%s$+$i$N3dEv$F!#%G%P%$%9!&%I%i%$%PEy$,;H$&!#(B
    $B$3$N$h$&$J%U%i%0$,B8:_$9$k:G$b=EMW$JM}M3$O!"%9%j!<%W$9$k2DG=@-$,$"$k$+(B $B$J$$$+$N0c$$!#(B $B$=$NB>$K!"$I$N%>!<%s$+$i%a%b%j$r3d$jEv$F$k$Y$-$+$rI=$9$b$N$,$"$k!#(B

    $B"!30It%U%i%0%a%s%F!<%7%g%s(B

    $BJ*M}%U%l!<%`$N3dEv$F$H3+J|$r7+$jJV$7$F$$$/$H!"30It%U%i%0%a%s%F!<%7%g%s(B (external fragmentation) $B$,@8$8$k!#A4BN$H$7$F$O6u$-%a%b%j$OB8:_$7$F$$$k(B $B$N$K!">.$5$J%a%b%j!&%U%l!<%`$,$"$A$3$A$KJ,;6$7$F$$$F!"Bg$-$5$N%Z!<%8%U(B $B%l!<%`$,B8:_$7$J$$$?$a$K%a%b%j$,3d$jEv$F$i$l$J$$>uBV$K4Y$k!#(B

    $B"!(BBuddy$B%7%9%F%`(B

    $B!V(BBuddy $B%7%9%F%`!W$O!"(BLinux $B$G;H$o$l$F$$$k30It%U%i%0%a%s%F!<%7%g%s$r5/(B $B$3$7$K$/$$%a%b%j3dEv$F%"%k%4%j%:%`!#(B

    buddy $B$H$O!"Cg4V$N0UL#!#(B

    buddy$B$NNc(B
    0 1
    2 3
    4 5
    6 7
    0,1 2,3
    4,5 6,7
    0,1,2,3 4,5,6,7

    Buddy$B%7%9%F%`$G$N%a%b%j4IM}

  • $BMxMQ2DG=$J%a%b%j!&%V%m%C%/$N%j%9%H$r4IM}$9$k!#(B $B%j%9%H$N?t$O!"(BMAX_ORDER$B8D!#(B
  • $B3F%j%9%H$O!"(B2$B$N$Y$->h$NBg$-$5$N%a%b%j!&%V%m%C%/$rJ];}$9$k(B( 2 0, 2 1, 2 2, ..., 2 (MAX_ORDER-1), )$B!#(B
  • $B%Z!<%8%U%l!<%`$N3dEv$F(B(alloc_pages())$B$G$O!"(B $BI,MW$J:G>.$N%a%b%j!&%V%m%C%/$r3d$jEv$F$k!#(B($BBg$-$J%V%m%C%/$r29B8$9$k!#(B) 2 order $B$,M_$7$$;~$K!"(B $B$=$N%a%b%j$,$"$l$P!"$=$l$rJV$9!#(B $B$J$1$l$P!"(B2 order+1 $B$rC5$7$F!"$=$l$r(B $BH>J,$KJ,3d$7$F!"JV$9!#(B $B!J;H$o$J$+$C$?J,$O!"(B2 order $B$N%j%9%H$K$D$J$0!#!K(B
  • $B%Z!<%8%U%l!<%`$N3+J|(B(__free_pages())$B$G$O!"(B 2 order $B$N%5%$%:$N%V%m%C%/$rMxMQ2DG=$J%j%9%H$K@\B3$9$k!#(B $BF1$8Bg$-$5$N%V%m%C%/$NCf$GO"B3$7$F$$$k$b$N(B(buddy)$B$,$J$$$+$rC5$9!#(B $B$"$l$P!"7k9g$7$FBg$-$J%V%m%C%/(B(2 (order+1)) $B$K$7$F%j%9%H$K@\B3$9$k!#(B

    zone$B!
    $B?^(B1(a) Buddy$B%7%9%F%`$K$h$k6u$-%Z!<%8$N4IM}(B($BO@M}E*$J8+J}(B)

    zone$B!
    $B?^(B1(b) Buddy$B%7%9%F%`$K$h$k6u$-%Z!<%8$N4IM}(B($B@~7A$J8+J}(B)

    $B"!(BBuddy$B%7%9%F%`$N>uBV(B

    /proc/buddyinfo $B$r8+$k$H!"8=:_$N6u$-%Z!<%8$N>uBV$,J,$+$k!#(B x86-64 $B$NNc!#(B
    $ cat /proc/buddyinfo [$B
    Node 0, zone      DMA      1      1      1      1      1      1      1      0      1      1      3
    Node 0, zone    DMA32   3544   7608   4945   3129   1783    840    337    121     33      0      0
    Node 0, zone   Normal  27583   9215  14233   4512   1288    208    127     20      3      1      0
    $ []
    
    $B$3$NNc$G$O!"(BDMA $B%>!<%s$N(B 2 0 (4KB) $B$K!"(B1 $B8D!"(B2 1 (8KB) $B$K!"(B1 $B8D!"!&!&!&!"(B2 10 $B$K(B3$B8D$N6u$-$,$"$k!#(B $B30It%U%i%0%a%s%F!<%7%g%s$,5/$-$k$H!"Bg$-$J2t$,>/$J$/$J$k!#(B

    x86 (32$B%S%C%H(B)$B$NNc(B

    % cat /proc/buddyinfo [$B
    Node 0, zone      DMA      6      5      3      3      4      2      2      0      1      1      2 
    Node 0, zone   Normal    476   2577    990    354    174    104     65     34     19      1    135 
    Node 0, zone  HighMem   1416   2920   1718   1082    933    504    251    152     87     43     53 
    % []
    
    $B$3$NNc$G$O!"(BDMA $B%>!<%s$N(B 2 0 (4KB) $B$K!"(B6 $B8D!"(B 2 1 (8KB) $B$K!"(B5 $B8D!"!&!&!&!"(B2 10 $B$K(B2$B8D$N6u$-$,$"$k!#(B $B30It%U%i%0%a%s%F!<%7%g%s$,5/$-$k$H!"Bg$-$J2t$,>/$J$/$J$k!#(B

    $B"#(Bkmalloc$B$H(Bkfree

    $BJ*M}%a%b%j$O!"%Z!<%8C10L!J(B4KB$B$N%Z!<%8%U%l!<%`C10L!K$G4IM}$7$F$$$k!#(B $B$7$+$7!"%+!<%M%kFb$N%G!<%?9=B$$O!"(B4KB $B$K$T$C$?$j$O$^$i$J$$!#(B Linux $B$G%Z!<%8C10L$G$O$J$$C10L$G%a%b%j$r3NJ]!&3+J|$G$-$k$K$O!"
  • kmalloc(), kfree(): malloc(), free() $B$HN`;w$N(B API
  • $B%9%i%V!&%"%m%1!<%?(B

    $B"!(Bkmalloc()

    C$B8@8l$N%f!<%66u4V$G;H$($k%i%$%V%i%j(B malloc() $B$K;w$F$$$k!#(B
    void *kmalloc(size_t size, gfp_t flags)
    
    $B0z?t(B $B7k2L(B: $B:GDc8B!"(Bsize $BJ,$N%a%b%j$r3d$jEv$F!"$=$N@hF,$NHVCO!J%+!<%M%kFb$N2>(B $BA[%"%I%l%9!K$rJV$9!#3d$jEv$F$i$l$?%a%b%j$O!"J*M}E*$K$bO"B3$K$J$k!#3dEv(B $B$F$G$-$J$$;~$K$O!"(BNULL $B$rJV$9!#(B

    $B"!(Bkmalloc()$B$N%U%i%0$NA*Br(B

    $B>u67(B $B%U%i%0(B
    $B%W%m%;%9$N%3%s%F%-%9%H!"%9%j!<%W2DG=(B GFP_KERNEL
    $B%W%m%;%9$N%3%s%F%-%9%H!"%9%j!<%WIT2D(B GFP_ATOMIC
    $B3d9~$_%O%s%I%i(B GFP_ATOMIC
    $B3d9~$_%O%s%I%i8eH>(B(Softirq,Tasklet,$B8e=R(B) GFP_ATOMIC
    DMA$B2DG=$J%a%b%j!"%9%j!<%W2DG=(B GFP_DMA|GFP_KERNEL
    DMA$B2DG=$J%a%b%j!"%9%j!<%WIT2D(B GFP_DMA|GFP_ATOMIC

    $B"!(Bkfree()

    void kfree(const void *objp)
    
    C$B8@8l$N%f!<%66u4V$G;H$($k%i%$%V%i%j(B free() $B$H;w$F$$$k!#(B kmalloc() $B$G3d$jEv$F$?%a%b%j$r2rJ|$9$k!#(B

    $B"!(Bvmalloc()$B$H(Bvfree()

    kmallc()/kfree() $B$H;w$F$$$k$,!"3d$jEv$F$i$l$k%a%b%j$OJ*M}E*$KO"B3$7$F$$(B $B$kJ]>Z$O$J$$!#!J%+!<%M%k6u4V$N2>A[%"%I%l%9$H$7$F$OO"B3$7$F$$$k!#!K(B

    $B"#%9%i%V%"%m%1!<%?(B(slab allocator)

    $BF1$8Bg$-$5$N9=B$BN$r3d$jEv$F$k;~$K;H$&!#(B kmalloc(), kfree() $B$h$j$b!"8zN($,$h$$!#(B

    $B"!(Bfree list$BJ}<0$H$=$NLdBjE@(B

    $B9=B$BN$N3dEv$F$K$O!"(Bfree list $BJ}<0$,;H$o$l$k$3$H$b$"$k!#(B $B$3$NJ}K!$G$O!"%a%b%j$K6u$-$,$"$C$F$b!"2rJ|$G$-$k$+4JC1$K$O$o$+$i$J$$!#(B

    free list$B!
    $B?^(B? $B%U%j!<%j%9%H$NNc(B

    $B%*%V%8%'%/%H$O!"(B1$B%Z!<%8$K(B2$B8DF~$k!#(B $B%*%V%8%'%/%H$,
  • object 2
  • object 6
  • object 3
  • object 1

    free list$B!
    $B?^(B? $B%U%j!<%j%9%H$NNc(B($B%Z!<%8$r0U<1(B)

    object 2 $B$H(B object 3 $B$NItJ,$O!"(B1$B%Z!<%86u$$$F$$$k!#(B

    $B"!%9%i%V!&%"%m%1!<%?$NL\I8(B

    $B%9%i%V!&%"%m%1!<%?<+?H$O!"(Balloc_pages() $BEy$N%Z!<%8C10L$N%a%b%j3dEv$F(B $B5!G=$r8F=P$7$F%a%b%j$r3NJ]$9$k!#(B

    $B"!%Z!<%8!&%U%l!<%`!"%9%i%V!"%*%V%8%'%/%H$N4X78(B

    $B%Z!<%8%U%l!<%`#3$D!
    $B?^(B? $B%Z!<%8!&%U%l!<%`!"%9%i%V!"%*%V%8%'%/%H$N4X78(B

    $B"!(Bkmem_cache_create()

    struct kmem_cache *
    kmem_cache_create (const char *name, size_t size, size_t align,
            unsigned long flags, void (*ctor)(void *))
    
    $B0z?t(B $B7k2L(B: $B@.8y$7$?;~$K$O!"(Bstruct kmem_cache $B$X$N%]%$%s%?!#(B $B<:GT$9$k$H(BNULL$B!#?7$7$$%Z!<%8$,3d$jEv$F$i$l$?;~$K$O!"(Bctor $B$G(B $B;XDj$5$l$?4X?t$,8F$P$l$k!#(B

    $B"!(Bkmem_cache_destroy()

    void kmem_cache_destroy(struct kmem_cache *c)
    
    kmem_cache_create() $B$G3d$jEv$F$?(B struct kmem_cache *$B$r3+J|$9$k!#(B shutdown ($BEE8;$r@Z$kA`:n(B)$B$G8F$P$l$k$3$H$,$"$k!#(B

    $B"!(Bkmem_cache_alloc()$B$H(Bkmem_cache_free()

    void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags)
    
    void *kmem_cache_alloc_node(struct kmem_cache *cachep,gfp_t flags, int node)
    
    void kmem_cache_free(struct kmem_cache *cachep, void *b)
    
    $B@8@.$7$?(B struct kmem_cache *$B$r;H$C$F%*%V%8%'%/%H$N%a%b%j$r3d$jEv$F$k!#(B $B3d$jEv$F$?%*%V%8%'%/%H$N%a%b%j$O!"(Bkmem_cache_free()$B$G3+J|$9$k!#(B

    kmem_cache_alloc_node() $B$O!"%a%b%j!&%"%/%;%9$,IT6Q$B"!MxMQNc(B(struct cred)

    linux-6.6.9/kernel/cred.c
     603:	void __init cred_init(void)
     604:	{
     605:	        /* allocate a slab in which we can store credentials */
     606:	        cred_jar = kmem_cache_create("cred_jar", sizeof(struct cred), 0,
     607:	                        SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT, NULL);
     608:	}
    
     201:	struct cred *prepare_creds(void)
     202:	{
     203:	        struct task_struct *task = current;
     204:	        const struct cred *old;
     205:	        struct cred *new;
     206:	
     207:	        new = kmem_cache_alloc(cred_jar, GFP_KERNEL);
    ...
     213:	        old = task->cred;
     214:	        memcpy(new, old, sizeof(struct cred));
    ...
     240:	        return new;
    ...
     245:	}
    
      68:	static void put_cred_rcu(struct rcu_head *rcu)
      69:	{
      70:	        struct cred *cred = container_of(rcu, struct cred, rcu);
    ...
      89:	        kmem_cache_free(cred_jar, cred);
      90:	}
    

    $B"!(B/proc/slabinfo

    /proc/slabinfo $B$r8+$k$H!"%9%i%V%"%m%1!<%?$N>uBV$,$o$+$k!#(B

    # cat /proc/slabinfo [$B
    slabinfo - version: 2.1
    # name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
    nfs_direct_cache       0      0    352   23    2 : tunables    0    0    0 : slabdata      0      0      0
    nfs_commit_data       92     92    704   23    4 : tunables    0    0    0 : slabdata      4      4      0
    ...
    UDP                  240    240   1088   30    8 : tunables    0    0    0 : slabdata      8      8      0
    tw_sock_TCP          160    160    256   16    1 : tunables    0    0    0 : slabdata     10     10      0
    TCP                  155    240   1984   16    8 : tunables    0    0    0 : slabdata     15     15      0
    ...
    task_struct          763    784   4224    7    8 : tunables    0    0    0 : slabdata    112    112      0
    cred_jar            1588   2982    192   21    1 : tunables    0    0    0 : slabdata    142    142      0
    anon_vma           18794  19584     80   51    1 : tunables    0    0    0 : slabdata    384    384      0
    pid                 1984   1984    128   32    1 : tunables    0    0    0 : slabdata     62     62      0
    ...
    dma-kmalloc-8192       0      0   8192    4    8 : tunables    0    0    0 : slabdata      0      0      0
    dma-kmalloc-4096       0      0   4096    8    8 : tunables    0    0    0 : slabdata      0      0      0
    ...
    dma-kmalloc-16         0      0     16  256    1 : tunables    0    0    0 : slabdata      0      0      0
    dma-kmalloc-8          0      0      8  512    1 : tunables    0    0    0 : slabdata      0      0      0
    ...
    kmalloc-8192          74     88   8192    4    8 : tunables    0    0    0 : slabdata     22     22      0
    kmalloc-4096         371    392   4096    8    8 : tunables    0    0    0 : slabdata     49     49      0
    ...
    kmalloc-32         47009  48256     32  128    1 : tunables    0    0    0 : slabdata    377    377      0
    kmalloc-16        115733 117760     16  256    1 : tunables    0    0    0 : slabdata    460    460      0
    kmalloc-8          65406  68608      8  512    1 : tunables    0    0    0 : slabdata    134    134      0
    kmem_cache_node      320    320     64   64    1 : tunables    0    0    0 : slabdata      5      5      0
    kmem_cache           160    160    256   16    1 : tunables    0    0    0 : slabdata     10     10      0
    # []
    
    $B%9%i%V!&%"%m%1!<%?$K$O!"#2
  • $B@lMQ!#$?$H$($P!"(Btask_struct $B$J$i!"(Bsizeof(struct task_struct) $B$H$7$F%-%c%C%7%e$KJ]B8!#(B $BA0H>$KI=<($5$l$k!#(B
  • $BHFMQ!#$$$/$D$+$NBg$-$5$N%a%b%j!#(B8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192$B!#(B $B8eH>$N(B size-$BHV9f(B $B!#(B DMA $B$,IU$$$F$$$k$b$N$O!"(BDMA $B2DG=$J%a%b%j!#(B

    $B"#%f!<%6!&%W%m%;%9$N2>A[%a%b%j$N

    $B"!(BOS$B$K5a$a$i$l$k5!G=(B($B%*%Z%l!<%F%#%s%0%7%9%F%`(B(I)$BI|=,(B)

    • 1$BBf$N%3%s%T%e!<%?$GJ#?t$N%W%m%;%9$rAv$i$;$k(B(multiprogramming)$B!#(B
    • $B%W%m%;%9$O!"$=$l$>$lFHN)$7$?%"%I%l%96u4V$r;}$D!#B?=E(B($B2>A[(B)$B%"%I%l%96u4V(B(multiple (virtual) address spaces)
    • $B2>A[5-21(B(virtual memory)$B$r $BJ*M}%a%b%j$r8GDjD9$N%Z!<%8!&%U%l!<%`(B(page frame)$B$KJ,3d$9$k!#(B
    • $B%W%m%;%9$N2>A[%"%I%l%96u4V$O!"%Z!<%8(B(page)$B$NJB$S$KJ,3d$9$k!#(B
    • $B%Z!<%8$NBg$-$5$H%Z!<%8!&%U%l!<%`$NBg$-$5$O!"F1$8!#(B $B%Z!<%8!&%5%$%:$H8F$V!#%Z!<%8!&%5%$%:$O!"(B2$B$N$Y$->h$NBg$-$5!#(B4KB-64KB $B$,B?$$!#(B
    • $BG$0U$N%Z!<%8$O!"G$0U$N%Z!<%8!&%U%l!<%`$K%^%C%W$G$-$k!#(B
    • CPU $B$O!"%W%m%0%i%`$rA[%"%I%l%9(B(virtual address)$B$r(B $B=PNO$7$F!"5!3#8lL?Na$d%G!<%?$r%"%/%;%9$9$k!#(B
    • MMU (Memory Management Unit) $B$O!"2>A[%"%I%l%9$rJ*M}%"%I%l%9(B(physical address) $B$KJQ49$9$k!#(B
    • MMU $B$O!"%a%b%jCf$K:n$i$l$?%Z!<%8%F!<%V%k(B(page table)$B$r8+$J$,$i(B $BJQ49$9$k!#%Z!<%8%F!<%V%k$O!"2>A[%"%I%l%9$HJ*M}%"%I%l%9$NBP1~I=!#(B
    • $B$7$P$i$/;H$o$J$$%Z!<%8$NFbMF$r!"%G%#%9%/$KB`Hr$9$k(B(page out)$B!#(B
    • $B%G%#%9%/$+$iMW5a$5$l$F$$$k%Z!<%8$NFbMF$r%a%b%j$K%3%T!<$9$k!J(Bpage in$B!K(B
    • $B%Z!<%8%"%&%H$5$l$F$$$k%a%b%j$r%"%/%;%9$9$k$H!"%Z!<%8%U%)!<%k%H(B(page fault) $B$,H/@8$9$k!#(B OS$B$O!"%Z!<%8%$%s$N=hM}$r9T$$!":F3+$9$k!#(B
    • $B2>A[%"%I%l%9$NBg$-$5$O!"IaDL!"(B32$B%S%C%H$N%7%9%F%`$J$i!"(B32$B%S%C%H!#(B 64$B%S%C%H$N%7%9%F%`$J$i!"(B64$B%S%C%H!#(B
    • $BJ*M}%"%I%l%9$NBg$-$5$O!"Ek:\$7$F$$$k%a%b%j$N%5%$%:$K$h$k!#(B 32$B%S%C%H$N%7%9%F%`$G$b!"(B4GB $B0J>e$N%a%b%j$rEk:\$7$F$$$k;~$K$O!"(B 64$B%S%C%H$NJ*M}%"%I%l%9$,;H$o$l$k$3$H$,$"$k!#(B ($BJ*M}E*$JG[@~$O!"(B64$BK\$h$j>/$J$$$3$H$,$"$k!#(B)
    x86 $B$K$O!"$=$NB>!"(BMultics $BM3Mh$N!V%;%0%a%s%H!W$,$"$k!#(BLinux $BEy$NJ#?t%"!<(B $B%-%F%/%A%c$GF0:n$9$k(B OS $B$O!"(Bx86 $B0MB8$N5!G=$K$O0MB8$7$J$$7A$G@_7W$5$l$k!#(B

    $B"!(BUnix$B$K$*$1$k%a%b%j$K4X$9$k%7%9%F%`!&%3!<%k$H%i%$%V%i%j(B

    $B%7%9%F%`!&%3!<%k(B
    • execve(): $B%a%b%jCf$N%W%m%0%i%`$rF~$lBX$($k!#%"%I%l%96u4V$r:n$k!#(B
    • mmap(): $B%U%!%$%k$r%a%b%j$K%^%C%W$9$k!#(B
    • brk(), sbrk(): $B%R!<%W%a%b%j$rA}$d$9!#(B
    • mprotect(): $B%a%b%j$NJ]8n%b!<%I$rJQ99$9$k!#(B
    • mlock(): $B%a%b%j$r%Z!<%8%"%&%H$5$l$J$$$h$&$K$9$k!J(Bpinning$B!"%T%sN1$a!K(B
    • munlock(): mlock() $B$G%T%sN1$a$7$?>uBV$r2r=|$9$k!#(B
    $B%i%$%V%i%j(B
    • malloc(): $B%R!<%W$+$i%a%b%j$r3d$jEv$F$k!#(B($B86;q$O!"(Bmmap(), brk(), sbrk() $B$GF@$k!#(B)
    • free(): malloc() $B$G3d$jEv$F$?%a%b%j$r2rJ|$9$k!#(B
    $B$=$NB>(B
    • $B%9%?%C%/$N<+F03HD%!#(B($B5v$5$l$?HO0O(B(ulimit -s)$B$G(B)$B!"<+F0E*$K%9%?%C%/(B $B$rBg$-$/$9$k!#(B

    $B"!(BUnix$B$K$*$1$k%W%m%;%9$N%"%I%l%96u4V$N4pK\E*$J9=B$(B

    $B%F%-%9%H!
    $B?^(B? $B%W%m%;%9$N%"%I%l%96u4V$N9=B$(B(64$B%S%C%H(B)

    • $B%F%-%9%H!"%G!<%?!"%9%?%C%/$N#3$D$KJ,3d(B
    • $B%F%-%9%H$O!"5!3#8lL?Na$rF~$l$k!#FI$_9~$_@lMQ!#(B
    • $B%G!<%?$O!"Bg0hJQ?t!"@EE*JQ?t!"(Bmalloc() $BEy$G3NJ]$7$?%G!<%?$rCV$/!#(B3$B$D$KJ,3d!#(B
      • $B%G!<%?!#=i4|CMIU$-$NJQ?t!#(B
      • BSS$B!#=i4|CM$J$7$NJQ?t!#(BOS$B$,<+F0E*$K(B0$B$K=i4|2=!#(B
      • $B%R!<%W!#(Bmalloc() $B$G3NJ]!#(B
    • $B%9%?%C%/$K$O!"4X?t$N6I=jJQ?t(B(auto$BJQ?t!"(Bstatic $B$,IU$+$J$$$b$N(B)$B!"4X?t$N0z?t(B $B$,CV$+$l$k!#(B
    • $B%9%?%C%/$NDl$K$O!"0z?t$H4D6-JQ?t$,CV$+$l$k!#(B
    • $B%9%?%C%/$O!"9b$$HVCO$+$iDc$$HVCO$X?-$S$k!#(B
    • $B%R!<%W$O!"Dc$$HVCO$+$i9b$$HVCO$X?-$S$k!#(B
    • 0$BHVCOIU6a$O!"%a%b%j$r3d$jEv$F$J$$$3$H$,0lHLE*!#(BNULL$B%]%$%s%?$NMxMQ(B $B$G$9$0$KMn$A$k!#(B
    Linux x86 (32$B%S%C%H(B) $B$G$O!"(B32$B%S%C%H$N%"%I%l%96u4V(B 0x00000000-0xffffffff $B$N$&$A(B0xc0000000-0xffffffff $B$N4V$O!"(B $B%*%Z%l!<%F%#%s%0!&%7%9%F%`!&%+!<%M%k$,;H$&$N$G!"%f!<%66u4V$G$O;H$($J$$!#(B

    $B"! Linux $B$G$O!"

    ELF $B%U%!%$%k$O!"%X%C%@$H%;%/%7%g%s$NJB$S$+$i$J$k!#=EMW$J%;%/%7%g%s$K(B $B$O!"(B.text, .rodata, .data $B$,$"$k!#(B

    $ file hello.c [$B
    hello.c: C source, ASCII text
    $ cat hello.c [$B
    #include <stdio.h>
    int main()
    {
            printf("hello, %s!\n","world");
    }
    $ cc -o hello hello.c [$B
    $ file hello [$B
    hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked
     (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=68c4fff13c07df8738b2e
    0f20a27f9a03a20f5c1, not stripped
    $ size hello [$B
       text	   data	    bss	    dec	    hex	filename
       1234    548        4    1786     6fa	hello
    $ readelf -S hello [$B
    There are 30 section headers, starting at offset 0x1928:
    
    Section Headers:
      [Nr] Name              Type             Address           Offset
           Size              EntSize          Flags  Link  Info  Align
      [ 0]                   NULL             0000000000000000  00000000
           0000000000000000  0000000000000000           0     0     0
      [ 1] .interp           PROGBITS         0000000000400238  00000238
           000000000000001c  0000000000000000   A       0     0     1
    ...
      [13] .text             PROGBITS         0000000000400440  00000440
           0000000000000182  0000000000000000  AX       0     0     16
    ...
      [15] .rodata           PROGBITS         00000000004005d0  000005d0
           0000000000000022  0000000000000000   A       0     0     8
    ...
      [24] .data             PROGBITS         0000000000601030  00001030
           0000000000000004  0000000000000000  WA       0     0     1
      [25] .bss              NOBITS           0000000000601034  00001034
           0000000000000004  0000000000000000  WA       0     0     1
    ...
      [27] .symtab           SYMTAB           0000000000000000  00001068
           00000000000005e8  0000000000000018          28    46     8
    ...
    $ []
    

    $B"!(Bexecve() $B%7%9%F%`!&%3!<%k(B

    $B%7%9%F%`%W%m%0%i%`$N9V5A;qNA;2>H(B$B!#(B
    int execve(const char *filename, char *const argv[], char *const envp[])
    
    • filename $B$O!"IaDL!"(BELF $B7A<0Ey$N#!$B$G%$%s%?%W%j%?(B $B$r;XDj$9$k$3$H$b$G$-$k!#(B
    • argv $B$O!"(Bmain $B$N0z?t!#(B
    • envp $B$O!"4D6-JQ?t!#(B

    $B"#(BLinux$B$K$*$1$k%f!<%6%W%m%;%9$N%"%I%l%96u4V$N

    $B"!%"%I%l%96u4V$H%a%b%j!&%(%j%"(B

    $BMxMQA[%"%I%l%9(B $B$r;H$C$F5!3#8lL?Na$rFI$_=P$7$?$j!"%G!<%?$rFI$_=q$-$9$k!#(B
    • 32$B%S%C%H%7%9%F%`$G!"(B0x00000000-0xffffffff
    • 64$B%S%C%H%7%9%F%`$G!"(B0x00000000-0xffffffffffffffff ($B (x86 $B$G$O!"%;%0%a%s%F!<%7%g%s$b;H$($k$N$G!"@~7A$G$O$J$$%"%I%l%96u4V$b2D(B $BG=$@$,!"(BLinux $B$G$O!"B>$N%"!<%-%F%/%A%c$H$N7s$M9g$$$b$"$j!"@~7A$J6u4V$r(B $B;H$&!#(B)

      $B@~7A$J%"%I%l%96u4V$O!"%a%b%j!&%(%j%"(B(memory area)($B$^$?$O!"(Bmemory region$B!"(Bmemory interval)$B$KJ,3d$5$l$k!#(B

      • $B%a%b%j!&%(%j%"$K$O!"3+;OHVCO$H=*N;HVCO!J$^$?$OBg$-$5!K$,$"$k!#(B
      • $B%a%b%j!&%(%j%"Kh$KJ]8nJ}K!$rJQ$($i$l$k!#%F%-%9%H$rFI$_9~$_@lMQ(B (read-only)$B$K$9$k$J$I!#(B
      • $B%a%b%j!&%(%j%"Kh$K%U%!%$%k$KBP1~$5$;$i$l$k!#(B

      $B"!(Btask_struct$B9=B$BN$H(Bmm_struct$B9=B$BN(B

      $B%+!<%M%kFb$G$O!"%W%m%;%9(B($BC10l%9%l%C%I(B)$B$N%a%b%j$O!"
    • $B9=B$BN(B task_struct: 1$B%W%m%;%9$G(B1$B8D!#(B
    • $B9=B$BN(B mm_struct: $BIaDL!"(B1$B%W%m%;%9$G(B1$B8D!#(B($BJ#?t%W%m%;%9$G6&M-$5$l$F$$$k$3$H$,$"$k!#(B)
    • $B9=B$BN(B vm_area: 1$B%W%m%;%9$GJ#?t!#(B
    linux-6.6.9/include/linux/sched.h
     743:	struct task_struct {
    ...
     876:	        struct mm_struct                *mm;
    ...
    1554:	};
    
    tast_struct $B$N(B mm $B%U%#!<%k%I(B
    • mm_alloc() $B$G3dEv$F!#(Bexecve() $B$N=hM}$NESCf$G8F$P$l$k!#(B
    • copy_mm() $B$G%3%T!<$5$l$k!#(Bfork() $B$N=hM}$NESCf$G8F$P$l$k!#(B
    • exit_mm() $B$G8e;OKv!#(Bexit() ($B<+H/E*$J=*N;(B) $B$N=hM}$NESCf$d!"(B $B6/@)=*N;$5$;$i$l$?;~$N=hM}$G8F$P$l$k!#(B

    $B"!(Bmm_struct$B9=B$BN(B

    linux-6.6.9/include/linux/mm_types.h
     673:	struct mm_struct {
    ...
     687:	                        atomic_t mm_count;
    ...
     690:	                struct maple_tree mm_mt;
    ...
     704:	                pgd_t * pgd;
    ...
     725:	                atomic_t mm_users;
    ...
     746:	                int map_count;                  /* number of VMAs */
    ...
     765:	                struct list_head mmlist;
    ...
     809:	                unsigned long start_code, end_code, start_data, end_data;
     810:	                unsigned long start_brk, brk, start_stack;
     811:	                unsigned long arg_start, arg_end, env_start, env_end;
    ...
     927:	};
    
    • mm_mt: vm_area_struct $B$rJ];}$9$k$?$a$N(B maple_tree (B$BLZ(B)$B!#(B
    • pgd: page global drectory $B$X$N%]%$%s%?!#(B $B8e=R(B$B!#(B
    • mm_users: $B6&M-$5$l$F$$$k>l9g!"$=$N%W%m%;%9$N?t!#IaDL$O!"(B1$B!#(B
    • mm_count: $B$3$N9=B$BN$N;2>H%+%&%s%?!#(B0$B$J$i$I$N%*%V%8%'%/%H$,$b;X$5$l$F$$$J$$!#(B
    • mmlist: mm_struct $B9=B$BN$N%j%9%H$r:n$k$?$a$N%U%#!<%k%I!#(B
    • start_code, end_code: $B%F%-%9%H!&%;%0%a%s%H$N3+;OHVCO$H=*N;HVCO!#(B
    • start_brk, brk: $B%R!<%W$N3+;OHVCO$H=*N;HVCO!#(B
    • start_stack: $B%9%?%C%/$N3+;OHVCO!#(B
    • arg_start, arg_end: $B0z?t$N3+;OHVCO$H=*N;HVCO!#(B
    • env_start, env_end: $B4D6-JQ?t$N3+;OHVCO$H=*N;HVCO!#(B

    $B"!(Bvm_area_struct$B9=B$BN(B

    linux-6.6.9/include/linux/mm_types.h
     565:	struct vm_area_struct {
    ...
     571:	                        unsigned long vm_start;
     572:	                        unsigned long vm_end;
    ...
     579:	        struct mm_struct *vm_mm;        /* The address space we belong to. */
     580:	        pgprot_t vm_page_prot;          /* Access permissions of this VMA. */
    ...
     587:	                const vm_flags_t vm_flags;
    ...
     634:	        const struct vm_operations_struct *vm_ops;
    ...
     639:	        struct file * vm_file;          /* File we map to (can be NULL). */
    ...
     663:	} __randomize_layout;
    
    • vm_start, vm_end: $B%a%b%j!&%(%j%"$N3+;OHVCO$H=*N;HVCO!#(B
    • vm_mm: $B?F$N(B mm_struct $B9=B$BN$X$N%]%$%s%?(B
    • vm_page_prot: $B%Z!<%8C10L$NJ]8n%b!<%I(B(proection)$B!#(BPTE $B$G;H$&!#%O!<%I%&%'%"0MB8!#(B
    • vm_flags: $B%U%i%0!#2<$NI=;2>H!#(B
    • vm_ops: $B4X?t$X$N%]%$%s%?!#(Bops$B$O!"(Boperations$B!#(Bopen, close, unmap$B!!$r4^$`!#(B
    • vm_file: $BBP1~$7$F$$$k%U%!%$%k!#(B
    vm_area_struct$B$N(Bvm_flags$B$NCM(B(include/linux/mm.h)
    $B%U%i%0(B$B@bL@(B
    VM_READ $BFI$_9~$_2D(B
    VM_WRITE $B=q$-9~$_2D(B
    VM_EXEC $B
    VM_SHARED $B6&M-$5$l$F$$$k(B
    VM_GROWSDOWN $B%"%I%l%9$,>.$5$$J}$K?-$S$k(B
    VM_GROWSUP $B%"%I%l%9$,Bg$-$$J}$K?-$S$k(B
    VM_DENYWRITE $B=q$-9~$_IT2D!#(B
    VM_EXECUTABLE $B
    VM_LOCKED $B%m%C%/$5$l$F$$$k!#(B
    VM_DONTCOPY $B%3%T!
    VM_DONTEXPAND $B3HD%IT2D!#(B

    $B"!%W%m%;%9$N%"%I%l%96u4V$N $B%W%m%;%9$N%"%I%l%96u4V(B $B$O!"mm_struct$B!
    $B?^(B? $B%W%m%;%9$N%"%I%l%96u4V$N

    • $B3FNN0h$K$O!"(Bstruct vm_area_struct $B$,BP1~$7$F$$$k!#(B
    • $B%F%-%9%H$H%G!<%?(B($B=i4|CMIU$-(B)$B$O!"(Bvm_area_struct $B$r7PM3$7$F!" BSS$B!"%R!<%W!"%9%?%C%/$O!"%U%!%$%k$H7k$S$D$$$F$$$J$$!#:G=i$K%"%/%;(B $B%9$5$l$?;~$K!"(B0 $B$GKd$a$i$l$?%Z!<%8!&%U%l!<%`(B(anonymous page)$B$,3d$jEv$F(B $B$i$l$k!#(B
    $B3FNN0h$O!"
    $B%F%-%9%H(B
    $B5!3#8l$rCV$/!#(BVM_EXEC $BB0@-$H(B VM_READ$BB0@-$,IU$$$F$$$k!#=q$-9~$_6X;_(B $B$G6&M-2DG=!#(Bmm_struct $B$N(B start_code $B$H(B end_code $B$,!"3+;OHVCO$H=*N;HVCO(B $B$rJ];}$9$k!#(B
    $B%G!<%?(B($B=i4|CMIU$-(B)
    $B%G!<%?$rCV$/!#(BVM_READ|VM_WRITE $BB0@-$,IU$$$F$$$k(B($B0J2 BSS($B=i4|CML5$7%G!<%?(B)
    0 $B$G=i4|2=$5$l$k%G!<%?$rCV$/!#%U%!%$%k$K=i4|CM$,4^$^$l$J$$!#(B
    $B%R!<%W(B
    $B%G!<%?$rCV$/!#(Bmalloc() $B$N86;q(B($B$N#1$D(B)$B!#(Bbrk() $B$d(B sbrk() $B%7%9%F%`!&(B $B%3!<%k$GBg$-$5$,JQ99$5$l$k!#HVCO$,Bg$-$$J}$K?-$S$k!#(Bmm_struct $B$N(B start_brk $B$H(Bbrk $B$,3+;OHVCO$H=*N;HVCO$rJ];}$9$k!#(B
    $B%9%?%C%/(B
    $B4X?t8F$S=P$7$N%9%?%C%/$,CV$+$l$k!#%9%?%C%/!&%]%$%s%?$,;X$9!#6I=jJQ(B $B?t$d4X?t$NLa$jHVCO$,CV$+$l$k!#%9%?%C%/%]%$%s%?$,2<8B$r1[$($F>.$5$/$J$k(B $B$H!"<+F03HD%$5$l$k$3$H$,$"$k$k(B

    $B"!%W%m%;%9$N%"%I%l%96u4V$N%l%$%"%&%H(B($BF0E*%j%s%/%i%$%V%i%j(B)

    $B85$N$K!"F0E*%j%s%/!&%i(B $B%$%V%i%j$KM3Mh$9$k%F%-%9%H$d%G!<%?$N$?$a$N%a%b%j!&%(%j%"$,:n$i$l$k!#(B /proc/PID/maps $B$H$$$&%U%!%$%k$r8+$k$H!"$=$NMM;R$,J,$+$k!#(B
    $ echo $$ [$B
    22696
    $ ls /proc/$$ [$B
    attr		 cwd	   map_files   oom_adj	      schedstat  task
    autogroup	 environ   maps        oom_score      sessionid  timers
    auxv		 exe	   mem	       oom_score_adj  setgroups  uid_map
    cgroup		 fd	   mountinfo   pagemap	      smaps	 wchan
    clear_refs	 fdinfo    mounts      patch_state    stack
    cmdline		 gid_map   mountstats  personality    stat
    comm		 io	   net	       projid_map     statm
    coredump_filter  limits    ns	       root	      status
    cpuset		 loginuid  numa_maps   sched	      syscall
    $ cat /proc/$$/maps [$B
    00400000-004de000 r-xp 00000000 fd:00 403270428                          /usr/bin/bash
    006dd000-006de000 r--p 000dd000 fd:00 403270428                          /usr/bin/bash
    006de000-006e7000 rw-p 000de000 fd:00 403270428                          /usr/bin/bash
    006e7000-006ed000 rw-p 00000000 00:00 0
    00b7a000-00bdc000 rw-p 00000000 00:00 0                                  [heap]
    ...
    7fb437f5e000-7fb438122000 r-xp 00000000 fd:00 50035                      /usr/lib64/libc-2.17.so
    7fb438122000-7fb438321000 ---p 001c4000 fd:00 50035                      /usr/lib64/libc-2.17.so
    7fb438321000-7fb438325000 r--p 001c3000 fd:00 50035                      /usr/lib64/libc-2.17.so
    7fb438325000-7fb438327000 rw-p 001c7000 fd:00 50035                      /usr/lib64/libc-2.17.so
    
    7ffc24c64000-7ffc24c85000 rw-p 00000000 00:00 0                          [stack]
    7ffc24dce000-7ffc24dd0000 r-xp 00000000 00:00 0                          [vdso]
    ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
    $ wc /proc/$$/maps [$B
    41 239 3630 /proc/22696/maps
    $ []
    
    /proc/PID/maps $B$N%U%#!<%k%I$N0UL#(B
    1. $B%a%b%j!&%;%0%a%s%H$N3+;OHVCO$H=*N;HVCO!#(B
    2. $B%"%/%;%95v2D!#(Br(read), w(write), x(executable), p(private), s(shared)
    3. $B%*%U%;%C%H(B
    4. $B%V%m%C%/!&%G%P%$%9$N%a%8%c!l9g$K$O!"(B00:00 $B$K$J$k!#(B
    5. $B%U%!%$%k$N(Binode$BHV9f!#(B
    6. $B%U%!%$%kL>!#(B
    $B%V%m%C%/!&%G%P%$%9$K$O!"%a%8%c!$OITMW$@$,!"(B/proc/PID/maps $B$G$O!"?M4V$K$H$C$F(B $BJ,$+$j$d$9$$$h$&$K$o$6$o$6I=<($7$F$$$k!#(B

    $B%V%m%C%/!&%G%P%$%9$N%a%8%c! $ ls -l /dev/sda2 [$B brw-r----- 1 root disk 8, 2 Jan 24 12:00 /dev/sda2 $ [] $B%U%!%$%k$N(B inode $BHV9f$O!"(Bls -i $B$G$o$+$k!#(B

    $ ls -li /bin/bash /usr/lib64/libc-2.17.so [$B
    403270428 -rwxr-xr-x 1 root root  964536 Oct 27  2021 /bin/bash
        50035 -rwxr-xr-x 1 root root 2156592 Mar 23  2023 /usr/lib64/libc-2.17.so
    $ []
    

    $B"#%Z!<%8%F!<%V%k(B

    $B"!2>A[%"%I%l%9$HJ*M}%"%I%l%9(B

    • $B%a%b%j$K$O!"J*M}%"%I%l%9$,$U$i$l$F$$$k!#(B
    • $B%f!<%6!&%W%m%;%9$,A[%"%I%l%9(B(virtual address) $B$r(B $B=PNO$9$k!#(B
    • $B2>A[%"%I%l%9$N$&$A!">e0L$O!"(BMMU (MMU) $B$K$h$jJQ49$9$k!#(B
    • $B2>A[%"%I%l%9$N$&$A!"2<0L(B($B%Z!<%8%5%$%:J,(B)$B$O!"$=$N$^$^%a%b%j$KAw$i$l$k!#(B
    MMU $B$K$h$kJQ49J}K!$O!"%Z!<%8%F!<%V%k$KJ]B8$5$l$k!#(B

    CPU$B!
    $B?^(B? MMU$B$K$h$k2>A[%"%I%l%9$+$iJ*M}%"%I%l%9$X$NJQ49(B

    $B"!(B1$BCJ$N%Z!<%8!&%F!<%V%k(B

    $B2>A[%"%I%l%9$N9=@.$N(B $BNc(B$B!#(B 1$B%Z!<%8$,(B4KB (4096, 0x1000)$B$G!"2>A[%"%I%l%9$,(B32$B%S%C%H$N;~!#(B
    • p: 31..12$B%S%C%H!#%Z!<%8%F!<%V%k$N%$%s%G%C%/%9(B (20$B%S%C%H(B)
    • offset: 11..0$B!#%Z!<%8Fb%*%U%;%C%H(B (12$B%S%C%H(B)

    p(20$B%S%C%H(B)+offset
    $B?^(B? 1$BCJ$N%Z!<%8%F!<%V%k(B

    $B%Z!<%8%F!<%V%k$O!" unsigned long int page_table[0x100000]; $B$3$NG[Ns$NMWAG$O!"%Z!<%8!&%U%l!<%`$N@hF,HVCO(B($BJ*M}%"%I%l%9(B)$B!#(B

    MMU($B%O!<%I%&%'%"(B) $B$O!"$3$N%Z!<%8%F!<%V%k$r;H$C$F!"A[%"(B $B%I%l%9$+$iJ*M}%"%I%l%9$r5a$a$k!#0J2<$O!"(BMMU $B$NF0$-$r(B C $B8@8l$G@bL@$7$?$b(B $B$N!#(B

    unsigned long int physical_address( unsigned long int virtual v ) {
        unsigned long int p, page, offset;
        p = v >> 12;         // 32$BCf!">e0L(B20$B%S%C%H(B(32-12==20)$B$N
    
    
    
    

    mm_struct$B!
    $B?^(B? 1$BCJ$N%Z!<%8%F!<%V%k(B

    $BCm0U(B: $BGr$$ItJ,$O!"(B0 $B$,F~$C$F$$$k!#(B0 $B$NItJ,$O!"%Z!<%8!&%U%l!<%`$,3d$jEv(B $B$F$i$l$F$$$J$$$3$H$r0UL#$9$k!#(B0 $B$rJ];}$9$k$?$a$K$b!"%a%b%j$,I,MW$G$"$k!#(B

    page_table[] $B$O!"(B0x100000 $B8D(B == 1024 * 1024 $B8D(B == 1M $B8D$NMWAG$+$i$J$k!#(B 1$BMWAG$,(B 4 $B%P%$%H(B(32$B%S%C%H(B) $B$J$i!"(B4MB $B$N%a%b%j$,I,MW$K$J$k!#(B

    $B"!B?CJ$N%Z!<%8!&%F!<%V%k(B

    $B

    $B2>A[%"%I%l%9$N9=@.$N(B $BNc(B$B!#(B 1$B%Z!<%8$,(B4KB$B!"2>A[%"%I%l%9$,(B32$B%S%C%H$N;~$NJ,3d$NNc(B($BB>$NJ,3dJ}K!$b9M$($i(B $B$l$k(B)

    • p: 31..28$B%S%C%H!#(BPGD$B$N%$%s%G%C%/%9(B(4$B%S%C%H(B)
    • q: 27..24$B%S%C%H!#(BP4D$B$N%$%s%G%C%/%9(B(4$B%S%C%H(B)
    • r: 23..20$B%S%C%H!#(BPUD$B$N%$%s%G%C%/%9(B(4$B%S%C%H(B)
    • s: 19..16$B%S%C%H!#(BPMD$B$N%$%s%G%C%/%9(B(4$B%S%C%H(B)
    • t: 15..12$B%S%C%H!#(BPTE$B$N%$%s%G%C%/%9(B(4$B%S%C%H(B)
    • offset: 11..0$B%S%C%H!#%Z!<%8Fb%*%U%;%C%H(B(12$B%S%C%H(B)

    4+4+4+4+4+12
    $B?^(B? $B2>A[%"%I%l%9>e0L(B20$B%S%C%H$N(B5$B$D$NItJ,$X$NJ,3dNc(B

    mm_struct$B!
    $B?^(B? 5$BCJ$N%Z!<%8%F!<%V%k(B

    • PGD: Page Global Directory
    • P4D: Page (Level-4?) Directory
    • PUD: Page Upper Directory
    • PMD: Page Middle Directory
    • Page Table Entry$B$NG[Ns(B (pte $B$NG[Ns(B)
    unsigned int pgd[0x10];
    
    unsigned long int physical_address( unsigned long int virtual v ) {
        unsigned int *pud, *p4d, *pmd, *pte, p, q, r, s, t, page, offset;
        p = v >>  (32-4) ;
        q = (v >> (32-8)) & 0xf;
        r = (v >> (32-12)) & 0xf;
        s = (v >> (32-16)) & 0xf;
        t = (v >> (32-20)) & 0xf;
        offset = v & 0xfff;
        p4d = pgd[p];
        pud = p4d[q];
        pmd = pud[r];
        pte = pmd[s];
        page = pte[t]
        return( page + offset );
    }
    

    $B"!(Bx86$B$N%Z!<%8!&%F!<%V%k(B

    x86 $B$G$O!"=>Mh!"(B2$BCJ$N%Z!<%8%F!<%V%k$rMQ$$$F$$$k!#
  • p $B$,(B 10 $B%S%C%H(B (31..22$B%S%C%H(B)
  • q $B$,(B 0 $B%S%C%H(B
  • r $B$,(B 0 $B%S%C%H(B
  • s $B$,(B 0 $B%S%C%H(B
  • t $B$,(B 10 $B%S%C%H(B (21..12$B%S%C%H(B)
  • offset $B$,(B 12 $B%S%C%H(B (11..0$B%S%C%H(B)

    10+10+12
    $B?^(B? $B2>A[%"%I%l%90L(B20$B%S%C%H$N(B2$B$D$NItJ,$X$NJ,3dNc(B

    nl *****

    mm_struct$B!
    $B?^(B? x86$B$N(B2$BCJ$N%Z!<%8%F!<%V%k(B

    $B"!(Bx86$B$N%Z!<%8!&%F!<%V%k(B(PAE$BM-8z(B)

    x86 $B$G(B PAE$B!J(BPhysical Address Extension
    $B?^(B? x86$B$N(B2$BCJ$N%Z!<%8%F!<%V%k(B

    $B$,M-8z$N;~$K$O!"A[%"%I%l%9$O!"(B32$B%S%C%H$G$"$k$,!"J*M}%"%I%l%9$O!"(B36$B%S%C%H$^$G;H$($k$h$&$K$J$k!#(B
    • p $B$,(B 2 $B%S%C%H(B
    • q $B$,(B 9 $B%S%C%H(B
    • r $B$,(B 0 $B%S%C%H(B
    • s $B$,(B 0 $B%S%C%H(B
    • t $B$,(B 9 $B%S%C%H(B
    • offset $B$,(B 12 $B%S%C%H(B

    $B"!(Bx86_64$B$N%Z!<%8!&%F!<%V%k(B(4$B%l%Y%k(B)

    x86_64 (64$B%S%C%H(B) $B$G$O!"2>A[%"%I%l%9$H$7$F(B 48 $B%S%C%H$D$+$&!#(B $B%Z!<%8%5%$%:$O!"(B4KB$B!"%Z!<%8%F!<%V%k$NC1?t$O!"(B4 $BCJ$G$"$k!#(B
    • p $B$,(B 9 $B%S%C%H(B
    • q $B$,(B 0 $B%S%C%H(B
    • r $B$,(B 9 $B%S%C%H(B
    • s $B$,(B 9 $B%S%C%H(B
    • t $B$,(B 9 $B%S%C%H(B
    • offset $B$,(B 12 $B%S%C%H(B

    $B"!(Bx86_64$B$N%Z!<%8!&%F!<%V%k(B(5$B%l%Y%k(B)

    x86_64 (64$B%S%C%H(B) $B$G$O!"2>A[%"%I%l%9$H$7$F(B 57 $B%S%C%H$D$+$&!#(B $B%Z!<%8%5%$%:$O!"(B4KB$B!"%Z!<%8%F!<%V%k$NC1?t$O!"(B5 $BCJ$G$"$k!#(B
    • p $B$,(B 9 $B%S%C%H(B
    • q $B$,(B 9 $B%S%C%H(B
    • r $B$,(B 9 $B%S%C%H(B
    • s $B$,(B 9 $B%S%C%H(B
    • t $B$,(B 9 $B%S%C%H(B
    • offset $B$,(B 12 $B%S%C%H(B

    $B"!(BTLB (Translation Look-aside Buffer)

    ($BB?CJ$N(B)$B%Z!<%8%F!<%V%k$rKh2s$N%a%b%j!&%"%/%;%9$G$?$I$C$F$$$?$iCY$/$F$7$g(B $B$&$,$J$$!#$B"#%Z!<%8!&%U%)!<%k%H(B
  • $B%a%b%j$,3d$jEv$F$i$l$F$$$J$$>l=j$r%W%m%;%9$,%"%/%;%9$7$?;~$K$O!"%Z!<%8!&(B $B%U%)!<%k%H$,H/@8$9$k!#(B
    • $B@5$7$$%"%I%l%9$r:G=i$K%"%/%;%9$7$?>l9g(B
      • $B%Z!<%8%F!<%V%k$,$J$1$l$P:n$k!#(B
      • $B%Z!<%8!&%U%l!<%`$,3d$jEv$F$i$l$F$$$J$1$l$P!"3d$jEv$F$k!#(B
      • $B%U%!%$%k$HBP1~$7$F$$$l$P!"%U%!%$%k$+$iFbMF$rFI$_9~$`!#(B $BBP1~$7$F$$$J$1$l$P!"(B0 $B$GKd$a$k!#(B
    • $B@5$7$$%"%I%l%9$r#22sL\0J9_$K%"%/%;%9$7$?>l9g(B
      • $B%Z!<%8%$%s$N=hM}$r9T$&(B
    • $BIT@5$J%"%I%l%9$r%"%/%;%9(B
      • $B%(%i!<(B(EFAULT$BEy(B) $B$G%W%m%;%9$r=*N;$5$;$k(B
    x86 $B$G$O4X?t(B handle_page_fault() $B$,$3$N$h$&$J=hM}$r9T$&!#$3$N4X?t$O!"8"(B $B8B30$N%"%/%;%9!"$?$H$($P!"=q$-9~$_6X;_$N%a%b%j$K=q$-9~$_$r;n$_$?>l9g$N(B $B%(%i!<$b=hM}$9$k!#(B

    $B"!(Bhandle_page_fault()

    linux-6.6.9/arch/x86/include/asm/idtentry.h
     165:	#define DEFINE_IDTENTRY_RAW_ERRORCODE(func)                             \
     166:	__visible noinstr void func(struct pt_regs *regs, unsigned long error_code)
    
    linux-6.6.9/arch/x86/mm/fault.c
    1517:	DEFINE_IDTENTRY_RAW_ERRORCODE(exc_page_fault)
    1518:	{
    1519:	        unsigned long address = read_cr2();
    ...
    1561:	        handle_page_fault(regs, error_code, address);
    ...
    1565:	}
    
    1492:	static __always_inline void
    1493:	handle_page_fault(struct pt_regs *regs, unsigned long error_code,
    1494:	                              unsigned long address)
    1495:	{
    ...
    1502:	        if (unlikely(fault_in_kernel_space(address))) {
    1503:	                do_kern_addr_fault(regs, error_code, address);
    1504:	        } else {
    1505:	                do_user_addr_fault(regs, error_code, address);
    ...
    1514:	        }
    1515:	}
    
    1238:	static inline
    1239:	void do_user_addr_fault(struct pt_regs *regs,
    1240:	                        unsigned long error_code,
    1241:	                        unsigned long address)
    1242:	{
    1243:	        struct vm_area_struct *vma;
    1244:	        struct task_struct *tsk;
    1245:	        struct mm_struct *mm;
    1246:	        vm_fault_t fault;
    1247:	        unsigned int flags = FAULT_FLAG_DEFAULT;
    1248:	
    1249:	        tsk = current;
    1250:	        mm = tsk->mm;
    ...
    1356:	        vma = lock_vma_under_rcu(mm, address);
    1357:	        if (!vma)
    1358:	                goto lock_mmap;
    ...
    1364:	        fault = handle_mm_fault(vma, address, flags | FAULT_FLAG_VMA_LOCK, regs);
    ...
    1395:	        if (unlikely(access_error(error_code, vma))) {
    1396:	                bad_area_access_error(regs, error_code, address, vma);
    1397:	                return;
    1398:	        }
    ...
    1413:	        fault = handle_mm_fault(vma, address, flags, regs);
    ...
    1382:	lock_mmap:
    ..
    1385:	        vma = lock_mm_and_find_vma(mm, address, regs);
    ...
    1413:	        fault = handle_mm_fault(vma, address, flags, regs);
    ...
    1476:	}
    
    • exc_page_fault() $B$O!"(B $B%O!<%I%&%'%"0MB8$N%3!<%I!#(B arch/x86 $B$N2<$K$"$k!#(B x86 $B$G(B CPU $B$K$h$jNc30(B(exception)$B$,8!=P$5$l$?$H;~$K8F$P$l$k!#(B
    • address $B$K$O!"%Z!<%8!&%U%)!<%k%H$,@8$8$?%"%I%l%9$,4^$^$l$F$$$k!#(B x86 $B$N(B cr2 (control register 2) $B$+$i exc_page_fault() $B$O!"(Bhandle_page_fault() $B$r8F$V!#(B handle_page_fault() $B$O!"(Baddress $B$,%f!<%66u4V$NHVCO$G$"$l$P!"(B do_user_addr_fault() $B$r8F$V!#(B
    • do_user_addr_fault() $B$G$O!"$^$:(B current $B$r;2>H$7!"(B tsk $B$K8=:_ mm $B$K8=:_ Linux $B%+!<%M%k$K=P$F$/$k(B likely() $B$d(B unlikely() $B$O!"9bB.2=$N$?$a$N(B $B%R%s%H$J$N$G!"0UL#$rGD0.$9$k;~$K$OB8:_$7$J$$$b$N$H$7$F$h$$!#(B
    • lock_vma_under_rcu() $B$G!"(Bvm_area_struct $B$rC5$9!#8+$D$+$i$J$1$l$P!"(B lock_mm_and_find_vma() $B$GC5$9!#(B $B$3$l$O!"(B maple tree $B$r;H$C$F9bB.$K(B vm_area_struct $B$rC5$9!#(B
    • handle_mm_fault() $B$r8F$S!"%Z!<%8%F!<%V%k$r:n$k!#(B

    $B"!(Bhandle_mm_fault()

    mm/memory.c $B$O!"%"!<%-%F%/%A%c$+$iFHN)$7$?%3!<%I!#(B
    linux-6.6.9/include/linux/mm.h
     508:	struct vm_fault {
    ...
     552:	};
    
    linux-6.6.9/mm/memory.c
    5255:	vm_fault_t handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
    5256:	                           unsigned int flags, struct pt_regs *regs)
    5257:	{
    5258:	        /* If the fault handler drops the mmap_lock, vma may be freed */
    5259:	        struct mm_struct *mm = vma->vm_mm;
    ...
    5268:	        if (!arch_vma_access_permitted(vma, flags & FAULT_FLAG_WRITE,
    5269:	                                            flags & FAULT_FLAG_INSTRUCTION,
    5270:	                                            flags & FAULT_FLAG_REMOTE)) {
    5271:	                ret = VM_FAULT_SIGSEGV;
    5272:	                goto out;
    5273:	        }
    5274:	
    ...
    5287:	                ret = __handle_mm_fault(vma, address, flags);
    ...
    5305:	        return ret;
    5306:	}
    
    5031:	static vm_fault_t __handle_mm_fault(struct vm_area_struct *vma,
    5032:	                unsigned long address, unsigned int flags)
    5033:	{
    5034:	        struct vm_fault vmf = {
    5035:	                .vma = vma,
    5036:	                .address = address & PAGE_MASK,
    5037:	                .real_address = address,
    5038:	                .flags = flags,
    5039:	                .pgoff = linear_page_index(vma, address),
    5040:	                .gfp_mask = __get_fault_gfp_mask(vma),
    5041:	        };
    5042:	        struct mm_struct *mm = vma->vm_mm;
    5043:	        unsigned long vm_flags = vma->vm_flags;
    5044:	        pgd_t *pgd;
    5045:	        p4d_t *p4d;
    5046:	        vm_fault_t ret;
    5047:	
    5048:	        pgd = pgd_offset(mm, address);
    5049:	        p4d = p4d_alloc(mm, pgd, address);
    ...
    5053:	        vmf.pud = pud_alloc(mm, p4d, address);
    ...
    5083:	        vmf.pmd = pmd_alloc(mm, vmf.pud, address);
    ...
    5122:	        return handle_pte_fault(&vmf);
    5123:	}
    
    • $B%Z!<%8%F!<%V%k$r(B pgd, p4d, pud, pmd $B$N=g$K3d$jEv$F$F$$$/!#(B
    • $B:G8e$K(B pte $B$r(B handle_pte_fault() $B$G:n$k!#(B

    $B"!(Bhandle_pte_fault()

    linux-6.6.9/mm/memory.c
    4947:	static vm_fault_t handle_pte_fault(struct vm_fault *vmf)
    4948:	{
    ...
    4967:	                vmf->pte = pte_offset_map_nolock(vmf->vma->vm_mm, vmf->pmd,
    4968:	                                                 vmf->address, &vmf->ptl);
    ...
    4971:	                vmf->orig_pte = ptep_get_lockless(vmf->pte);
    4972:	                vmf->flags |= FAULT_FLAG_ORIG_PTE_VALID;
    ...
    4980:	        if (!vmf->pte)
    4981:	                return do_pte_missing(vmf);
    4982:	
    4983:	        if (!pte_present(vmf->orig_pte))
    4984:	                return do_swap_page(vmf);
    ...
    5023:	}
    
    3667:	static vm_fault_t do_pte_missing(struct vm_fault *vmf)
    3668:	{
    3669:	        if (vma_is_anonymous(vmf->vma))
    3670:	                return do_anonymous_page(vmf);
    3671:	        else
    3672:	                return do_fault(vmf);
    3673:	}
    
    4678:	static vm_fault_t do_fault(struct vm_fault *vmf)
    4679:	{
    4680:	        struct vm_area_struct *vma = vmf->vma;
    4681:	        struct mm_struct *vm_mm = vma->vm_mm;
    4682:	        vm_fault_t ret;
    ...
    4687:	        if (!vma->vm_ops->fault) {
    ...
    4707:	        } else if (!(vmf->flags & FAULT_FLAG_WRITE))
    4708:	                ret = do_read_fault(vmf);
    4709:	        else if (!(vma->vm_flags & VM_SHARED))
    4710:	                ret = do_cow_fault(vmf);
    4711:	        else
    4712:	                ret = do_shared_fault(vmf);
    ...
    4719:	        return ret;
    4720:	}
    
    4550:	static vm_fault_t do_read_fault(struct vm_fault *vmf)
    4551:	{
    ...
    4571:	        ret = __do_fault(vmf);
    ...
    4580:	        return ret;
    4581:	}
    
    4181:	static vm_fault_t __do_fault(struct vm_fault *vmf)
    4182:	{
    4183:	        struct vm_area_struct *vma = vmf->vma;
    4184:	        vm_fault_t ret;
    ...
    4207:	        ret = vma->vm_ops->fault(vmf);
    ...
    4234:	        return ret;
    4235:	}
    
    • pte $B$,$^$C$5$i(B($B=i$a$F%"%/%;%9$5$l$?(B)
      • do_anonymous_page() $B$G=hM}!#(B0 $B$G=i4|2=$5$l$?%Z!<%8$r3d$jEv$F$k!#(B
      • do_fault(), do_read_fault(), __do_fault() $B$G=hM}!#(B
        • vma->vm_ops->fault(vma, &vmf)$B$G=hM}!#(B ELF $B7A<0$N
      • pte $B$,$^$C$5$i$G$O$J$$(B
        • ...
        • do_swap_page() $B$G%Z!<%8%$%s!#2>A[5-21$NFs

        $B"!(Bmaple tree

        maple tree $B$O!"(BB$BLZ$N0l

        • $B%-!<$O!"(B0 $B$+$i(B ULONG_MAX $B$^$G!#%*!<%P!<%i%C%W$7$J$$!#(B
        • $BJ]B8(B: mtree_store(), mtree_store_range() $BEy!#(B
        • $B8!:w(B: mtree_load(), mt_find() $BEy!#(B
        • $B:o=|(B: mtree_erase() $B$+(B mtree_store() $B$G(B NULL $B$r(B $BJ]B8!#(B
        • struct ma_state $B$KCf4V>uBV$rJ]B8$9$k(BAPI$B$,$"$k!#(Bmas_find() $BEy!#(B
        $B0JA0$O!"@V9uLZ(B(red-black tree)$B$,;H$o$l$F$$$?=j$,!"(Bmaple tree $B$X$NCV$-49(B $B$($i$l$?!#(B $B;29M(B

        $B"!(Bmaple tree$B$G(Bvm_area_struct$B$rC5$9(B

        linux-6.6.9/mm/memory.c
        5369:	struct vm_area_struct *lock_mm_and_find_vma(struct mm_struct *mm,
        5370:	                        unsigned long addr, struct pt_regs *regs)
        5371:	{
        5372:	        struct vm_area_struct *vma;
        ...
        5377:	        vma = find_vma(mm, addr);
        ...
        5417:	        return vma;
        ...
        5422:	}
        
        linux-6.6.9/mm/mmap.c
        1872:	struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
        1873:	{
        1874:	        unsigned long index = addr;
        ...
        1877:	        return mt_find(&mm->mm_mt, &index, ULONG_MAX);
        1878:	}
        

        $B"#2]Bj(B2 $B%a%b%j4IM}(B

        $B!zLdBj(B(201) Buddy$B%7%9%F%`(B

        Buddy$B%7%9%F%`$G!"
      • 7
      • 8
      • 8,9
      • 8,9,10,11

      $B!zLdBj(B(202) kmalloc()$B$H(Bkfree()

      $B0J2<$O!"%f!<%66u4V$G%a%b%j$r3dEv$F!"MxMQ$7!"3+J|$9$k%W%m%0%i%`$N0lIt$G$"$k!#(B
      struct s1 {
         /* $B>JN,(B */
      };
      $BMxMQ(B
         struct s1 *p;
         p = malloc( sizeof(struct s1) );
         use( p );
         free( p );
      
      $B$3$N%W%m%0%i%`$r!"%+!<%M%kFb$GF0$+$9$3$H$rA[Dj$7$F(Bkmalloc() $B$H(B kfree() $B$r;H$C$F=q$-49$($J$5$$!#$?$@$7!"(Bgfp $B$N%U%i%0$H$7$F$O!"(BGFP_KERNEL $B$r;H$$$J$5$$!#(B
      $BMxMQ(B
         struct s1 *p;
         /*$B2sEz(B*/
         use( p );
         /*$B2sEz(B*/
      

      $B!zLdBj(B(203) $B%9%i%V%"%m%1!<%?(B

      $BLdBj(B(202) $B$N%W%m%0%i%`$r!"%9%i%V%"%m%1!<%?$r;H$C$F=q$-49(B $B$($J$5$$!#$9$J$o$A!"(Bkmem_cache_create()$B!"(Bkmem_cache_alloc()$B!"$*$h$S!"(B kmem_cache_free()$B$r;H$C$F=q$-49$($J$5$$!#$?$@$7!"(Bkmem_cache_create() $B$N(B $BBh(B3$B0z?t$N(Balign $B$H$7$F$O!"(B0$B$r!"Bh(B4$B0z?t$N(Bflags$B$H$7$F$O!"(BSLAB_PANIC$B!"Bh(B5$B0z(B $B?t$N%3%s%9%H%i%/%?$H$7$F$O!"(BNULL $B$r;XDj$7$J$5$$!#(B
      $B=i4|2=(B
         /*$B2sEz(B*/
      
      $BMxMQ(B
         struct s1 *p;
         /*$B2sEz(B*/
         use( p );
         /*$B2sEz(B*/
      

      $B!zLdBj(B(204) 1$BCJ$N%Z!<%8%F!<%V%k(B

      $B2>A[%"%I%l%9$N%5%$%:$,(B32$B%S%C%H!"(B1$B%Z!<%8$NBg$-$5$,(B4KB$B$H$9$k!#(B $B
    • 0x00000000 $B$+$i(B 0x00000fff $B$^$G(B
    • 0x00001000 $B$+$i(B 0x00001fff $B$^$G(B
    • 0xfffff000 $B$+$i(B 0xffffffff $B$^$G(B
    1$BCJ$N%Z!<%8%F!<%V%k(B $B$rMQ$$$F$$$?>l9g!"%Z!<%8%F!<%V%k$N7A$HFbMF$O$I$&$J$k$+!#4JC1$K?^$G=q$-$J$5$$!#(B $B$^$?!"%Z!<%8%F!<%V%k$KI,MW$J%a%b%j$O2?%P%$%H$K$J$k$+!#%Z!<%8%F!<%V%k$N(B 1$B%(%s%H%j$N%P%$%H$O!"(B4$B%P%$%H$H$9$k!#(B $B$J$*!"KvC<$N%Z!<%8!&%U%l!<%`$KI,MW$J%a%b%j(B($B$3$N>l9g$O!"(B3$B%Z!<%8!"(B12KB)$B$O!"(B $B%Z!<%8%F!<%V%k$KI,MW$J%a%b%j$G$O$J$$$N$G!"7W;;$KF~$l$J$$!#(B

    $B!zLdBj(B(205) 2$BCJ$N%Z!<%8%F!<%V%k(B

    $BLdBj(B(204) $B$G!"$B!V(Bx86$B$N%Z!<%8!&%F!<%V%k!W(B$B$HF1$8(B) $B$rMQ$$$F$$$?$H$9$k!#(B
    • 1$BCJL\(B: 31..22$B%S%C%H(B ($B>e0L(B10$B%S%C%H(B)
    • 2$BCJL\(B: 21..12$B%S%C%H(B
    • $B%*%U%;%C%H(B: $B2<0L(B12$B%S%C%H(B (11..0$B%S%C%H(B)
    $B$3$N>l9g!"%Z!<%8%F!<%V%k$N7A$HFbMF$O$I$&$J$k$+!#4JC1$K?^$G=q$-$J$5$$!#(B $B$^$?!"%Z!<%8%F!<%V%k$KI,MW$J%a%b%j$O2?%P%$%H$K$J$k$+!#%Z!<%8%F!<%V%k(B $B$N(B1$B%(%s%H%j$N%P%$%H$O!">e0L$N%Z!<%8%F!<%V%k$b2<0L$N%Z!<%8%F!<%V%k$b(B4$B%P(B $B%$%H$H$9$k!#(B
    Last updated: 2024/02/14 10:10:11
    Yasushi Shinjo / <yas@cs.tsukuba.ac.jp>