11/*
2- * Copyright (c) 2006-2023, RT-Thread Development Team
2+ * Copyright (c) 2006-2025 RT-Thread Development Team
33 *
44 * SPDX-License-Identifier: Apache-2.0
55 *
3535static rt_mem_obj_t dfs_get_mem_obj (struct dfs_file * file );
3636static void * dfs_mem_obj_get_file (rt_mem_obj_t mem_obj );
3737
38+ /**
39+ * @brief Perform memory mapping operation
40+ *
41+ * @param[in] lwp Pointer to the lightweight process structure
42+ * @param[in] map_vaddr Requested virtual address for mapping (may be NULL)
43+ * @param[in] map_size Size of the memory region to map
44+ * @param[in] attr Memory attributes for the mapping
45+ * @param[in] flags Memory mapping flags
46+ * @param[in] pgoffset Offset in pages from the start of the memory object
47+ * @param[in] data Pointer to the file descriptor to be mapped
48+ * @param[out] code Pointer to store the operation result code
49+ *
50+ * @return void* The mapped virtual address on success, NULL on failure
51+ *
52+ * @note This is a low-level mapping function that interacts directly with the address space manager.
53+ * The actual mapping is performed by rt_aspace_map().
54+ */
3855static void * _do_mmap (struct rt_lwp * lwp , void * map_vaddr , size_t map_size , size_t attr ,
3956 mm_flag_t flags , off_t pgoffset , void * data , rt_err_t * code )
4057{
@@ -59,6 +76,20 @@ static void *_do_mmap(struct rt_lwp *lwp, void *map_vaddr, size_t map_size, size
5976 return vaddr ;
6077}
6178
79+ /**
80+ * @brief Map data to user space address
81+ *
82+ * @param[in,out] mmap2 Pointer to memory mapping arguments structure
83+ * - Input: Contains mapping parameters (addr, length, etc.)
84+ * - Output: Contains the mapped address in ret field if successful
85+ * @param[in] data Pointer to the file descriptor to be mapped
86+ * @param[out] code Pointer to store the error code if mapping fails
87+ *
88+ * @return void* The mapped virtual address on success, NULL on failure
89+ *
90+ * @note This function performs page alignment on the mapping parameters and
91+ * converts user-space flags/attributes to kernel-space before mapping.
92+ */
6293static void * _map_data_to_uspace (struct dfs_mmap2_args * mmap2 , void * data , rt_err_t * code )
6394{
6495 size_t offset = 0 ;
@@ -89,6 +120,17 @@ static void hint_free(rt_mm_va_hint_t hint)
89120{
90121}
91122
123+ /**
124+ * @brief Handle page fault for memory mapped file
125+ *
126+ * @param[in] varea Pointer to the virtual memory area structure
127+ * @param[in,out] msg Pointer to the page fault message structure
128+ * - Input: Contains fault information (fault_vaddr, etc.)
129+ * - Output: Contains response status and mapped page address
130+ *
131+ * @note This function is called when a page fault occurs in a memory mapped file region.
132+ * It attempts to map the faulting page and updates the response accordingly.
133+ */
92134static void on_page_fault (struct rt_varea * varea , struct rt_aspace_fault_msg * msg )
93135{
94136 void * page ;
@@ -124,15 +166,33 @@ static void on_page_fault(struct rt_varea *varea, struct rt_aspace_fault_msg *ms
124166 }
125167}
126168
127- /* do pre open bushiness like inc a ref */
169+ /**
170+ * @brief Handle virtual memory area opening event
171+ *
172+ * @param[in] varea Pointer to the virtual memory area structure
173+ *
174+ * @note This function is called when a virtual memory area is opened.
175+ * It increments the reference count of the associated file and
176+ * initializes varea->data to NULL.
177+ */
128178static void on_varea_open (struct rt_varea * varea )
129179{
130180 struct dfs_file * file = dfs_mem_obj_get_file (varea -> mem_obj );
131181 varea -> data = RT_NULL ;
132182 rt_atomic_add (& (file -> ref_count ), 1 );
133183}
134184
135- /* do post close bushiness like def a ref */
185+ /**
186+ * @brief Handle virtual memory area closing event
187+ *
188+ * @param[in] varea Pointer to the virtual memory area structure
189+ *
190+ * @note This function is called when a virtual memory area is closed.
191+ * It performs cleanup operations including:
192+ * - Unmapping the file from memory
193+ * - Decrementing file reference count
194+ * - Closing and destroying file if reference count reaches zero
195+ */
136196static void on_varea_close (struct rt_varea * varea )
137197{
138198 struct dfs_file * file = dfs_mem_obj_get_file (varea -> mem_obj );
@@ -167,13 +227,35 @@ static void on_varea_close(struct rt_varea *varea)
167227 }
168228}
169229
230+ /**
231+ * @brief Get the name of the memory mapped file
232+ *
233+ * @param[in] varea Pointer to the virtual memory area structure
234+ *
235+ * @return const char* The name of the mapped file if available,
236+ * otherwise returns "file-mapper" as default name
237+ *
238+ * @note This function retrieves the file name from the dentry structure
239+ * associated with the memory mapped file.
240+ */
170241static const char * get_name (rt_varea_t varea )
171242{
172243 struct dfs_file * file = dfs_mem_obj_get_file (varea -> mem_obj );
173244
174245 return (file && file -> dentry ) ? file -> dentry -> pathname : "file-mapper" ;
175246}
176247
248+ /**
249+ * @brief Read data from memory mapped file page
250+ *
251+ * @param[in] varea Pointer to the virtual memory area structure
252+ * @param[in,out] msg Pointer to the I/O message structure
253+ * - Input: Contains read request information
254+ * - Output: Contains response status and read data
255+ *
256+ * @note This function handles page read operations for memory mapped files.
257+ * If the read size is less than page size, it zero-fills the remaining space.
258+ */
177259void page_read (struct rt_varea * varea , struct rt_aspace_io_msg * msg )
178260{
179261 rt_ubase_t ret ;
@@ -201,6 +283,17 @@ void page_read(struct rt_varea *varea, struct rt_aspace_io_msg *msg)
201283 }
202284}
203285
286+ /**
287+ * @brief Write data to memory mapped file page
288+ *
289+ * @param[in] varea Pointer to the virtual memory area structure
290+ * @param[in,out] msg Pointer to the I/O message structure
291+ * - Input: Contains write request information
292+ * - Output: Contains response status and write result
293+ *
294+ * @note This function handles page write operations for memory mapped files.
295+ * If the write size is less than page size, it zero-fills the remaining space.
296+ */
204297void page_write (struct rt_varea * varea , struct rt_aspace_io_msg * msg )
205298{
206299 rt_ubase_t ret ;
@@ -228,6 +321,20 @@ void page_write(struct rt_varea *varea, struct rt_aspace_io_msg *msg)
228321 }
229322}
230323
324+ /**
325+ * @brief Unmap pages from virtual memory area
326+ *
327+ * @param[in] varea Pointer to the virtual memory area structure
328+ * @param[in] rm_start Starting address of the range to unmap (must be page aligned)
329+ * @param[in] rm_end Ending address of the range to unmap (must be page aligned)
330+ *
331+ * @return rt_err_t Error code:
332+ * - RT_EOK: Success
333+ * - -RT_ERROR: Failure (varea not associated with a file)
334+ *
335+ * @note This function performs page-by-page unmapping.
336+ * Both rm_start and rm_end must be page-aligned (checked by RT_ASSERT).
337+ */
231338static rt_err_t unmap_pages (rt_varea_t varea , void * rm_start , void * rm_end )
232339{
233340 struct dfs_file * file = dfs_mem_obj_get_file (varea -> mem_obj );
@@ -254,6 +361,20 @@ static rt_err_t unmap_pages(rt_varea_t varea, void *rm_start, void *rm_end)
254361 return - RT_ERROR ;
255362}
256363
364+ /**
365+ * @brief Handle virtual memory area shrinking operation
366+ *
367+ * @param[in] varea Pointer to the virtual memory area structure
368+ * @param[in] new_vaddr New starting address after shrinking
369+ * @param[in] size New size of the virtual memory area
370+ *
371+ * @return rt_err_t Error code:
372+ * - RT_EOK: Success
373+ * - Other errors from unmap_pages()
374+ *
375+ * @note This function determines the range of pages to unmap based on whether
376+ * the varea is shrinking from the start or end.
377+ */
257378rt_err_t on_varea_shrink (struct rt_varea * varea , void * new_vaddr , rt_size_t size )
258379{
259380 char * varea_start = varea -> start ;
@@ -279,6 +400,17 @@ rt_err_t on_varea_shrink(struct rt_varea *varea, void *new_vaddr, rt_size_t size
279400 return unmap_pages (varea , rm_start , rm_end );
280401}
281402
403+ /**
404+ * @brief Handle virtual memory area expansion operation
405+ *
406+ * @param[in] varea Pointer to the virtual memory area structure
407+ * @param[in] new_vaddr New starting address after expansion
408+ * @param[in] size New size of the expanded virtual memory area
409+ *
410+ * @return rt_err_t returns RT_EOK (success).
411+ *
412+ * @note This function is currently not implemented.
413+ */
282414rt_err_t on_varea_expand (struct rt_varea * varea , void * new_vaddr , rt_size_t size )
283415{
284416 LOG_I ("%s varea: %p" , __func__ , varea );
@@ -289,6 +421,23 @@ rt_err_t on_varea_expand(struct rt_varea *varea, void *new_vaddr, rt_size_t size
289421 return RT_EOK ;
290422}
291423
424+ /**
425+ * @brief Handle virtual memory area splitting operation
426+ *
427+ * @param[in] existed Pointer to the existing virtual memory area to be split
428+ * @param[in] unmap_start Starting address of the range to unmap
429+ * @param[in] unmap_len Length of the range to unmap
430+ * @param[in,out] subset Pointer to the new subset virtual memory area
431+ * - Input: Contains new varea parameters
432+ * - Output: Contains initialized varea after splitting
433+ *
434+ * @return rt_err_t Error code:
435+ * - RT_EOK: Success
436+ * - -RT_ERROR: Failure (varea not associated with a file)
437+ *
438+ * @note This function splits an existing virtual memory area into two parts.
439+ * It unmaps the specified range and initializes the new subset area.
440+ */
292441rt_err_t on_varea_split (struct rt_varea * existed , void * unmap_start , rt_size_t unmap_len , struct rt_varea * subset )
293442{
294443 rt_err_t rc ;
@@ -324,6 +473,16 @@ rt_err_t on_varea_split(struct rt_varea *existed, void *unmap_start, rt_size_t u
324473 return - RT_ERROR ;
325474}
326475
476+ /**
477+ * @brief Handle virtual memory area merging operation
478+ *
479+ * @param[in] merge_to Pointer to the target virtual memory area that will receive the merge
480+ * @param[in] merge_from Pointer to the source virtual memory area to be merged
481+ *
482+ * @return rt_err_t Error code:
483+ * - RT_EOK: Success
484+ * - -RT_ERROR: Failure (varea not associated with a file)
485+ */
327486rt_err_t on_varea_merge (struct rt_varea * merge_to , struct rt_varea * merge_from )
328487{
329488 struct dfs_file * file = dfs_mem_obj_get_file (merge_from -> mem_obj );
@@ -352,6 +511,20 @@ rt_err_t on_varea_merge(struct rt_varea *merge_to, struct rt_varea *merge_from)
352511 return - RT_ERROR ;
353512}
354513
514+ /**
515+ * @brief Handle virtual memory area remapping operation
516+ *
517+ * @param[in] varea Pointer to the virtual memory area structure
518+ * @param[in] new_size New size of the virtual memory area after remapping
519+ * @param[in] flags Remapping flags (e.g., MREMAP_MAYMOVE)
520+ * @param[in] new_address New starting address after remapping (optional)
521+ *
522+ * @return void* Pointer to the new virtual memory area after remapping
523+ * - Returns RT_NULL if remapping fails
524+ *
525+ * @note This function remaps a virtual memory area to a new address or size.
526+ * It currently supports the MREMAP_MAYMOVE flag.
527+ */
355528void * on_varea_mremap (struct rt_varea * varea , rt_size_t new_size , int flags , void * new_address )
356529{
357530 void * vaddr = RT_NULL ;
@@ -384,30 +557,51 @@ void *on_varea_mremap(struct rt_varea *varea, rt_size_t new_size, int flags, voi
384557 return vaddr ;
385558}
386559
560+ /**
561+ * @brief Memory object operations structure
562+ *
563+ * Defines function pointers for various virtual memory area (varea) operations,
564+ * including memory management, page fault handling, and lifecycle callbacks.
565+ */
387566static struct rt_mem_obj _mem_obj =
388567{
389- .hint_free = hint_free ,
390- .on_page_fault = on_page_fault ,
391- .on_varea_open = on_varea_open ,
392- .on_varea_close = on_varea_close ,
393- .get_name = get_name ,
568+ .hint_free = hint_free , /* Free memory hint function */
569+ .on_page_fault = on_page_fault , /* Page fault handler */
570+ .on_varea_open = on_varea_open , /* Varea open callback */
571+ .on_varea_close = on_varea_close , /* Varea close callback */
572+ .get_name = get_name , /* Get mapped file name */
394573
395- .page_read = page_read ,
396- .page_write = page_write ,
574+ .page_read = page_read , /* Page read operation */
575+ .page_write = page_write , /* Page write operation */
397576
398- .on_varea_shrink = on_varea_shrink ,
399- .on_varea_expand = on_varea_expand ,
400- .on_varea_split = on_varea_split ,
401- .on_varea_merge = on_varea_merge ,
577+ .on_varea_shrink = on_varea_shrink , /* Varea shrink handler */
578+ .on_varea_expand = on_varea_expand , /* Varea expand handler */
579+ .on_varea_split = on_varea_split , /* Varea split handler */
580+ .on_varea_merge = on_varea_merge , /* Varea merge handler */
402581
403- .on_varea_mremap = on_varea_mremap ,
582+ .on_varea_mremap = on_varea_mremap , /* Varea remap handler */
404583};
405584
585+ /**
586+ * @brief DFS memory object structure
587+ *
588+ * Contains a standard memory object and an associated file pointer,
589+ * used to maintain the relationship between memory mappings and files.
590+ */
406591struct dfs_mem_obj {
407- struct rt_mem_obj mem_obj ;
408- void * file ;
592+ struct rt_mem_obj mem_obj ; /* Base memory object */
593+ void * file ; /* Associated file pointer */
409594};
410595
596+ /**
597+ * @brief Get or create memory mapping object for a file
598+ *
599+ * @param[in] file Pointer to the file descriptor structure
600+ *
601+ * @return rt_mem_obj_t Memory mapping object associated with the file
602+ * - Returns existing object if already created
603+ * - Creates and initializes new object if not exists
604+ */
411605static rt_mem_obj_t dfs_get_mem_obj (struct dfs_file * file )
412606{
413607 rt_mem_obj_t mobj = file -> mmap_context ;
@@ -428,13 +622,38 @@ static rt_mem_obj_t dfs_get_mem_obj(struct dfs_file *file)
428622 return mobj ;
429623}
430624
625+ /**
626+ * @brief Get the file descriptor from memory mapping object
627+ *
628+ * @param[in] mem_obj Pointer to the memory mapping object
629+ *
630+ * @return void* Pointer to the associated file descriptor structure
631+ *
632+ * @note This function uses rt_container_of macro to get the containing
633+ * dfs_mem_obj structure from its mem_obj member.
634+ */
431635static void * dfs_mem_obj_get_file (rt_mem_obj_t mem_obj )
432636{
433637 struct dfs_mem_obj * dfs_mobj ;
434638 dfs_mobj = rt_container_of (mem_obj , struct dfs_mem_obj , mem_obj );
435639 return dfs_mobj -> file ;
436640}
437641
642+ /**
643+ * @brief Map a file into memory
644+ *
645+ * @param[in] file Pointer to the file descriptor structure
646+ * @param[in,out] mmap2 Pointer to memory mapping arguments structure
647+ * - Input: Contains mapping parameters (addr, length, etc.)
648+ * - Output: Contains the mapped address in ret field if successful
649+ *
650+ * @return int Error code:
651+ * - EINVAL: Invalid parameters
652+ * - Other errors from underlying mapping operations
653+ *
654+ * @note This function creates a virtual address area in user space (lwp) for the file mapping.
655+ * The actual mapping is performed by _map_data_to_uspace().
656+ */
438657int dfs_file_mmap (struct dfs_file * file , struct dfs_mmap2_args * mmap2 )
439658{
440659 rt_err_t ret = - EINVAL ;
0 commit comments