diff --git a/docs/config/Languages.txt b/docs/config/Languages.txt
index 8d5bc0f..2ccad5c 100644
--- a/docs/config/Languages.txt
+++ b/docs/config/Languages.txt
@@ -1,4 +1,4 @@
-Format: 1.51
+Format: 1.52
 
 # This is the Natural Docs languages file for this project.  If you change
 # anything here, it will apply to THIS PROJECT ONLY.  If you'd like to change
diff --git a/docs/config/Menu.txt b/docs/config/Menu.txt
index e963368..49a410c 100644
--- a/docs/config/Menu.txt
+++ b/docs/config/Menu.txt
@@ -20,7 +20,7 @@ Timestamp: Updated yyyy/mm/dd
 # These are indexes you deleted, so Natural Docs will not add them again
 # unless you remove them from this line.
 
-Don't Index: Classes, Variables, Macros
+Don't Index: Variables, Macros, Classes
 
 
 # --------------------------------------------------------------------------
@@ -63,9 +63,12 @@ Group: BootLoader  {
    Group: Loader  {
 
       File: a20.inc  (boot/loader/a20.inc)
+      File: disk.inc  (boot/loader/disk.inc)
+      File: fat.inc  (boot/loader/fat.inc)
       File: loader.asm  (boot/loader/loader.asm)
       File: logger.inc  (boot/loader/logger.inc)
       File: memory.inc  (boot/loader/memory.inc)
+      File: stpdfs.inc  (boot/loader/stpdfs.inc)
       File: video.inc  (boot/loader/video.inc)
       }  # Group: Loader
 
@@ -81,6 +84,9 @@ Group: BootLoader  {
    Group: EFI  {
 
       File: bootia32.asm  (boot/efi/bootia32.asm)
+      File: fs.inc  (boot/efi/fs.inc)
+      File: logger.inc  (boot/efi/logger.inc)
+      File: memory.inc  (boot/efi/memory.inc)
       File: uefi.inc  (boot/efi/uefi.inc)
       }  # Group: EFI
 
@@ -105,10 +111,10 @@ Group: Kernel  {
          File: cmos.inc  (kernel/dev/at/cmos.inc)
          File: com.inc  (kernel/dev/at/com.inc)
          File: floppy.inc  (kernel/dev/at/floppy.inc)
-         File: ide.inc  (kernel/dev/at/ide.inc)
          File: kbd.inc  (kernel/dev/at/kbd.inc)
          File: ne2k.inc  (kernel/dev/at/ne2k.inc)
          File: pit.inc  (kernel/dev/at/pit.inc)
+         File: ata.inc  (kernel/dev/at/ata.inc)
          }  # Group: At
 
       File: console.inc  (kernel/dev/console.inc)
@@ -140,6 +146,8 @@ Group: Kernel  {
    File: lock.inc  (kernel/lock.inc)
    File: pic.inc  (kernel/pic.inc)
    File: vfs.inc  (kernel/vfs.inc)
+   File: bio.inc  (kernel/bio.inc)
+   File: shed.inc  (kernel/sched.inc)
    }  # Group: Kernel
 
 Group: Lib  {
diff --git a/docs/config/Topics.txt b/docs/config/Topics.txt
index 2703bcc..119cc0f 100644
--- a/docs/config/Topics.txt
+++ b/docs/config/Topics.txt
@@ -1,4 +1,4 @@
-Format: 1.51
+Format: 1.52
 
 # This is the Natural Docs topics file for this project.  If you change anything
 # here, it will apply to THIS PROJECT ONLY.  If you'd like to change something
diff --git a/kernel/bio.inc b/kernel/bio.inc
index d768fa3..da988bd 100644
--- a/kernel/bio.inc
+++ b/kernel/bio.inc
@@ -2,6 +2,12 @@
 	;; Buffer cache
 
 	;; Struc: Buffer
+	;; 
+	;; .dev      - Device id
+	;; .block    - Block number
+	;; .ulock    - lock
+	;; .refcount - refcount
+	;; .data     - block data
 struc Buffer {
 	.dev      dd ?
 	.block    dd ?
@@ -21,14 +27,39 @@ bio_init:
 
 	;; Function: bio_read
 	;;
+	;; In:
+	;;    EAX - devid (AH major, AL minor)
+	;;    ECX - block
 bio_bread:
+	push eax
 	mov eax, uBIOLock
 	call lock_acquire
+	pop eax
 
+	movzx ecx, ah
+	shl ecx, 2
+	add ecx, aBlockDevices
+	cmp ecx, aBlockDevices.end
+	jb @f
+
+	mov esi, szErrorInvalidDevid
+	call klog
+	jmp .end
+@@:
+	mov ecx, [ecx]
+	mov ecx, [ecx + BlkDev.strategy]
+
+	call ecx
+
+.end:
 	mov eax, uBIOLock
 	call lock_release
 	ret
 
+	;; Function: bio_bwrite
+bio_bwrite:
+	ret
+
 	;; Function: bio_brelse
 	;; Unbusy a buffer and release it to the free lists.
 bio_brelse:
@@ -40,3 +71,4 @@ bio_brelse:
 	ret
 
 uBIOLock dd 0
+szErrorInvalidDevid db "Error: invalid devid", 0
diff --git a/kernel/cpuid.inc b/kernel/cpuid.inc
new file mode 100644
index 0000000..ea3796f
--- /dev/null
+++ b/kernel/cpuid.inc
@@ -0,0 +1,4 @@
+CPUID_FEAT_ECX_SSE3   = (1 shl 0)
+CPUID_FEAT_ECX_PCLMUL = (1 shl 1)
+
+CPUID_FEAT_EDX_APIC = (1 shl 9) 
diff --git a/kernel/dev/at/floppy.inc b/kernel/dev/at/floppy.inc
index 6c90026..1e50fe2 100644
--- a/kernel/dev/at/floppy.inc
+++ b/kernel/dev/at/floppy.inc
@@ -14,11 +14,24 @@ FLOPPY_720KB  = 0x3
 FLOPPY_1_44MB = 0x4
 FLOPPY_2_88MB = 0x5
 
+	;; TODO: disk geometry for each floppy type
+HEADS_PER_CYLINDER  = 2
+SECTORS_PER_CLUSTER = 1
+BYTES_PER_SECTOR    = 512
+SECTORS_PER_TRACK   = 18
+TOTAL_SECTORS       = 2880
+
 FLOPPY_MAX = 2
 
+	;; Struct: Floppy
+	;;
+	;; .active - XXX
+	;; .motor  - XXX
 struc Floppy {
 	.active db ?
+	.motor  db ?
 }
+DEFN Floppy
 
 floppy_probe:
 	mov al, CMOS_FLOPPY_TYPE
@@ -45,9 +58,52 @@ floppy_init:
 	call floppy_probe
 	ret
 
+	;; Function: floppy_lba_to_chs
+	;; Convert LBA to CHS
+	;;
+	;; In:
+	;;   EAX - LBA
+	;;
+	;; Out:
+	;; 	AL - Cylinder
+	;;  AH - Head
+	;;  CL - Sector
+floppy_lba_to_chs:
+	push ebp
+	mov ebp, esp
+	sub esp, 1
+	; CYL = LBA / (HPC * SPT)
+	; HEAD = (LBA % (HPC * SPT)) / SPT
+	; SECT = (LBA % (HPC * SPT)) % SPT + 1
+
+	mov edx, eax
+	shr edx, 16
+	mov cx, (HEADS_PER_CYLINDER * SECTORS_PER_TRACK)
+	div cx
+
+	mov [ebp-1], al ; cyl
+
+	mov ax, dx
+	mov cl, SECTORS_PER_TRACK
+	div cl
+
+	mov cl, ah
+	inc cl
+	xchg al, ah
+	mov al, [ebp-1]
+	leave
+	ret
+
+	;; Function: floppy_strategy
+	;; Do a read or write operation
+	;;
+	;; In:
+	;;    EAX - Address of <Buffer>
 floppy_strategy:
 	ret
 
+	;; Function: floppy_open
+	;; Open the device for I/O operations
 floppy_open:
 	push ebp
 	mov ebp, esp
@@ -63,6 +119,8 @@ floppy_open:
 	pop ebp
 	ret
 
+	;; Function: floppy_close
+	;; Close a device.
 floppy_close:
 	xor eax, eax
 	ret
@@ -75,6 +133,7 @@ floppy_dump:
 	ret
 
 floppy_psize:
+	xor eax, eax
 	ret
 
 floppy_irq:
diff --git a/kernel/dev/dev.inc b/kernel/dev/dev.inc
index 2dd487a..6e2c81c 100644
--- a/kernel/dev/dev.inc
+++ b/kernel/dev/dev.inc
@@ -18,7 +18,7 @@ DEFN Device
 	;; Struc: BlkDev
 	;;
 	;; .open     - Open the device in preparation for I/O operations
-	;; .strategy - Start a read or write operation, and return immediately.
+	;; .strategy - Do a read or write operation.
 	;; .close    - Close a device.
 	;; .dump     - Write all physical memory to the device.
 	;; .psize    - Return the size of a disk-drive partition.
@@ -31,6 +31,7 @@ struc BlkDev {
 	.dump     dd ?
 	.psize    dd ?
 }
+DEFN BlkDev
 
 	;; Struc: CharDev
 	;;
diff --git a/kernel/intro.txt b/kernel/intro.txt
index bb9c92b..4599ce0 100644
--- a/kernel/intro.txt
+++ b/kernel/intro.txt
@@ -1 +1,4 @@
 File: Introduction
+
+About: StupidOS Kernel
+
diff --git a/kernel/kernel.asm b/kernel/kernel.asm
index 1ed6276..196c605 100644
--- a/kernel/kernel.asm
+++ b/kernel/kernel.asm
@@ -14,8 +14,9 @@
 	jmp short kmain
 
 	;; Function: kmain
+	;; Kernel entry point
 	;;
-	;; Parameters:
+	;; In:
 	;; 
 	;;     EAX - Boot Magic
 	;;     EBX - Boot structure address
@@ -29,7 +30,7 @@ kmain:
 	; Copy boot structure
 	mov ecx, sizeof.BootInfo
 	mov esi, ebx
-	mov edi, boot_structure
+	mov edi, stBootInfo
 	rep movsb
 
 	; print hello world 
@@ -52,11 +53,11 @@ kmain:
 	call mm_init
 
 	mov eax, 0xC0400000
-	mov ebx, [boot_structure.high_mem]
+	mov ebx, [stBootInfo.high_mem]
 	add ebx, KERNEL_VIRT_BASE
 	call pmm_free_range
 
-	;mov eax, [boot_structure.low_mem]
+	;mov eax, [stBootInfo.low_mem]
 	;call heap_init
 
 	call pic_init
@@ -88,6 +89,9 @@ kmain:
 
 	call vfs_init
 
+	mov ah, 2
+	call bio_bread
+
 	mov eax, SYSCALL_EXIT
 	int 0x42
 
@@ -126,7 +130,9 @@ szMsgKernelAlive db "Kernel (", VERSION_FULL , ") is alive", 0
 szMsgBuildDate db "Built ", BUILD_DATE, 0
 szErrorBootProtocol db "Error: wrong magic number", 0
 
-boot_structure BootInfo
+	;; Variable: stBootInfo
+	;; <BootInfo>
+stBootInfo BootInfo
 
 kTSS TSS
 
diff --git a/kernel/mm/mm.inc b/kernel/mm/mm.inc
index 52b6d2b..25c5463 100644
--- a/kernel/mm/mm.inc
+++ b/kernel/mm/mm.inc
@@ -176,7 +176,7 @@ mm_init:
 	KV2P eax
 	mov [edx], eax
 
-	cmp esi, [boot_structure.high_mem]
+	cmp esi, [stBootInfo.high_mem]
 	jb .loop
 
 	; reload cr3
diff --git a/kernel/sys/bootinfo.inc b/kernel/sys/bootinfo.inc
index 309b948..43a2f3f 100644
--- a/kernel/sys/bootinfo.inc
+++ b/kernel/sys/bootinfo.inc
@@ -7,8 +7,13 @@ struc BootInfoRange {
 }
 
 	;; Struct: BootInfo
-	;;
 	;; StupidOS boot protocol structure
+	;;
+	;; .mmap         - Free memory map
+	;; .kernel_start - Kernel start address
+	;; .kernel_size  - Kernel size in bytes
+	;; .high_mem     - Free memory under 1MB
+	;; .low_mem      - Free memory upper 1MB
 struc BootInfo {
 	.mmap         dd 4*2*20 dup(0)
 	.kernel_start dd ?