Add read to EXT2
diff --git a/.build.yml b/.build.yml
index 39c52f6..6f7943b 100644
--- a/.build.yml
+++ b/.build.yml
@@ -8,6 +8,7 @@
   - python3
   - gawk
   - nasm
+  - libreadline-dev:i386
 tasks:
   - build-kernel: |
       cd bluejay
diff --git a/include/kernel/dri/fs/ext2/ext2.h b/include/kernel/dri/fs/ext2/ext2.h
index 0ffeaac..2c04c8a 100644
--- a/include/kernel/dri/fs/ext2/ext2.h
+++ b/include/kernel/dri/fs/ext2/ext2.h
@@ -234,6 +234,9 @@
 	EXT2_S_IXOTH = 0x0001,
 };
 
+/// File type flag (used on inode->mode)
+#define EXT2_F_TYPE 0xf000
+
 struct ext2_dirent
 {
 	uint inode;
@@ -278,3 +281,5 @@
 						   struct ext2_inode *inode,
 						   void *buffer,
 						   uint block);
+
+ssize_t ext2_read_inode(struct ext2_superblock *sb, struct ext2_inode *inode, void *buffer, ssize_t size);
\ No newline at end of file
diff --git a/include/kernel/kint.h b/include/kernel/kint.h
index f70b22f..66f22b6 100644
--- a/include/kernel/kint.h
+++ b/include/kernel/kint.h
@@ -7,6 +7,8 @@
 
 typedef unsigned long size_t;
 
+typedef signed long ssize_t;
+
 typedef _Bool bool;
 
 enum
diff --git a/src/kernel/Jmk b/src/kernel/Jmk
index 05e2b8e..eefaa34 100644
--- a/src/kernel/Jmk
+++ b/src/kernel/Jmk
@@ -24,7 +24,7 @@
 
 FS ?= ext2
 
-CFLAGS += -I $(ROOT)/include/kernel $(test_defines)
+CFLAGS += -I $(ROOT)/include/kernel $(test_defines) -O0
 
 LDFLAGS += -Tlink.ld -melf_i386
 ASMFLAGS += -felf -Fdwarf
diff --git a/src/kernel/dri/ata_pio/ata_pio.c b/src/kernel/dri/ata_pio/ata_pio.c
index 17041a8..5696925 100644
--- a/src/kernel/dri/ata_pio/ata_pio.c
+++ b/src/kernel/dri/ata_pio/ata_pio.c
@@ -30,7 +30,7 @@
 
 static void ata_pio_send_init(uint lba, uchar num_sectors)
 {
-	outb(ATA_PORT_DRIVE_SEL, 0xe0 | (lba >> 24) & 0x0f);
+	outb(ATA_PORT_DRIVE_SEL, 0xe0 | ((lba >> 24) & 0x0f));
 	outb(0x1f1, 0x0); // waste some time
 	outb(ATA_PORT_SECTOR_COUNT, num_sectors);
 	outb(ATA_PORT_LBA_LOW, lba & 0xff);
diff --git a/src/kernel/dri/fs/ext2/ext2.c b/src/kernel/dri/fs/ext2/ext2.c
index 3a1e183..2cf15f5 100644
--- a/src/kernel/dri/fs/ext2/ext2.c
+++ b/src/kernel/dri/fs/ext2/ext2.c
@@ -3,6 +3,7 @@
 #include <kint.h>
 #include <log.h>
 #include <io.h>
+#include <alloc.h>
 
 inline uint ext2_block_size(struct ext2_superblock *sb)
 {
@@ -77,9 +78,25 @@
 	return descriptors[bgd_offset];
 }
 
-static void print_entry(uint inode, const char *name, void *data)
+static void print_entry(uint inode, const char *name, void *sb)
 {
 	kprintf("%d\t %s\n", inode, name);
+
+	struct ext2_inode in;
+
+	if (ext2_find_inode(sb, inode, &in))
+	{
+		if ((in.mode & EXT2_F_TYPE) == EXT2_S_IFREG)
+		{
+			char buffer[65];
+			uint read = ext2_read_inode(sb, &in, buffer, 64);
+			buffer[read] = 0;
+
+			kprintf("contents: %d\n'%s'\n", read, buffer);
+		}
+	}
+
+	return;
 }
 
 void ext2_mount(struct fs_node *where)
@@ -100,7 +117,7 @@
 		kprintf("ls /\n");
 		kprintf("inode\t name\n");
 		kprintf("--------------------\n");
-		ext2_dir_ls(&sb, &root, print_entry, NULL);
+		ext2_dir_ls(&sb, &root, print_entry, &sb);
 	}
 	else
 	{
@@ -143,7 +160,7 @@
 	struct ext2_block_group_descriptor descriptor =
 		ext2_load_block_group_descriptor(sb, block_group);
 
-	kprintf(DEBUG "Descriptor inode_table = 0x%x\n", descriptor.inode_table_start_block);
+	// kprintf(DEBUG "Descriptor inode_table = 0x%x\n", descriptor.inode_table_start_block);
 
 	// We need to figure out what FS block the inode is on, we know how many
 	// inodes there are total in this BGD and the number per page, so this is
@@ -184,7 +201,7 @@
 		struct ext2_dirent *ent = (void *)buffer;
 
 		// While there are files in this block
-		while (ent < buffer + ext2_block_size(sb))
+		while ((uint)ent < (uint)(buffer + ext2_block_size(sb)))
 		{
 			if (ent->inode == 0)
 				return true;
@@ -195,7 +212,7 @@
 
 				memcpy(name, ent->name, ent->name_len);
 				name[ent->name_len] = '\0';
-				
+
 				cb(ent->inode, name, data);
 			}
 
@@ -208,6 +225,32 @@
 	return true;
 }
 
+ssize_t ext2_read_inode(struct ext2_superblock *sb, struct ext2_inode *inode, void *buffer, ssize_t size)
+{
+	const uint block_size = ext2_block_size(sb);
+	char transfer[block_size];
+
+	uint fsize = MIN(inode->size, size);
+	uint i;
+
+	// Transfer full blocks straight to the output buffer
+	for (i = 0; i < fsize / block_size; i++)
+	{
+		ext2_read_inode_block(sb, inode, buffer + i * block_size, i);
+	}
+
+	// If we have part of a block left over read it here first, then transfer what we need
+	if (i * block_size < fsize)
+	{
+		uint remainder = fsize % block_size;
+
+		ext2_read_inode_block(sb, inode, transfer, i);
+		memcpy(buffer + i * block_size, transfer, remainder);
+	}
+
+	return fsize;
+}
+
 bool ext2_read_inode_block(struct ext2_superblock *sb,
 						   struct ext2_inode *inode,
 						   void *buffer,
@@ -223,4 +266,6 @@
 	uint block_address = inode->blocks[block];
 
 	ext2_read_block(sb, buffer, block_address);
+
+	return true;
 }