diff --git a/copy_of_klist_android_kernel.c b/copy_of_klist_android_kernel.c
new file mode 100644
index 0000000000000000000000000000000000000000..526d4c444fc8fb6d110562df38537e8bf863b47e
--- /dev/null
+++ b/copy_of_klist_android_kernel.c
@@ -0,0 +1,199 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/fs.h>
+#include <linux/rbtree.h>
+#include <linux/hashtable.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/tty.h>
+#include <asm/errno.h>
+#include <linux/miscdevice.h>
+
+#define ERR(...) printk(KERN_ERR __VA_ARGS__)
+
+/* #define DEBUG */
+#ifdef DEBUG
+#define LOG(...) printk(KERN_INFO __VA_ARGS__)
+#else
+#define LOG(...)
+#endif
+
+/* klist functions */
+#define LIST_CMD 0x1337
+#define LIST_ADD (LIST_CMD + 0)
+#define LIST_INSERT (LIST_CMD + 1)
+#define LIST_SET (LIST_CMD + 2)
+#define LIST_GET (LIST_CMD + 3)
+#define LIST_DELETE (LIST_CMD + 4)
+
+/* consts */
+#define MAX_SIZE 0x400
+
+static volatile struct k_list {
+    long values[MAX_SIZE];
+    unsigned long size;
+} list;
+
+struct index_val_t {
+	unsigned long index;
+	long value;
+};
+
+long add_item(long arg)
+{
+	if (list.size >= MAX_SIZE)
+		return -EINVAL;
+	list.values[list.size] = arg;
+	list.size++;
+
+	return 0;
+}
+
+long insert_item(long arg)
+{
+	struct index_val_t io;
+	unsigned long i;
+	if (copy_from_user((void *)&io, (void __user *)arg, sizeof(struct index_val_t)))
+		return -EINVAL;
+
+	if (list.size >= MAX_SIZE)
+		return -EINVAL;
+	if (io.index > list.size)
+		return -EINVAL;
+
+	for(i = list.size; i > io.index; i--)
+	{
+		list.values[i] = list.values[i-1];
+	}
+	list.values[io.index] = io.value;
+	list.size++;
+
+	return 0;
+}
+
+long set_item(long arg)
+{
+	struct index_val_t io;
+	if (copy_from_user((void *)&io, (void __user *)arg, sizeof(struct index_val_t)))
+		return -EINVAL;
+
+	if (io.index >= list.size)
+		return -EINVAL;
+
+	list.values[io.index] = io.value;
+
+	return 0;
+}
+
+long get_item(long arg)
+{
+	struct index_val_t io;
+	if (copy_from_user((void *)&io, (void __user *)arg, sizeof(struct index_val_t)))
+		return -EINVAL;
+
+	if (io.index >= list.size)
+		return -EINVAL;
+
+	io.value = list.values[io.index];
+	if (copy_to_user((void __user *)arg, (void *)&io, sizeof(struct index_val_t)))
+		return -EINVAL;
+
+	return 0;
+}
+
+long delete_item(long arg)
+{
+	unsigned long index = arg;
+
+	if (index >= list.size)
+		return -EINVAL;
+
+	for(; index < list.size-1; index++)
+	{
+		list.values[index] = list.values[index+1];
+	}
+	list.size--;
+
+	return 0;
+}
+
+static long list_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	long ret;
+
+	switch(cmd) {
+		case LIST_ADD:
+			ret = add_item(arg);
+			break;
+		case LIST_INSERT:
+			ret = insert_item(arg);
+			break;
+		case LIST_SET:
+			ret = set_item(arg);
+			break;
+		case LIST_GET:
+			ret = get_item(arg);
+			break;
+		case LIST_DELETE:
+			ret = delete_item(arg);
+			break;
+		default:
+			ret = -EINVAL;
+			break;
+	}
+
+	return ret;
+}
+
+static int list_open(struct inode *inode, struct file *file)
+{
+	LOG("open device\n");
+
+	return 0;
+}
+
+static int list_release(struct inode *inode, struct file *file)
+{
+	LOG("close device\n");
+
+	return 0;
+}
+
+struct file_operations list_fops = {
+	owner: THIS_MODULE,
+	open: list_open,
+	release: list_release,
+	unlocked_ioctl: list_ioctl,
+};
+
+static struct miscdevice klist = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = "klist",
+	.fops = &list_fops,
+};
+
+static int __init init_list(void)
+{
+	int ret;
+
+	ret = misc_register(&klist);
+	LOG("register device: %d\n", ret);
+	list.size = 0;
+
+	return ret;
+}
+
+static void __exit exit_list(void)
+{
+	misc_deregister(&klist);
+	LOG("exit.\n");
+}
+
+module_init(init_list);
+module_exit(exit_list);
+
+MODULE_LICENSE("GPL");