1
1
/*
2
- * Copyright (c) 2006-2023, RT-Thread Development Team
2
+ * Copyright (c) 2006-2025 RT-Thread Development Team
3
3
*
4
4
* SPDX-License-Identifier: Apache-2.0
5
5
*
35
35
static rt_mem_obj_t dfs_get_mem_obj (struct dfs_file * file );
36
36
static void * dfs_mem_obj_get_file (rt_mem_obj_t mem_obj );
37
37
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
+ */
38
55
static void * _do_mmap (struct rt_lwp * lwp , void * map_vaddr , size_t map_size , size_t attr ,
39
56
mm_flag_t flags , off_t pgoffset , void * data , rt_err_t * code )
40
57
{
@@ -59,6 +76,20 @@ static void *_do_mmap(struct rt_lwp *lwp, void *map_vaddr, size_t map_size, size
59
76
return vaddr ;
60
77
}
61
78
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
+ */
62
93
static void * _map_data_to_uspace (struct dfs_mmap2_args * mmap2 , void * data , rt_err_t * code )
63
94
{
64
95
size_t offset = 0 ;
@@ -89,6 +120,17 @@ static void hint_free(rt_mm_va_hint_t hint)
89
120
{
90
121
}
91
122
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
+ */
92
134
static void on_page_fault (struct rt_varea * varea , struct rt_aspace_fault_msg * msg )
93
135
{
94
136
void * page ;
@@ -124,15 +166,33 @@ static void on_page_fault(struct rt_varea *varea, struct rt_aspace_fault_msg *ms
124
166
}
125
167
}
126
168
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
+ */
128
178
static void on_varea_open (struct rt_varea * varea )
129
179
{
130
180
struct dfs_file * file = dfs_mem_obj_get_file (varea -> mem_obj );
131
181
varea -> data = RT_NULL ;
132
182
rt_atomic_add (& (file -> ref_count ), 1 );
133
183
}
134
184
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
+ */
136
196
static void on_varea_close (struct rt_varea * varea )
137
197
{
138
198
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)
167
227
}
168
228
}
169
229
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
+ */
170
241
static const char * get_name (rt_varea_t varea )
171
242
{
172
243
struct dfs_file * file = dfs_mem_obj_get_file (varea -> mem_obj );
173
244
174
245
return (file && file -> dentry ) ? file -> dentry -> pathname : "file-mapper" ;
175
246
}
176
247
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
+ */
177
259
void page_read (struct rt_varea * varea , struct rt_aspace_io_msg * msg )
178
260
{
179
261
rt_ubase_t ret ;
@@ -201,6 +283,17 @@ void page_read(struct rt_varea *varea, struct rt_aspace_io_msg *msg)
201
283
}
202
284
}
203
285
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
+ */
204
297
void page_write (struct rt_varea * varea , struct rt_aspace_io_msg * msg )
205
298
{
206
299
rt_ubase_t ret ;
@@ -228,6 +321,20 @@ void page_write(struct rt_varea *varea, struct rt_aspace_io_msg *msg)
228
321
}
229
322
}
230
323
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
+ */
231
338
static rt_err_t unmap_pages (rt_varea_t varea , void * rm_start , void * rm_end )
232
339
{
233
340
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)
254
361
return - RT_ERROR ;
255
362
}
256
363
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
+ */
257
378
rt_err_t on_varea_shrink (struct rt_varea * varea , void * new_vaddr , rt_size_t size )
258
379
{
259
380
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
279
400
return unmap_pages (varea , rm_start , rm_end );
280
401
}
281
402
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
+ */
282
414
rt_err_t on_varea_expand (struct rt_varea * varea , void * new_vaddr , rt_size_t size )
283
415
{
284
416
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
289
421
return RT_EOK ;
290
422
}
291
423
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
+ */
292
441
rt_err_t on_varea_split (struct rt_varea * existed , void * unmap_start , rt_size_t unmap_len , struct rt_varea * subset )
293
442
{
294
443
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
324
473
return - RT_ERROR ;
325
474
}
326
475
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
+ */
327
486
rt_err_t on_varea_merge (struct rt_varea * merge_to , struct rt_varea * merge_from )
328
487
{
329
488
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)
352
511
return - RT_ERROR ;
353
512
}
354
513
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
+ */
355
528
void * on_varea_mremap (struct rt_varea * varea , rt_size_t new_size , int flags , void * new_address )
356
529
{
357
530
void * vaddr = RT_NULL ;
@@ -384,30 +557,51 @@ void *on_varea_mremap(struct rt_varea *varea, rt_size_t new_size, int flags, voi
384
557
return vaddr ;
385
558
}
386
559
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
+ */
387
566
static struct rt_mem_obj _mem_obj =
388
567
{
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 */
394
573
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 */
397
576
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 */
402
581
403
- .on_varea_mremap = on_varea_mremap ,
582
+ .on_varea_mremap = on_varea_mremap , /* Varea remap handler */
404
583
};
405
584
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
+ */
406
591
struct 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 */
409
594
};
410
595
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
+ */
411
605
static rt_mem_obj_t dfs_get_mem_obj (struct dfs_file * file )
412
606
{
413
607
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)
428
622
return mobj ;
429
623
}
430
624
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
+ */
431
635
static void * dfs_mem_obj_get_file (rt_mem_obj_t mem_obj )
432
636
{
433
637
struct dfs_mem_obj * dfs_mobj ;
434
638
dfs_mobj = rt_container_of (mem_obj , struct dfs_mem_obj , mem_obj );
435
639
return dfs_mobj -> file ;
436
640
}
437
641
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
+ */
438
657
int dfs_file_mmap (struct dfs_file * file , struct dfs_mmap2_args * mmap2 )
439
658
{
440
659
rt_err_t ret = - EINVAL ;
0 commit comments