Browse Source

Allow modules to install procfs entries

K. Lange 1 year ago
parent
commit
36e9046ae8
5 changed files with 174 additions and 116 deletions
  1. 11 0
      base/usr/include/kernel/mod/procfs.h
  2. 1 1
      kernel/sys/version.c
  3. 46 0
      modules/lfbvideo.c
  4. 63 0
      modules/net.c
  5. 53 115
      modules/procfs.c

+ 11 - 0
base/usr/include/kernel/mod/procfs.h

@@ -0,0 +1,11 @@
+#pragma once
+
+#include <kernel/fs.h>
+
+struct procfs_entry {
+	int          id;
+	char *       name;
+	read_type_t  func;
+};
+
+extern int procfs_install(struct procfs_entry * entry);

+ 1 - 1
kernel/sys/version.c

@@ -18,7 +18,7 @@ char * __kernel_version_format = "%d.%d.%d-%s";
 /* Version numbers X.Y.Z */
 int    __kernel_version_major = 1;
 int    __kernel_version_minor = 5;
-int    __kernel_version_lower = 2;
+int    __kernel_version_lower = 3;
 
 /* Kernel build suffix, which doesn't necessarily
  * mean anything, but can be used to distinguish

+ 46 - 0
modules/lfbvideo.c

@@ -22,6 +22,7 @@
 #include <kernel/tokenize.h>
 #include <kernel/module.h>
 #include <kernel/video.h>
+#include <kernel/mod/procfs.h>
 
 #define PREFERRED_W  1024
 #define PREFERRED_H  768
@@ -211,12 +212,57 @@ static void lfb_video_panic(char ** msgs) {
 	}
 }
 
+static uint32_t framebuffer_func(fs_node_t * node, uint32_t offset, uint32_t size, uint8_t * buffer) {
+	char * buf = malloc(4096);
+
+	if (lfb_driver_name) {
+		sprintf(buf,
+			"Driver:\t%s\n"
+			"XRes:\t%d\n"
+			"YRes:\t%d\n"
+			"BitsPerPixel:\t%d\n"
+			"Stride:\t%d\n"
+			"Address:\t0x%x\n",
+			lfb_driver_name,
+			lfb_resolution_x,
+			lfb_resolution_y,
+			lfb_resolution_b,
+			lfb_resolution_s,
+			lfb_vid_memory);
+	} else {
+		sprintf(buf, "Driver:\tnone\n");
+	}
+
+	size_t _bsize = strlen(buf);
+	if (offset > _bsize) {
+		free(buf);
+		return 0;
+	}
+	if (size > _bsize - offset) size = _bsize - offset;
+
+	memcpy(buffer, buf + offset, size);
+	free(buf);
+	return size;
+}
+
+static struct procfs_entry framebuffer_entry = {
+	0,
+	"framebuffer",
+	framebuffer_func,
+};
+
 /* Install framebuffer device */
 static void finalize_graphics(const char * driver) {
 	lfb_driver_name = driver;
 	fs_node_t * fb_device = lfb_video_device_create();
 	vfs_mount("/dev/fb0", fb_device);
 	debug_video_crash = lfb_video_panic;
+
+	int (*procfs_install)(struct procfs_entry *) = (int (*)(struct procfs_entry *))(uintptr_t)hashmap_get(modules_get_symbols(),"procfs_install");
+
+	if (procfs_install) {
+		procfs_install(&framebuffer_entry);
+	}
 }
 
 /* Bochs support {{{ */

+ 63 - 0
modules/net.c

@@ -9,6 +9,7 @@
 #include <kernel/printf.h>
 #include <kernel/tokenize.h>
 #include <kernel/mod/net.h>
+#include <kernel/mod/procfs.h>
 
 #include <toaru/list.h>
 #include <toaru/hashmap.h>
@@ -31,6 +32,61 @@ static struct netif _netif = {0};
 
 static int tasklet_pid = 0;
 
