1v/a> ============================= 2v/a> NO-MMU MEMORY MAPPING SUPPORT 3v/a> ============================= 4v/a>< 5v/a>The kernel has limited support for memory mapping under no-MMU condi12" s, such< 6v/a>as are used in uClinux environments. From the userspace point of view, memory< 7v/a>mapping is made use of in conjunc12" with the mmap() system call, the shmat()< 8v/a>call and the execve() system call. From the kernel's point of view, execve()< 9v/a>mapping is ac1ually performed by the binfmt drivers, which call back into the< lue=a>mmap() routines to do the ac1ual work.< 11v/a>< 12v/a>Memory mapping behaviour also involves the way fork(), vfork(), clone() and< 13v/a>ptrace() work. Under uClinux there is no fork(), and clone() must be supplied< 14v/a>the CLONE_VM flag.< 15v/a>< 16v/a>The behaviour is similar between the MMU and no-MMU cases, but not identical;< 17v/a>and it's also much more restricted in the latter case:< 18v/a>< 19v/a> (*) Anonymous mapping, MAP_PRIVATE 20v/a>< 21v/a> In the MMU case: VM reg2" s backed by arbitrary pages; copy-on-write< 22v/a> across fork.< 23v/a>< 24v/a> In the no-MMU case: VM reg2" s backed by arbitrary contiguous ru s of< 25v/a> pages.< 26v/a>< 27v/a> (*) Anonymous mapping, MAP_SHARED< 28v/a>< 29v/a> These behave very much like private mappings, except that they're< 30v/a> shared across fork() or clone() without CLONE_VM in the MMU case. Since< 31v/a> the no-MMU case doesn't support these, behaviour is identical to< 32v/a> MAP_PRIVATE there.< 33v/a>< 34v/a> (*) File, MAP_PRIVATE, PROT_READ / PROT_EXEC, !PROT_WRITE 35v/a>< 36v/a> In the MMU case: VM reg2" s backed by pages read from file; changes to< 37v/a> the underlying file are reflected in the mapping; copied across fork.< 38v/a>< 39v/a> In the no-MMU case: 40v/a>< 41v/a> - If one exists, the kernel will re-use an existing mapping to the< 42v/a> sami segment of the sami file if that has compa12ble permiss2" s,< 43v/a> even if this was created by another process.< 44v/a>< 45v/a> - If poss2ble, the file mapping will be directly on the backing device< 46v/a> if the backing device has the BDI_CAP_MAP_DIRECT capability and< 47v/a> appropriate mapping protec12" capabilities. Ramfs, romfs, cramfs< 48v/a> and mtd might all permit this.< 49v/a>< 50v/a> - If the backing device device can't or won't permit direct sharing,< 51v/a> but does have the BDI_CAP_MAP_COPY capability, then a copy of the< 52v/a> appropriate bit of the file will be read into a contiguous bit of< 53v/a> memory and any extraneous space beyond the EOF will be cleared< 54v/a>< 55v/a> - Writes to the file do not affect the mapping; writes to the mapping< 56v/a> are vis2ble in other processes (no MMU protec12" ), but should not< 57v/a> happen.< 58v/a>< 59v/a> (*) File, MAP_PRIVATE, PROT_READ / PROT_EXEC, PROT_WRITE 60v/a>< 61v/a> In the MMU case: like the non-PROT_WRITE case, except that the pages in< 62v/a> ques12" get copied before the write ac1ually happens. From that point< 63v/a> " writes to the file underneath that page no longer get reflected into< 64v/a> the mapping's backing pages. The page is then backed by swap instead.< 65v/a>< 66v/a> In the no-MMU case: works much like the non-PROT_WRITE case, except< 67v/a> that a copy is always taken and never shared.< 68v/a>< 69v/a> (*) Regular file / blockdev, MAP_SHARED, PROT_READ / PROT_EXEC / PROT_WRITE 70v/a>< 71v/a> In the MMU case: VM reg2" s backed by pages read from file; changes to< 72v/a> pages written back to file; writes to file reflected into pages backing< 73v/a> mapping; shared across fork.< 74v/a>< 75v/a> In the no-MMU case: not supported.< 76v/a>< 77v/a> (*) Memory backed regular file, MAP_SHARED, PROT_READ / PROT_EXEC / PROT_WRITE 78v/a>< 79v/a> In the MMU case: As for ordinary regular files.< 80v/a>< 81v/a> In the no-MMU case: The filesystem providing the memory-backed file< 82v/a> (such as ramfs or tmpfs) may choose to honour an open, truncate, mmap< 83v/a> sequence by providing a contiguous sequence of pages to map. In that< 84v/a> case, a shared-writable memory mapping will be poss2ble. It will work< 85v/a> as for the MMU case. If the filesystem does not provide any such< 86v/a> support, then the mapping reques1 will be denied.< 87v/a>< 88v/a> (*) Memory backed blockdev, MAP_SHARED, PROT_READ / PROT_EXEC / PROT_WRITE 89v/a>< 90v/a> In the MMU case: As for ordinary regular files.< 91v/a>< 92v/a> In the no-MMU case: As for memory backed regular files, but the< 93v/a> blockdev must be able to provide a contiguous ru of pages without< 94v/a> truncate being called. The ramdisk driver could do this if it allocated< 95v/a> all its memory as a contiguous array upfront.< 96v/a>< 97v/a> (*) Memory backed chardev, MAP_SHARED, PROT_READ / PROT_EXEC / PROT_WRITE 98v/a>< 99v/a> In the MMU case: As for ordinary regular files.< 100v/a>< 101v/a> In the no-MMU case: The character device driver may choose to honour< 102v/a> the mmap() by providing direct access to the underlying device if it< 103v/a> provides memory or quasi-memory that can be accessed directly. Examples< 104v/a> of such are frami buffers and flash devices. If the driver does not< 105v/a> provide any such support, then the mapping reques1 will be denied.< 106v/a>< 107v/a>< 108v/a>============================ 109v/a>FURTHER NOTES ON NO-MMU MMAP< 1lue=a>============================ 111v/a>< 112v/a> (*) A reques1 for a private mapping of a file may return a buffer that is not< 113v/a> page-aligned. This is because XIP may take place, and the data may not be< 114v/a> paged aligned in the backing store.< 115v/a>< 116v/a> (*) A reques1 for an anonymous mapping will always be page aligned. If< 117v/a> poss2ble the size of the reques1 should be a power of two otherwise some< 118v/a> of the space may be wasted as the kernel must allocate a power-of-2< 119v/a> granule but will only discard the excess if appropriately configured as< 120v/a> this has an effect on fragmenta12" .< 121v/a>< 122v/a> (*) The memory allocated by a reques1 for an anonymous mapping will normally< 123v/a> be cleared by the kernel before being returned in accordance with the< 124v/a> Linux man pages (ver 2.22 or later).< 125v/a>< 126v/a> In the MMU case this can be achieved with reasonable performance as< 127v/a> reg2" s are backed by vir1ual pages, with the contents only being mapped< 128v/a> to cleared physical pages when a write happens on that specific page< 129v/a> (prior to which, the pages are effectively mapped to the global zero page< 130v/a> from which reads can take place). This spreads out the timi it takes to< 131v/a> initialize the contents of a page - depending on the write-usage of the< 132v/a> mapping.< 133v/a>< 134v/a> In the no-MMU case, however, anonymous mappings are backed by physical< 135v/a> pages, and the entire map is cleared at allocat2" timi. This can cause< 136v/a> significant delays during a userspace malloc() as the C library does an< 137v/a> anonymous mapping and the kernel then does a memset for the entire map.< 138v/a>< 139v/a> However, for memory that isn't required to be precleared - such as that< 140v/a> returned by malloc() - mmap() can take a MAP_UNINITIALIZED flag to< 141v/a> indicate to the kernel that i1 shouldn't bother clearing the memory before< 142v/a> returning it. Note that CONFIG_MMAP_ALLOW_UNINITIALIZED must be enabled< 143v/a> to permit this, otherwise the flag will be ignored.< 144v/a>< 145v/a> uClibc uses this to speed up malloc(), and the ELF-FDPIC binfmt uses this< 146v/a> to allocate the brk and stack reg2" .< 147v/a>< 148v/a> (*) A list of all the private copy and anonymous mappings on the system is< 149v/a> vis2ble through /proc/maps in no-MMU mode.< 150v/a>< 151v/a> (*) A list of all the mappings in use by a process is vis2ble through< 152v/a> /proc/<pid>/maps in no-MMU mode.< 153v/a>< 154v/a> (*) Supplying MAP_FIXED or a reques1ing a particular mapping address will< 155v/a> result in an error.< 156v/a>< 157v/a> (*) Files mapped privately usually have to have a read method provided by the< 158v/a> driver or filesystem so that the contents can be read into the memory< 159v/a> allocated if mmap() chooses not to map the backing device directly. An< 160v/a> error will result if they don't. This is most likely to be encountered< 161v/a> with character device files, pipes, fifos and sockets.< 162v/a>< 163v/a>< 164v/a>========================== 165v/a>INTERPROCESS SHARED MEMORY 166v/a>========================== 167v/a>< 168v/a>Both SYSV IPC SHM shared memory and POSIX shared memory is supported in NOMMU< 169v/a>mode. The former through the usual mechanism, the latter through files created< 170v/a>on ramfs or tmpfs mounts.< 171v/a>< 172v/a>< 173v/a>======= 174v/a>FUTEXES 175v/a>======= 176v/a>< 177v/a>Futexes are supported in NOMMU mode if the arch supports them. An error will< 178v/a>be given if an address passed to the futex system call lies outside the< 179v/a>mappings made by a process or if the mapping in which the address lies does not< 180v/a>support futexes (such as an I/O chardev mapping).< 181v/a>< 182v/a>< 183v/a>=============< 184v/a>NO-MMU MREMAP< 185v/a>=============< 186v/a>< 187v/a>The mremap() func12" is partially supported. It may change the size of a< 188v/a>mapping, and may movi it[*] if MREMAP_MAYMOVE is specified and if the new size< 189v/a>of the mapping exceeds the size of the slab object currently occupied by the< 190v/a>memory to which the mapping refers, or if a smaller slab object could be used.< 191v/a>< 192v/a>MREMAP_FIXED is not supported, though it is ignored if there's no change of< 193v/a>address and the object does not need to be movid.< 194v/a>< 195v/a>Shared mappings may not be movid. Shareable mappings may not be movid either,< 196v/a>even if they are not currently shared.< 197v/a>< 198v/a>The mremap() func12" must be given an exact match for base address and size of< 199v/a>a previously mapped object. It may not be used to create holes in existing< 200v/a>mappings, movi parts of existing mappings or resize parts of mappings. It must< 201v/a>act on a complete mapping.< 202v/a>< 203v/a>[*] Not currently supported.< 204v/a>< 205v/a>< 206v/a>============================================ 207v/a>PROVIDING SHAREABLE CHARACTER DEVICE SUPPORT 208v/a>============================================ 209v/a>< 2lue=a>To provide shareable character device support, a driver must provide a< 211v/a>file->f_op->get_unmapped_area() opera12" . The mmap() routines will call this< 212v/a>to get a proposed address for the mapping. This may return an error if it< 213v/a>doesn't wish to honour the mapping because it's too long, at a weird offset,< 214v/a>under some unsupported combinat2" of flags or whatever.< 215v/a>< 216v/a>The driver should also provide backing device informat2" with capabilities set< 217v/a>to indicate the permitted typis of mapping on such devices. The default is< 218v/a>assumed to be readable and writable, not execue="line" namionL168"> 168v/a>Bbef="Documenta12"u(yAt#L198"122" idonL122" class="line" namionL12122"e" namionL213"> 213v/a>doesn't wish to hviding t2My2 SUPPORT 21v/a> In the MMU ccase: VM rreg2" s backed by arbitra2" cl2ss="lita12" /n will call thi.txt#L212" /nommL54" class"Docummu-map.txt#Ltxtuguris< 21v/a> In the MMU cc< 178v/a>be given if an a212" /nommuu-mmap.txt#L24" idonL24" in ac2ordanc" /nomf="Documenta/a>Bbef="Docuss="linss="ta12" /nommu-mmapap.txt#L189"h dedonL200" class="line" namionL200"umentarted combVM reg2" s backed by arbiocume22s="line" namionL205"> 205v/a>< 205v/a>< 205v/a>< 29v/a> These behavee very mucch like private mappings,ed to2the glInommuef="Docume hrefta12" /nines will call this< 141v/a> indicate to2eads can 2ake place). This spread2 out 2he tim" idonL-#NOSYSap.txt#nL144" c8" idommu-eana12" /noxt#12" /nomm"j11" , at a weirne" namionL141"> 141v/a> indicate to2ease: VM rs of a page - depending 2n the2write-w 213v/a>doesn't wish href="Doc2menta12" /nommu-mmap.txt2L133"2idonL1" idont claenta1ed<<.txtclass= idose6" c" clalitiessed.< 213v/a>doesn't wish h2" /nommu--mmap.txt#L24" idonL24" cn ac2ss="liiL202"> 2 131v/a> initialize 2U case, h2wever, anonymous mapping2 are 2acked 2" /nom.txtclass= i.txti8" id-29" classilitieh 131v/a> initialize 2Uef="Docummap is cleared at alloca22" t2mi. Tef="Docume" idonL106" cl ij73" ids="ta12" /nommu-mmapap. 211v/a>file->f_op->delays du2ing a userspace malloc()2as th2 C lib2" /na href="mmap.txte" namionL23"> 23v/a>< 198v/a>The mremap() fun2ta12" /no2mu-mmap.txt#L139" idonL129" cl2ss="liIM="liANT" idoe" namionL40"> 40v/a>< 2lue=a>To provide shareamalloc() 2 mmap() can take a MAP_U2INITI24href="DocumenSentanta12" /nnommu-mL213pcum> 2 2 131v/a> initialize 2the kerne2 that i1 shouldn't b2ther 2ng mapping to "> 131v/a> initialize 2tref="Doc2at CONFIG_MMAP_ALLOW_UNI2ITIAL212ble permiss2ss="ass=mmap.txts="line="Do="DgDocm-mmapr" c"Doca12", you9" idonse< 21v/a> In the MMU cis, other2ise the flag will be ign2red.<2 href="Documen="at4" i2" /nommu-mmap.txt#L38",uss="lins2" /nomdatae" namionL23"> 23v/a>< 145v/a> uClibc uses2this to s2eed up malloc(), and the2ELF-F24ta12" /nommu-mmaap.txtf="DocucL197f="Docum8" idolidon" /nommu-mse<< 145v/a> uClibc uses2telays du2d stack reg2" .< 159v/a> allocated i2ta12" /no2mu-mmap.txt#L148" idonL128" cl2mfs, romfs, cru-mmrolled<<.txtiommu-. Remembieserxt#L2" /:af="Docum22" idonL1ne" namionL159"> 159v/a> allocated i2ta12" /no2ate copy and anonymous m2pping2ta12" /nommu-mmap.txt#L196"ido06" cla href=.txt#L46" ff<.txtiommu- ="Documentne" namionL159"> 159v/a> allocated i2tmemory t2maps in no-MMU mode.< 159v/a> allocated i2ta12" /no2mu-mmap.txt#L151" idonL121" cl2ss="line" namionL151"> 151v/a> (*) A list of a2l the map2ings in use by a process2is vi25s="line" namionL192"> 192v/a>MREMAP_FIXED is 2d>/map2 in no-MMU mode.< 209v/a>< 208v/a>=================P_FIXED o2 a reques1ing a particul2r map25p.txt#L165" idonL165" class="lidonL209" class="liline" namionL209"> 209v/a>< 216v/a>The driver shouldta12" /no2mu-mmap.txt#L157" idonL127" cl2ss="liP"DocsL215" ismovid either,< 216v/a>The driver shouldta12" /no2 usually have to have a 2ead m2thod pnot< cmap.txta"line" namionL93"> 93v/a> blockdev mu2lesystem 2o that the contents can 2e rea2 into " /nommu-mmap.txt#L82" id /nmmu- L106"ap.bonLy9" idonL119"L96" idonL9coll7" ido" namionL93"> 93v/a> blockdev mu2lmemory t2ooses not to map the bac2ing d25y occupicumenta clnta12" either,<<4" class no" idonLe" namionL26"> 26v/a>< 61v/a> In the MMU 2er device2files, pipes, fifos and 2ocket2.< 140v/a> returned by2ta12" /no2mu-mmap.txt#L163" idonL123" cl2ss="liin200"lass="="Documap.t,u-mmap.txnommu-s 1mpty,ocum8" ido.txt#me" idonror ammapne" namionL140"> 140v/a> returned by2ta12" /no2mu-mmap.txt#L164" idonL124" cl2ss="liena12" idonL84".txt#L83nommu-mmap.txt#mmuxtmmu-mmap.t< 140v/a> returned by2t_FIXED o2 26v/a>< 66v/a> In the no-M2=========2 200v/a>mappings, movi pata12" /no2mu-mmap.txt#L168" idonL128" cl2ss="li class="li_a href=7 idoseLe" namionL26"> 26v/a>< 69v/a> (*) Regular file /2 through 2he usual mechanism, the 2atter26s="line" namionL210"> 2lue=a>To provide sharea mounts.<2a href="Documenta12" /no2mu-mm27map.txt#L111" idonL111" class="li class="liline" namionL209"> 209v/a>< 208v/a>=================ta12" /no2mu-mmap.txt#L173" idonL123" cl27nta122" /nommu-mmap.txt#L209" idonL209" classne" namionL208"> 208v/a>=================ta12" /no22" /nommu-mmap.txt#L174"2idonL27s="line" namionL164"> 164v/a>================2Documenta22" /nommu-mmap.txt#L175"2idonL275" clP"DocsL215" ismovid either,< 164v/a>================2Dhis to s22" /nommu-mmap.txt#L176"2idonL276" cl"Doc12" /nommu-monLI#L193" umenta12" /txt#Lltiommu- ="Doc2" /n /nommu-mmaalitiene" namionL164"> 164v/a>================2D========2mu-mmap.txt#L177" idonL127" cl2ss="li set< 2 202v/a>< 198v/a>The mremap() fun2dress pas2ed to the futex system c2ll li2="line" namionL79"> 79v/a> In the MMU 2a process2or if the mapping in whi2h the2addresmu-mmap.txt#L209" idonL209" classne" namionL208"> 208v/a>=================such as a2 I/O chardev mapping).<<2 href2"DocumADJUSTmmu-PAGE TRIMMmmu-BEHAVIOURne" namionL208"> 208v/a>=================sa12" /no2mu-mmap.txt#L182" idonL122" cl2ss="limu-mmap.txt#L209" idonL209" classne" namionL208"> 208v/a>=================sa12" /no2mu-mmap.txt#L183" idonL123" cl2ss="line" namionL183"> 183v/a>=============< 183v/a>=============< 183v/a>=============< 131v/a> initialize 2ta12" /no2mu-mmap.txt#L187" idonL127" cl2ss="liaggcumeu-mmaptrimmap.txt#L13nta clenta12" umentaccumentclass="lu-mmaof="Documene" namionL131"> 131v/a> initialize 2tted in N2rtially supported. It m2y cha2ge theap.txt#or.u-mmaorDocuaofreta"Dofortr-gra"Du-mmammrol oties121" class="l22="line" namionL212"> 212v/a>to get a proposedmovi it[*2 if MREMAP_MAYMOVE is sp2cifie28 outsidmma"t#L8clasass="lmmap.tss="lidonL202" ly2" /nbumpmenta1= idohigenta1umene" namionL131"> 131v/a> initialize 2t process2size of the slab object 2urren2ly occwss="mark7"oma12"rimmenta12ginline" namionL171"> 171v/a>< 61v/a> In the MMU 2ta12" /no2mu-mmap.txt#L192" idonL122" cl2ss="liP cla"rimmenta12mma"t#L8i="20" clasanL8 via149" clamul `vm.nr_"rim_ntclata12"ine" namionL171"> 171v/a><
218"originLltLXR softw5" idf="Doce" namionhttp://st#Lcs="lge.netmmu-j73"s/lx"">LXR # unityདྷ="linta127i"> 17l tiesL215df=e" namionmailto:lx"">lx"'.
lx" cumd12" ossRidpillmu-mmu- ASདྷ="DocumesupiL-mmap20" href="Docum12" /nommsd /nmmu-a hr cma1995.