Skip to content

Instantly share code, notes, and snippets.

@mhansen
Created October 22, 2009 22:52
Show Gist options
  • Select an option

  • Save mhansen/216423 to your computer and use it in GitHub Desktop.

Select an option

Save mhansen/216423 to your computer and use it in GitHub Desktop.
--- oldsrc/drivers/memory/memory.c 2009-10-22 18:26:49.251667100 +1300
+++ src/drivers/memory/memory.c 2009-10-22 18:34:50.203175900 +1300
@@ -10,99 +10,104 @@
* Changes:
* Apr 29, 2005 added null byte generator (Jorrit N. Herder)
* Apr 09, 2005 added support for boot device (Jorrit N. Herder)
* Jul 26, 2004 moved RAM driver to user-space (Jorrit N. Herder)
* Apr 20, 1992 device dependent/independent split (Kees J. Bot)
*/
#include "../drivers.h"
#include "../libdriver/driver.h"
#include <sys/ioc_memory.h>
#include <env.h>
#include <minix/ds.h>
#include <minix/vm.h>
#include <sys/mman.h>
#include "../../kernel/const.h"
#include "../../kernel/config.h"
#include "../../kernel/type.h"
#include <sys/vm.h>
#include <sys/vm_i386.h>
#include "assert.h"
#include "local.h"
/* ramdisks (/dev/ram*) */
#define RAMDISKS 6
#define RAM_DEV_LAST (RAM_DEV_FIRST+RAMDISKS-1)
-#define NR_DEVS (7+RAMDISKS) /* number of minor devices */
+#define NR_DEVS (8+RAMDISKS) /* number of minor devices */
PRIVATE struct device m_geom[NR_DEVS]; /* base and size of each device */
PRIVATE vir_bytes m_vaddrs[NR_DEVS];
PRIVATE int m_device; /* current device */
PRIVATE struct kinfo kinfo; /* kernel information */
extern int errno; /* error number for PM calls */
FORWARD _PROTOTYPE( char *m_name, (void) );
FORWARD _PROTOTYPE( struct device *m_prepare, (int device) );
FORWARD _PROTOTYPE( int m_transfer, (int proc_nr, int opcode, u64_t position,
iovec_t *iov, unsigned nr_req, int safe));
FORWARD _PROTOTYPE( int m_do_open, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( void m_init, (void) );
FORWARD _PROTOTYPE( int m_ioctl, (struct driver *dp, message *m_ptr, int safe));
FORWARD _PROTOTYPE( void m_geometry, (struct partition *entry) );
/* Entry points to this driver. */
PRIVATE struct driver m_dtab = {
m_name, /* current device's name */
m_do_open, /* open or mount */
do_nop, /* nothing on a close */
m_ioctl, /* specify ram disk geometry */
m_prepare, /* prepare for I/O on a given minor device */
m_transfer, /* do the I/O */
nop_cleanup, /* no need to clean up */
m_geometry, /* memory device "geometry" */
nop_signal, /* system signals */
nop_alarm,
nop_cancel,
nop_select,
NULL,
NULL
};
/* Buffer for the /dev/zero null byte feed. */
#define ZERO_BUF_SIZE 1024
+
+/* Buffer for the /dev/one byte feed */
+#define ONE_BUF_SIZE 1024
PRIVATE char dev_zero[ZERO_BUF_SIZE];
+PRIVATE char dev_one[ONE_BUF_SIZE];
+
#define click_to_round_k(n) \
((unsigned) ((((unsigned long) (n) << CLICK_SHIFT) + 512) / 1024))
/*===========================================================================*
* main *
*===========================================================================*/
PUBLIC int main(void)
{
/* Main program. Initialize the memory driver and start the main loop. */
struct sigaction sa;
sa.sa_handler = SIG_MESS;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGTERM,&sa,NULL)<0) panic("MEM","sigaction failed", errno);
m_init();
driver_task(&m_dtab);
return(OK);
}
/*===========================================================================*
* m_name *
*===========================================================================*/
PRIVATE char *m_name()
{
/* Return a name for the current device. */
static char name[] = "memory";
return name;
@@ -247,62 +252,63 @@
if (opcode == DEV_GATHER_S) { /* copy data */
s=sys_safecopyto(proc_nr, user_vir,
vir_offset, (vir_bytes) vaddr+page_off, subcount, D);
} else {
s=sys_safecopyfrom(proc_nr, user_vir,
vir_offset, (vir_bytes) vaddr+page_off, subcount, D);
}
if(s != OK)
return s;
count = subcount;
break;
}
/* Null byte stream generator. */
case ZERO_DEV:
if (opcode == DEV_GATHER_S) {
size_t suboffset = 0;
left = count;
while (left > 0) {
chunk = (left > ZERO_BUF_SIZE) ? ZERO_BUF_SIZE : left;
s=sys_safecopyto(proc_nr, user_vir,
vir_offset+suboffset, (vir_bytes) dev_zero, chunk, D);
if(s != OK)
report("MEM","sys_safecopyto failed", s);
left -= chunk;
suboffset += chunk;
}
}
break;
-
}
+
+
/* Book the number of bytes transferred. */
position += count;
vir_offset += count;
if ((iov->iov_size -= count) == 0) { iov++; nr_req--; vir_offset = 0; }
}
return(OK);
}
/*===========================================================================*
* m_do_open *
*===========================================================================*/
PRIVATE int m_do_open(dp, m_ptr)
struct driver *dp;
message *m_ptr;
{
int r;
/* Check device number on open. */
if (m_prepare(m_ptr->DEVICE) == NIL_DEV) return(ENXIO);
if (m_device == MEM_DEV)
{
r = sys_enable_iop(m_ptr->IO_ENDPT);
if (r != OK)
{
printf("m_do_open: sys_enable_iop failed for %d: %d\n",
m_ptr->IO_ENDPT, r);
return r;
}
@@ -316,60 +322,65 @@
PRIVATE void m_init()
{
/* Initialize this task. All minor devices are initialized one by one. */
u32_t ramdev_size;
int i, s;
if (OK != (s=sys_getkinfo(&kinfo))) {
panic("MEM","Couldn't get kernel information.",s);
}
#if 0
/* Map in kernel memory for /dev/kmem. */
m_geom[KMEM_DEV].dv_base = cvul64(kinfo.kmem_base);
m_geom[KMEM_DEV].dv_size = cvul64(kinfo.kmem_size);
if((m_vaddrs[KMEM_DEV] = vm_map_phys(SELF, (void *) kinfo.kmem_base,
kinfo.kmem_size)) == MAP_FAILED) {
printf("MEM: Couldn't map in /dev/kmem.");
}
#endif
/* Ramdisk image built into the memory driver */
m_geom[IMGRD_DEV].dv_base= cvul64(0);
m_geom[IMGRD_DEV].dv_size= cvul64(imgrd_size);
m_vaddrs[IMGRD_DEV] = (vir_bytes) imgrd;
/* Initialize /dev/zero. Simply write zeros into the buffer. */
for (i=0; i<ZERO_BUF_SIZE; i++) {
dev_zero[i] = '\0';
}
+ /* initialize /dev/one. */
+ for (i=0; i<ONE_BUF_SIZE; i++) {
+ dev_one[i] = '1';
+ }
+
/* Set up memory range for /dev/mem. */
m_geom[MEM_DEV].dv_base = cvul64(0);
m_geom[MEM_DEV].dv_size = cvul64(0xffffffff);
m_vaddrs[MEM_DEV] = (vir_bytes) MAP_FAILED; /* we are not mapping this in. */
}
/*===========================================================================*
* m_ioctl *
*===========================================================================*/
PRIVATE int m_ioctl(dp, m_ptr, safe)
struct driver *dp; /* pointer to driver structure */
message *m_ptr; /* pointer to control message */
int safe;
{
/* I/O controls for the memory driver. Currently there is one I/O control:
* - MIOCRAMSIZE: to set the size of the RAM disk.
*/
struct device *dv;
if(!safe) {
printf("m_transfer: unsafe?\n");
return EPERM;
}
switch (m_ptr->REQUEST) {
case MIOCRAMSIZE: {
/* Someone wants to create a new RAM disk with the given size. */
u32_t ramdev_size;
int s, dev;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment