1212#include <basics.h>
1313#include <strings.h>
1414#include <heap.h>
15+ #include <memory.h>
1516
1617#define PROCFS_MAX_FILES 32
1718
@@ -86,6 +87,59 @@ static procfs_entry_t proc_heap = {
8687 .priv = NULL
8788};
8889
90+ extern struct memory_context * limine_memory_ctx ;
91+
92+ static int proc_meminfo_read (vfs_file_t * file , uint8_t * buf , uint32_t size , void * priv ) {
93+ (void )priv ;
94+
95+ char tmp [512 ];
96+ int len = 0 ;
97+
98+ // Convert bytes to KB
99+ uint64_t kb_total = limine_memory_ctx -> total / 1024 ;
100+ uint64_t kb_free = limine_memory_ctx -> usable / 1024 ;
101+ uint64_t kb_reserved = limine_memory_ctx -> reserved / 1024 ;
102+ uint64_t kb_acpi_reclaim = limine_memory_ctx -> acpi_reclaimable / 1024 ;
103+ uint64_t kb_acpi_nvs = limine_memory_ctx -> acpi_nvs / 1024 ;
104+ uint64_t kb_bad = limine_memory_ctx -> bad / 1024 ;
105+ uint64_t kb_boot = limine_memory_ctx -> bootloader_reclaimable / 1024 ;
106+ uint64_t kb_kernel = limine_memory_ctx -> kernel_modules / 1024 ;
107+ uint64_t kb_fb = limine_memory_ctx -> framebuffer / 1024 ;
108+ uint64_t kb_unknown = limine_memory_ctx -> unknown / 1024 ;
109+
110+ // Build meminfo string like Linux
111+ len += snprintf (tmp + len , sizeof (tmp ) - len ,
112+ "MemTotal: %u kB\n"
113+ "MemFree: %u kB\n"
114+ "MemReserved: %u kB\n"
115+ "ACPI Reclaim: %u kB\n"
116+ "ACPI NVS: %u kB\n"
117+ "BadMem: %u kB\n"
118+ "Bootloader: %u kB\n"
119+ "KernelModules: %u kB\n"
120+ "Framebuffer: %u kB\n"
121+ "Unknown: %u kB\n" ,
122+ kb_total , kb_free , kb_reserved , kb_acpi_reclaim ,
123+ kb_acpi_nvs , kb_bad , kb_boot , kb_kernel , kb_fb , kb_unknown
124+ );
125+
126+ // Handle file offset for multiple reads
127+ if (file -> pos >= (uint32_t )len ) return 0 ;
128+
129+ uint32_t rem = len - file -> pos ;
130+ if (rem > size ) rem = size ;
131+
132+ memcpy (buf , tmp + file -> pos , rem );
133+ file -> pos += rem ;
134+ return rem ;
135+ }
136+
137+ static procfs_entry_t proc_meminfo = {
138+ .name = "meminfo" ,
139+ .read = proc_meminfo_read ,
140+ .write = NULL ,
141+ .priv = NULL
142+ };
89143
90144/* END */
91145
@@ -94,6 +148,7 @@ void procfs_init(void) {
94148 memset (proc_files , 0 , sizeof (proc_files ));
95149 procfs_register (& proc_stat );
96150 procfs_register (& proc_heap );
151+ procfs_register (& proc_meminfo );
97152}
98153
99154/* Register a virtual proc file */
@@ -115,30 +170,40 @@ static procfs_entry_t* procfs_find(const char* name) {
115170}
116171
117172int procfs_open (vfs_file_t * file ) {
173+ if (!file || !file -> rel_path )
174+ return -1 ;
175+
118176 procfs_entry_t * e = procfs_find (file -> rel_path );
119177 if (!e )
120- return -1 ;
178+ return -1 ; // file doesn't exist
121179
122180 file -> pos = 0 ;
123181 return 0 ;
124182}
125183
126184int procfs_read (vfs_file_t * file , uint8_t * buf , uint32_t size ) {
185+ if (!file || !file -> rel_path || !buf )
186+ return -1 ;
187+
127188 procfs_entry_t * e = procfs_find (file -> rel_path );
128- if (!e || ! e -> read )
129- return 0 ;
189+ if (!e ) return -1 ; // file not found
190+ if (! e -> read ) return -1 ; // read not supported
130191
131192 return e -> read (file , buf , size , e -> priv );
132193}
133194
134195int procfs_write (vfs_file_t * file , const uint8_t * buf , uint32_t size ) {
135- procfs_entry_t * e = procfs_find (file -> rel_path );
136- if (!e || !e -> write )
196+ if (!file || !file -> rel_path || !buf )
137197 return -1 ;
138198
199+ procfs_entry_t * e = procfs_find (file -> rel_path );
200+ if (!e ) return -1 ;
201+ if (!e -> write ) return -1 ;
202+
139203 return e -> write (file , buf , size , e -> priv );
140204}
141205
206+
142207void procfs_close (vfs_file_t * file ) {
143208 (void )file ;
144209}
0 commit comments