+uint32_t get_primary_dns(void);
+
+static uint32_t netif_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
+	char * buf = malloc(4096);
+
+	struct netif * netif = &_netif;
+	char ip[16];
+	ip_ntoa(netif->source, ip);
+	char dns[16];
+	ip_ntoa(get_primary_dns(), dns);
+	char gw[16];
+	ip_ntoa(netif->gateway, gw);
+
+	if (netif->hwaddr[0] == 0 &&
+		netif->hwaddr[1] == 0 &&
+		netif->hwaddr[2] == 0 &&
+		netif->hwaddr[3] == 0 &&
+		netif->hwaddr[4] == 0 &&
+		netif->hwaddr[5] == 0) {
+
+		sprintf(buf, "no network\n");
+	} else {
+		sprintf(buf,
+			"ip:\t%s\n"
+			"mac:\t%2x:%2x:%2x:%2x:%2x:%2x\n"
+			"device:\t%s\n"
+			"dns:\t%s\n"
+			"gateway:\t%s\n"
+			,
+			ip,
+			netif->hwaddr[0], netif->hwaddr[1], netif->hwaddr[2], netif->hwaddr[3], netif->hwaddr[4], netif->hwaddr[5],
+			netif->driver,
+			dns,
+			gw
+		);
+	}
+
+	size_t _bsize = strlen(buf);
+	if (offset > _bsize) {
+		free(buf);
+		return 0;
+	}
+	if (size > _bsize - offset) size = _bsize - offset;
+
+	memcpy(buffer, buf + offset, size);
+	free(buf);
+	return size;
+}
+
+static struct procfs_entry netif_entry = {
+	0, /* filled by install */
+	"netif",
+	netif_func,
+};
+
 void init_netif_funcs(get_mac_func mac_func, get_packet_func get_func, send_packet_func send_func, char * device) {
 	_netif.get_mac = mac_func;
 	_netif.get_packet = get_func;
@@ -38,6 +94,13 @@ void init_netif_funcs(get_mac_func mac_func, get_packet_func get_func, send_pack
 	_netif.driver = device;
 	memcpy(_netif.hwaddr, _netif.get_mac(), sizeof(_netif.hwaddr));
 
+	if (!netif_entry.id) {
+		int (*procfs_install)(struct procfs_entry *) = (int (*)(struct procfs_entry *))(uintptr_t)hashmap_get(modules_get_symbols(),"procfs_install");
+		if (procfs_install) {
+			procfs_install(&netif_entry);
+		}
+	}
+
 	if (!tasklet_pid) {
 		tasklet_pid = create_kernel_tasklet(net_handler, "[net]", NULL);
 		debug_print(NOTICE, "Network worker tasklet started with pid %d", tasklet_pid);

+ 53 - 115
modules/procfs.c

@@ -10,19 +10,13 @@
 #include <kernel/process.h>
 #include <kernel/printf.h>
 #include <kernel/module.h>
-#include <kernel/mod/net.h>
 #include <kernel/multiboot.h>
 #include <kernel/pci.h>
+#include <kernel/mod/procfs.h>
 
 #define PROCFS_STANDARD_ENTRIES (sizeof(std_entries) / sizeof(struct procfs_entry))
 #define PROCFS_PROCDIR_ENTRIES  (sizeof(procdir_entries) / sizeof(struct procfs_entry))
 
-struct procfs_entry {
-	int          id;
-	char *       name;
-	read_type_t  func;
-};
-
 static fs_node_t * procfs_generic_create(char * name, read_type_t read_func) {
 	fs_node_t * fnode = malloc(sizeof(fs_node_t));
 	memset(fnode, 0x00, sizeof(fs_node_t));
@@ -504,65 +498,6 @@ static uint32_t mounts_func(fs_node_t *node, uint32_t offset, uint32_t size, uin
 	return size;
 }
 
-static uint32_t netif_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
-	char * buf = malloc(4096);
-
-	/* In order to not directly depend on the network module, we dynamically locate the symbols we need. */
-	void (*ip_ntoa)(uint32_t, char *) = (void (*)(uint32_t,char*))(uintptr_t)hashmap_get(modules_get_symbols(),"ip_ntoa");
-
-	struct netif * (*get_netif)(void) = (struct netif *(*)(void))(uintptr_t)hashmap_get(modules_get_symbols(),"get_default_network_interface");
-
-	uint32_t (*get_dns)(void) = (uint32_t (*)(void))(uintptr_t)hashmap_get(modules_get_symbols(),"get_primary_dns");
-
-	if (get_netif) {
-		struct netif * netif = get_netif();
-		char ip[16];
-		ip_ntoa(netif->source, ip);
-		char dns[16];
-		ip_ntoa(get_dns(), dns);
-		char gw[16];
-		ip_ntoa(netif->gateway, gw);
-
-		if (netif->hwaddr[0] == 0 &&
-			netif->hwaddr[1] == 0 &&
-			netif->hwaddr[2] == 0 &&
-			netif->hwaddr[3] == 0 &&
-			netif->hwaddr[4] == 0 &&
-			netif->hwaddr[5] == 0) {
-
-			sprintf(buf, "no network\n");
-		} else {
-			sprintf(buf,
-				"ip:\t%s\n"
-				"mac:\t%2x:%2x:%2x:%2x:%2x:%2x\n"
-				"device:\t%s\n"
-				"dns:\t%s\n"
-				"gateway:\t%s\n"
-				,
-				ip,
-				netif->hwaddr[0], netif->hwaddr[1], netif->hwaddr[2], netif->hwaddr[3], netif->hwaddr[4], netif->hwaddr[5],
-				netif->driver,
-				dns,
-				gw
-			);
-		}
-	} else {
-		sprintf(buf, "no network\n");
-	}
-
-	size_t _bsize = strlen(buf);
-	if (offset > _bsize) {
-		free(buf);
-		return 0;
-	}
-	if (size > _bsize - offset) size = _bsize - offset;
-
-	memcpy(buffer, buf + offset, size);
-	free(buf);
-	return size;
-
-}
-
 static uint32_t modules_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
 	list_t * hash_keys = hashmap_keys(modules_get_list());
 	char * buf = malloc(hash_keys->length * 512);
@@ -740,46 +675,6 @@ static uint32_t pci_func(fs_node_t *node, uint32_t offset, uint32_t size, uint8_
 	return size;
 }
 
-static uint32_t framebuffer_func(fs_node_t * node, uint32_t offset, uint32_t size, uint8_t * buffer) {
-	char * buf = malloc(4096);
-
-	char ** lfb_driver_name     = hashmap_get(modules_get_symbols(),"lfb_driver_name");
-	uint16_t * lfb_resolution_x = hashmap_get(modules_get_symbols(),"lfb_resolution_x");
-	uint16_t * lfb_resolution_y = hashmap_get(modules_get_symbols(),"lfb_resolution_y");
-	uint16_t * lfb_resolution_b = hashmap_get(modules_get_symbols(),"lfb_resolution_b");
-	uint32_t * lfb_resolution_s = hashmap_get(modules_get_symbols(),"lfb_resolution_s");
-	uintptr_t ** lfb_vid_memory = hashmap_get(modules_get_symbols(),"lfb_vid_memory");
-
-	if (lfb_driver_name && *lfb_driver_name) {
-		sprintf(buf,
-			"Driver:\t%s\n"
-			"XRes:\t%d\n"
-			"YRes:\t%d\n"
-			"BitsPerPixel:\t%d\n"
-			"Stride:\t%d\n"
-			"Address:\t0x%x\n",
-			*lfb_driver_name,
-			*lfb_resolution_x,
-			*lfb_resolution_y,
-			*lfb_resolution_b,
-			*lfb_resolution_s,
-			*lfb_vid_memory);
-	} else {
-		sprintf(buf, "Driver:\tnone\n");
-	}
-
-	size_t _bsize = strlen(buf);
-	if (offset > _bsize) {
-		free(buf);
-		return 0;
-	}
-	if (size > _bsize - offset) size = _bsize - offset;
-
-	memcpy(buffer, buf + offset, size);
-	free(buf);
-	return size;
-}
-
 static struct procfs_entry std_entries[] = {
 	{-1, "cpuinfo",  cpuinfo_func},
 	{-2, "meminfo",  meminfo_func},
@@ -788,16 +683,29 @@ static struct procfs_entry std_entries[] = {
 	{-5, "version",  version_func},
 	{-6, "compiler", compiler_func},
 	{-7, "mounts",   mounts_func},
-	{-8, "netif",    netif_func},
-	{-9, "modules",  modules_func},
-	{-10,"filesystems", filesystems_func},
-	{-11,"loader",   loader_func},
-	{-12,"irq",      irq_func},
-	{-13,"pat",      pat_func},
-	{-14,"pci",      pci_func},
-	{-15,"framebuffer", framebuffer_func},
+	{-8, "modules",  modules_func},
+	{-9, "filesystems", filesystems_func},
+	{-10,"loader",   loader_func},
+	{-11,"irq",      irq_func},
+	{-12,"pat",      pat_func},
+	{-13,"pci",      pci_func},
 };
 
+static list_t * extended_entries = NULL;
+static int next_id = 0;
+
+int procfs_install(struct procfs_entry * entry) {
+	if (!extended_entries) {
+		extended_entries = list_create();
+		next_id = -PROCFS_STANDARD_ENTRIES - 1;
+	}
+
+	entry->id = next_id--;
+	list_insert(extended_entries, entry);
+
+	return 0;
+}
+
 static struct dirent * readdir_procfs_root(fs_node_t *node, uint32_t index) {
 	if (index == 0) {
 		struct dirent * out = malloc(sizeof(struct dirent));
@@ -832,7 +740,29 @@ static struct dirent * readdir_procfs_root(fs_node_t *node, uint32_t index) {
 		strcpy(out->name, std_entries[index].name);
 		return out;
 	}
-	int i = index - PROCFS_STANDARD_ENTRIES + 1;
+
+	index -= PROCFS_STANDARD_ENTRIES;
+
+	if (extended_entries) {
+		if (index < extended_entries->length) {
+			size_t i = 0;
+			node_t * n = extended_entries->head;
+			while (i < index) {
+				n = n->next;
+				i++;
+			}
+
+			struct procfs_entry * e = n->value;
+			struct dirent * out = malloc(sizeof(struct dirent));
+			memset(out, 0x00, sizeof(struct dirent));
+			out->ino = e->id;
+			strcpy(out->name, e->name);
+			return out;
+		}
+		index -=  extended_entries->length;
+	}
+
+	int i = index + 1;
 
 	debug_print(WARNING, "%d %d %d", i, index, PROCFS_STANDARD_ENTRIES);
 
@@ -885,6 +815,14 @@ static fs_node_t * finddir_procfs_root(fs_node_t * node, char * name) {
 		}
 	}
 
+	foreach(node, extended_entries) {
+		struct procfs_entry * e = node->value;
+		if (!strcmp(name, e->name)) {
+			fs_node_t * out = procfs_generic_create(e->name, e->func);
+			return out;
+		}
+	}
+
 	return NULL;
 }