Added a dos command line buffer and hardcoded the kernel command line for ntoskrnl...
[reactos.git] / reactos / loaders / dos / loadros.asm
index 39fbd79..e6933c9 100644 (file)
@@ -6,23 +6,31 @@
 ;
 ; Base address of the kernel
 ;
-KERNEL_BASE    equ     0c0000000h
+LOAD_BASE      equ     0200000h
 
 ;
 ; Segment selectors
 ;
-;USER_CS               equ     08h
-;USER_DS               equ     010h
-;KERNEL_CS     equ     020h
-;KERNEL_DS     equ     028h
-
-KERNEL_CS       equ     08h
-KERNEL_DS       equ     010h
-                                     
-;
-; Space reserved in the gdt for tss descriptors
-;
-NR_TASKS        equ     128
+%define KERNEL_CS     (0x8)
+%define KERNEL_DS     (0x10)
+%define LOADER_CS     (0x18)
+%define LOADER_DS     (0x20)
+
+struc multiboot_module
+mbm_mod_start: resd    1
+mbm_mod_end:   resd    1
+mbm_string:    resd    1
+mbm_reserved:  resd    1
+endstruc
+
+struc multiboot_address_range
+mar_baselow:    resd 1
+mar_basehigh:   resd 1
+mar_lengthlow:  resd 1
+mar_lengthhigh:        resd 1
+mar_type:       resd 1
+mar_reserved:   resd 3
+endstruc
 
 ;
 ; We are a .com program
@@ -38,199 +46,547 @@ BITS 16
 
 %macro DPRINT  1+
 %ifndef        NDEBUG
-               jmp     %%end_str
+       jmp     %%end_str
 
-%%str:         db      %1
+%%str: db      %1
 
 %%end_str:
-               push    di
-               push    ds
-               push    es
-               pop     ds
-               mov     di, %%str
-               call    print_string
-               pop     ds
-               pop     di
+       push    di
+       push    ds
+       push    es
+       pop     ds
+       mov     di, %%str
+       call    print_string
+       pop     ds
+       pop     di
 %endif
 %endmacro
 
 entry:
-        ;
-        ; Load stack
-        ;
-        cli
-        push    ds
-        pop     ss
-        push    ds
-        pop     es
-        mov     sp,real_stack_end
-        sti
-
-        ;
-        ; Setup the loader space
-        ;
-        mov     ebx,0
-        mov     eax,0
-        mov     ecx,0
-        mov     edx,0
-        mov     esi,0
-        mov     edi,0
-
-        ;
-        ; Calculate the end of this module
-        ;
-        mov     ax,ds
-        movzx   ebx,ax
-        shl     ebx,4
-        add     ebx,_end
-
-        ;
-        ; Round up to the nearest page
-        ;
-        and     ebx,~0xfff
-        add     ebx,01000h
-
-        ;
-        ; Set the start of the page directory
-        ;
-        mov     [kernel_page_directory_base],ebx
-
-        ;
-        ; Set the start of the continuous range of physical memory
-        ; occupied by the kernel
-        ;
-        mov     [_start_mem],ebx
-        add     ebx,01000h
-
-        ;
-        ; Calculate the start of the system page table (0xc0000000 upwards)
-        ;
-        mov     [system_page_table_base],ebx
-        add     ebx,01000h
-
-        ;
-        ; Calculate the start of the page table to map the first 4mb
-        ;
-        mov     [lowmem_page_table_base],ebx
-        add     ebx,01000h
-
-        ;
-        ; Set the position for the first module to be loaded
-        ;
-        mov     [next_load_base],ebx
-
-        ;
-        ; Set the address of the start of kernel code
-        ;
-        mov     [_start_kernel],ebx
-
-        ;
-        ; Make the argument list into a c string
-        ;
-        mov     di,081h
-l1:
-        cmp     byte [di],0dh
-        je      l2
-        cmp     byte [di],' '
-        jne      l12
-        mov     byte [di],0
-l12:
-        inc     di
-        jmp     l1
-l2:
-        mov     byte [di],0
-        mov     [end_cmd_line],di
-
-        mov     dx,082h
-l14:
-        mov     bx,dx
-        cmp     byte [bx],0
-        je      l16
-
-        ;
-        ; Process the arguments
-        ;
-        mov     di,loading_msg
-        call    print_string
-        mov     di,dx
-        call    print_string
-        mov     ah,02h
-        mov     dl,0dh
-        int     021h
-        mov     ah,02h
-        mov     dl,0ah
-        int     021h
-
-        ;
-        ; Load the file
-        ;
-        push    di
-        mov     dx,di
-;        call    _load_file
+       ;;
+       ;; Load stack
+       ;;
+       cli
+       push    ds
+       pop     ss
+       push    ds
+       pop     es
+       mov     sp, real_stack_end
+       sti
+
+       ;;
+       ;; Setup the 32-bit registers
+       ;;
+       mov     ebx, 0
+       mov     eax, 0
+       mov     ecx, 0
+       mov     edx, 0
+       mov     esi, 0
+       mov     edi, 0
+
+       ;;
+       ;; Set the position for the first module to be loaded
+       ;;
+       mov     dword [next_load_base], LOAD_BASE
+
+       ;;
+       ;; Setup various variables
+       ;;
+       mov     bx, ds
+       movzx   eax, bx
+       shl     eax, 4
+       add     [gdt_base], eax
+
+       ;;
+       ;; Setup the loader code and data segments
+       ;;
+       mov     eax, 0
+       mov     ax, cs
+       shl     eax, 4
+       mov     [_loader_code_base_0_15], ax
+       shr     eax, 16
+       mov     byte [_loader_code_base_16_23], al
+
+       mov     eax, 0
+       mov     ax, ds
+       shl     eax, 4
+       mov     [_loader_data_base_0_15], ax
+       shr     eax, 16
+       mov     byte [_loader_data_base_16_23], al
+
+       ;;
+       ;; load gdt
+       ;;
+       lgdt    [gdt_descr]
+
+       ;;
+       ;; Enable the A20 address line (to allow access to over 1mb)
+       ;;
+       call    empty_8042
+       mov     al, 0D1h                ; command write
+       out     064h, al
+       call    empty_8042
+       mov     al, 0DFh                ; A20 on
+       out     060h, al
+       call    empty_8042
+
+       ;;
+       ;; Make the argument list into a c string
+       ;;
+       mov     di, 081h
+       mov     si, dos_cmdline
+.next_char
+       mov     al, [di]
+       mov     [si], al
+       cmp     byte [di], 0dh
+       je      .end_of_command_line
+       inc     di
+       inc     si
+       jmp     .next_char
+       
+.end_of_command_line:
+       mov     byte [di], 0
+       mov     byte [si], 0
+       mov     [dos_cmdline_end], di
+       
+       ;;
+       ;; Make the argument list into a c string
+       ;;
+       mov     di, 081h
+.next_char2
+       cmp     byte [di], 0
+       je      .end_of_command_line2
+       cmp     byte [di], ' '
+       jne     .not_space
+       mov     byte [di], 0
+.not_space
+       inc     di
+       jmp     .next_char2
+.end_of_command_line2
+
+       ;;
+       ;; Check if we want to skip the first character
+       ;;
+       cmp     byte [081h], 0
+       jne     .first_char_is_zero
+       mov     dx, 082h
+       jmp     .start_loading
+.first_char_is_zero
+       mov     dx, 081h
+
+       ;;
+       ;; Check if we have reached the end of the string
+       ;;
+.start_loading
+       mov     bx, dx
+       cmp     byte [bx], 0
+       jne     .more_modules
+       jmp     .done_loading
+
+.more_modules
+       ;;
+       ;; Process the arguments
+       ;;
+       cmp     byte [di], '/'
+       jne     .no_next_module
+       jmp     .next_module
+.no_next_module:
+
+       ;;
+       ;; Display a message saying we are loading the module
+       ;;
+       mov     di, loading_msg
+       call    print_string
+       mov     di, dx
+       call    print_string
+
+       ;;
+       ;; Save the filename
+       ;;
+       mov     si, di
+       mov     edx, 0
+
+       mov     dx, [_multiboot_mods_count]
+       shl     dx, 8
+       add     dx, _multiboot_module_strings   
+       mov     bx, [_multiboot_mods_count]
+       imul    bx, bx, multiboot_module_size
+       add     bx, _multiboot_modules
+       mov     eax, 0
+       mov     ax, ds
+       shl     eax, 4
+       add     eax, edx
+       mov     [bx + mbm_string], eax
+       
+       mov     bx, dx
+.copy_next_char
+       mov     al, [si]
+       mov     [bx], al
+       inc     si
+       inc     bx
+       cmp     al, 0
+       jne     .copy_next_char
+
+       ;;
+       ;; Load the file
+       ;;
+       push    di
+       mov     dx, di
+
+       ; Check if it is a symbol file
+       cmp     byte [bx-5],'.'
+       jne     .checkForHive
+       cmp     byte [bx-4],'s'
+       jne     .checkForHive
+       cmp     byte [bx-3],'y'
+       jne     .checkForHive
+       cmp     byte [bx-2],'m'
+       jne     .checkForHive
+
+       call    sym_load_module
+       jmp     .after_copy
+
+.checkForHive:
+       ; Check if it is a symbol file
+       cmp     byte [bx-5],'.'
+       jne     .lst_copy
+       cmp     byte [bx-4],'h'
+       jne     .lst_copy
+       cmp     byte [bx-3],'i'
+       jne     .lst_copy
+       cmp     byte [bx-2],'v'
+       jne     .lst_copy
+
+       call    sym_load_module
+       jmp     .after_copy
+
+.lst_copy:
+       ;; Check for a module list file
+       cmp     byte [bx-5],'.'
+       jne     .pe_copy
+       cmp     byte [bx-4],'l'
+       jne     .pe_copy
+       cmp     byte [bx-3],'s'
+       jne     .pe_copy
+       cmp     byte [bx-2],'t'
+       jne     .pe_copy
+
+       call    sym_load_module
+
+       push    es
+       mov     bx,0x9000
+       push    bx
+       pop     es
+       xor     edi,edi
+
+.lst_copy_bytes:
+       mov     bx,_lst_name_local
+       
+.lst_byte:
+       mov     al,[es:di]
+       inc     di
+       cmp     al,' '
+       jg      .lst_not_space
+       mov     byte [bx],0
+       inc     bx
+.lst_space:
+       mov     al,[es:di]
+       inc     di
+       cmp     al,' '
+       jle     .lst_space
+.lst_not_space:
+       cmp     al,'*'
+       je      .lst_end
+       mov     [bx],al
+       inc     bx
+       jmp     .lst_byte
+
+.lst_end:
+       ;; We are here because the terminator was encountered
+       mov     byte [bx],0             ; Zero terminate
+       inc     bx
+       mov     byte [bx],0
+       mov     [dos_cmdline_end],bx    ; Put in cmd_line_length
+       mov     dx,_lst_name_local; Put this address in di
+       mov     di,dx                   ; This, too, at the start of the
+                                       ; string
+
+       pop     es
+
+       jmp     .start_loading  
+                       
+.pe_copy:
        call    pe_load_module
-        pop     di
-
-        ;
-        ; Move onto the next module name in the command line
-        ;
-l15:
-        cmp     di,[end_cmd_line]
-        je      l16
-        cmp     byte [di],0
-        je      l17
-        inc     di
-        jmp     l15
-l17:
-        inc     di
-        mov     dx,di
-        jmp     l14
-l16:
-
-        ;
-        ; Set the end of kernel memory 
-        ;
-        mov     eax,[next_load_base]
-        mov     [_end_mem],eax
-
-        ;
-        ; Begin the pmode initalization
-        ;
-        jmp     _to_pmode
-
-exit:
-        mov     ax,04c00h
-        int     21h
-
-        ;
-        ; Any errors detected jump here
-        ;
-_error:
-        mov     di,err_msg
-        call    print_string
-        jmp     exit
-
-end_cmd_line dw 0
 
-;
-; In: EDI = address
-; Out: FS = segment
-;      DI = base
-;
-convert_to_seg:
-        push    eax
+.after_copy:
+       pop     di
+       cmp     eax, 0
+       jne     .load_success
+       jmp     .exit
+.load_success:
+       mov     ah, 02h
+       mov     dl, 0dh
+       int     021h
+       mov     ah, 02h
+       mov     dl, 0ah
+       int     021h
+
+       ;;
+       ;; Move onto the next module name in the command line
+       ;;
+.next_module
+       cmp     di, [dos_cmdline_end]
+       je      .done_loading
+       cmp     byte [di], 0
+       je      .found_module_name
+       inc     di
+       jmp     .next_module
+.found_module_name
+       inc     di
+       mov     dx, di
+       jmp     .start_loading
 
-        mov     eax,edi
-;        shr     eax,16
-;        shl     eax,12
-;        mov     fs,ax
-       shr     eax, 4
-       mov     fs, ax
-       and     edi, 0xf
+.done_loading
 
-;        and     edi,0ffffh
+       ;;
+       ;; Initialize the multiboot information
+       ;;
+       mov     eax, 0
+       mov     ax, ds
+       shl     eax, 4
+       
+       mov     [_multiboot_info_base], eax
+       add     dword [_multiboot_info_base], _multiboot_info
+       
+       mov     dword [_multiboot_flags], 0xc
+  
+       mov     [_multiboot_cmdline], eax
+       add     dword [_multiboot_cmdline], _multiboot_kernel_cmdline
+       
+       ;;
+       ;; Hide the kernel's entry in the list of modules
+       ;;
+       mov     [_multiboot_mods_addr], eax
+       mov     ebx, _multiboot_modules
+       add     ebx, multiboot_module_size
+       add     dword [_multiboot_mods_addr], ebx
+       dec     dword [_multiboot_mods_count]
+
+       ;;
+       ;; get extended memory size in KB
+       ;;
+       push    ebx
+       xor     ebx,ebx
+       mov     [_multiboot_mem_upper],ebx
+       mov     [_multiboot_mem_lower],ebx
+
+       mov     ax, 0xe801
+       int     015h
+       jc      .oldstylemem
+
+       cmp     ax, 0
+       je      .cmem
+
+       and     ebx, 0xffff
+       shl     ebx,6
+       mov     [_multiboot_mem_upper],ebx
+       and     eax,0xffff
+       add     dword [_multiboot_mem_upper],eax
+       jmp     .done_mem
+
+.cmem:
+       cmp     cx, 0
+       je      .oldstylemem
+
+       and     edx, 0xFFFF
+       shl     edx, 6
+       mov     [_multiboot_mem_upper], edx
+       and     ecx, 0xFFFF
+       add     dword [_multiboot_mem_upper], ecx
+       jmp     .done_mem
+
+.oldstylemem:
+       ;; int 15h opt e801 don't work , try int 15h, option 88h
+       mov     ah, 088h
+       int     015h
+       cmp     ax, 0
+       je      .cmosmem
+       mov     [_multiboot_mem_upper],ax
+       jmp     .done_mem
+.cmosmem:
+       ;; int 15h opt 88h don't work , try read cmos
+       xor     eax,eax
+       mov     al, 0x31
+       out     0x70, al
+       in      al, 0x71
+       and     eax, 0xffff     ; clear carry
+       shl     eax,8
+       mov     [_multiboot_mem_upper],eax
+       xor     eax,eax
+       mov     al, 0x30
+       out     0x70, al
+       in      al, 0x71
+       and     eax, 0xffff     ; clear carry
+       add     [_multiboot_mem_lower],eax
+
+.done_mem:
+
+       ;;
+       ;; Retrieve BIOS memory map if available
+       ;;
+       xor ebx,ebx
+       mov edi, _multiboot_address_ranges
+
+.mmap_next:
+
+       mov edx, 'PAMS'
+       mov ecx, multiboot_address_range_size
+       mov eax, 0E820h
+       int 15h
+       jc  .done_mmap
+
+       cmp eax, 'PAMS'
+       jne .done_mmap
+
+       add edi, multiboot_address_range_size
+
+       cmp ebx, 0
+       jne .mmap_next
+
+       ;;
+       ;; Prepare multiboot memory map structures
+       ;;
+
+       ;; Fill in the address descriptor size field
+       mov dword [_multiboot_address_range_descriptor_size], multiboot_address_range_size
+
+       ;; Set flag and base address and length of memory map
+       or  dword [_multiboot_flags], 40h
+       mov eax, edi
+       sub eax, _multiboot_address_ranges
+       mov dword [_multiboot_mmap_length], eax
+
+       xor     eax, eax
+       mov     ax, ds
+       shl     eax, 4
+       mov     [_multiboot_mmap_addr], eax
+       add     dword [_multiboot_mmap_addr], _multiboot_address_ranges
+
+.done_mmap:
+
+       pop ebx
+       
+       ;;
+       ;; Begin the pmode initalization
+       ;;
+       
+       ;;
+       ;; Save cursor position
+       ;;
+       mov     ax, 3           ;! Reset video mode
+       int     10h
+
+       mov     bl, 10
+       mov     ah, 12
+       int     10h
+
+       mov     ax, 1112h       ;! Use 8x8 font
+       xor     bl, bl
+       int     10h
+       mov     ax, 1200h       ;! Use alternate print screen
+       mov     bl, 20h
+       int     10h
+       mov     ah, 1h          ;! Define cursor (scan lines 6 to 7)
+       mov     cx, 0607h
+       int     10h
+
+       mov     ah, 1
+       mov     cx, 0600h
+       int     10h
+
+       mov     ah, 6           ; Scroll active page up
+       mov     al, 32h         ; Clear 50 lines
+       mov     cx, 0           ; Upper left of scroll
+       mov     dx, 314fh       ; Lower right of scroll
+       mov     bh, 1*10h+1     ; Use normal attribute on blanked lines
+       int     10h
+
+       mov     dx, 0
+       mov     dh, 0
+
+       mov     ah, 2
+       mov     bh, 0
+       int     10h
+
+       mov     dx, 0
+       mov     dh, 0
+
+       mov     ah, 2
+       mov     bh, 0
+       int     10h
+
+       mov     ah, 3
+       mov     bh, 0
+       int     10h
+       movzx   eax, dl
+;      mov     [_cursorx], eax
+       movzx   eax, dh
+;      mov     [_cursory], eax
+
+       cli
+
+       ;;
+       ;; Load the absolute address of the multiboot information structure
+       ;;
+       mov     ebx, [_multiboot_info_base]
+
+       ;;
+       ;; Enter pmode and clear prefetch queue
+       ;;
+       mov     eax,cr0
+       or      eax,0x10001
+       mov     cr0,eax
+       jmp     .next
+.next:
+       ;;
+       ;; NOTE: This must be position independant (no references to
+       ;; non absolute variables)
+       ;;
+
+       ;;
+       ;; Initalize segment registers
+       ;;
+       mov     ax,KERNEL_DS
+       mov     ds,ax
+       mov     ss,ax
+       mov     es,ax
+       mov     fs,ax
+       mov     gs,ax
+
+       ;;
+       ;; Initalize eflags
+       ;;
+       push    dword 0
+       popf
+
+       ;;
+       ;; Load the multiboot magic value into eax
+       ;;      
+       mov     eax, 0x2badb002
+
+       ;;
+       ;; Jump to start of the kernel
+       ;;
+       jmp     dword KERNEL_CS:(LOAD_BASE+0x1000)
+
+       ;;
+       ;; Never get here
+       ;;
+
+.exit:
+       mov     ax,04c00h
+       int     21h
 
-        pop     eax
-        ret
 
 ;
 ; Print string in DS:DI
@@ -238,19 +594,19 @@ convert_to_seg:
 print_string:
        push    ebp
        mov     bp, sp
-        push    eax
-        push    edx
-        push    edi
+       push    eax
+       push    edx
+       push    edi
 
-        mov     ax, 0x0200
+       mov     ax, 0x0200
 .loop:
-        mov     dl, [di]
-        cmp     dl, 0
-        je      .end_loop
+       mov     dl, [di]
+       cmp     dl, 0
+       je      .end_loop
        cmp     dl, '%'
        jne     .print_char
        inc     di
-        mov     dl, [di]
+       mov     dl, [di]
        cmp     dl, 'a'
        jne     .not_ax
        push    eax
@@ -280,18 +636,18 @@ print_string:
 .not_cx:
 
 .print_char:
-        int     0x21
+       int     0x21
 
 .next_char:
-        inc     di
-        jmp     .loop
+       inc     di
+       jmp     .loop
 
 .end_loop:
-        pop     edi
-        pop     edx
-        pop     eax
+       pop     edi
+       pop     edx
+       pop     eax
        pop     ebp
-        ret
+       ret
 
 ;
 ; print_ax - print the number in the ax register
@@ -351,7 +707,7 @@ print_eax:
 .hex_val:
        add     dl, 'a' - 10
 
-.not_hex:      
+.not_hex:
        int     0x21
        shl     ebx, 4
        dec     cx
@@ -363,8 +719,7 @@ print_eax:
        pop     eax
        ret
 
-
-STRUC  DOS_HDR
+STRUC  pe_doshdr
 e_magic:       resw    1
 e_cblp:                resw    1
 e_cp:          resw    1
@@ -386,465 +741,405 @@ e_res2:         resw    10
 e_lfanew:      resd    1
 ENDSTRUC
 
-STRUC  NT_HDRS
-nth_sig:       resd    1
-ntf_mach:      resw    1    
-ntf_num_secs:  resw    1
-ntf_timestamp: resd    1
-ntf_symtab_ptr:        resd    1
-ntf_num_syms:  resd    1
-ntf_opt_hdr_sz:        resw    1
-ntf_chars:     resw    1
-
-nto_magic:     resw    1
-nto_mjr_lnk_vr:        resb    1
-nto_mnr_lnk_vr:        resb    1
-nto_code_sz:   resd    1
-nto_data_sz:   resd    1   
-nto_bss_sz:    resd    1   
-nto_entry_offs:        resd    1   
-nto_code_offs: resd    1   
-nto_data_offs: resd    1   
-nto_image_base:        resd    1   
-nto_sec_align: resd    1   
-nto_file_align:        resd    1   
-nto_mjr_os_ver:        resw    1    
-nto_Mnr_os_ver:        resw    1    
-nto_mjr_img_vr:        resw    1    
-nto_Mnr_img_vr:        resw    1    
-nto_mjr_subsys:        resw    1    
-nto_mnr_subsys:        resw    1    
-nto_w32_ver:   resd    1   
-nto_image_sz:  resd    1   
-nto_hdr_sz:    resd    1   
-nto_chksum:    resd    1   
-nto_subsys:    resw    1    
-nto_dll_chars: resw    1    
-nto_stk_res_sz:        resd    1   
-nto_stk_cmt_sz:        resd    1   
-nto_hp_res_sz: resd    1   
-nto_hp_cmt_sz: resd    1   
-nto_ldr_flags: resd    1   
-nto_dir_cnt:   resd    1   
-nto_dir_ent:   resq    16
-ENDSTRUC
-
-STRUC  DATA_DIR
-dd_rva:                resd    1
-dd_sz:         resd    1
-ENDSTRUC
-
-STRUC  SCN_HDR
-se_name:       resb    8
-se_vsz:                resd    1
-se_vaddr:      resd    1
-se_rawsz:      resd    1
-se_raw_ofs:    resd    1
-se_reloc_ofs:  resd    1
-se_lnum_ofs:   resd    1
-se_num_relocs: resw    1
-se_num_lnums:  resw    1
-se_chars:      resd    1
-ENDSTRUC
 
-;
-; pe_load_module - load a PE module into memory
-;
-;      DI - Filename
-;
-;      [_nr_files] - total files loaded (incremented)
-;      [next_load_base] - load base for file (updated to next loc)
-;      [_module_lengths] - correct slot is set.
-;
+_mb_magic:
+       dd 0
+_mb_flags:
+       dd 0
+_mb_checksum:
+       dd 0
+_mb_header_addr:
+       dd 0
+_mb_load_addr:
+       dd 0
+_mb_load_end_addr:
+       dd 0
+_mb_bss_end_addr:
+       dd 0
+_mb_entry_addr:
+       dd 0
+
+_cpe_doshdr:
+       times pe_doshdr_size db 0
+_current_filehandle:
+       dw 0
+_current_size:
+       dd 0
+_current_file_size:
+       dd 0
+       
+_lst_name_local:
+       times 2048 db 0
+       
+       ;;
+       ;; Load a SYM file
+       ;;      DS:DX = Filename
+       ;;
+sym_load_module:
+       call    load_module1
+       call    load_module2
+       mov     edi, [next_load_base]
+       add     edi, [_current_file_size]
+
+       mov     eax, edi
+       test    di, 0xfff
+       jz      .sym_no_round
+       and     di, 0xf000
+       add     edi, 0x1000
+
+       ;;
+       ;; Clear unused space in the last page
+       ;;
+       mov     esi, edi
+       mov     ecx, edi
+       sub     ecx, eax
+
+.sym_clear:
+       mov     byte [esi],0
+       inc     esi
+       loop    .sym_clear
+
+.sym_no_round:
+
+       call    load_module3
+       ret
 
+       ;;
+       ;; Load a PE file
+       ;;      DS:DX = Filename
+       ;;
 pe_load_module:
-       push    dx
-       push    ds
-
-       push    ds
-       pop     es
-
-       mov     eax, [next_load_base]
-       mov     [load_base], eax
-DPRINT 'next_load_base %A', 13, 10, 0
-
-        ;
-        ; Open the file
-        ;
-        mov     ax, 0x3d00
-        mov     dx, di
-        int     0x21
-        jnc    .open_good
-       jmp     .error
-.open_good:
-        mov     [file_handle],ax
-        
-        ;
-        ; Seek to beginning of file
-        ;
-        mov     ax,0x4200
-        mov     bx, [file_handle]
-        mov     cx, 0
-        mov     dx, 0
-        int     0x21
-       jnc     .rewind_good
-        jmp    .error
-.rewind_good:
-
-       ;
-       ; Compute load address for PE headers
-       ;
-        mov     edi,[load_base]
-        call    convert_to_seg
-        mov     dx,di
-        push    fs
-        pop     ds
-
-       ;
-       ; Load the headers
-       ;
-        mov     ax, 0x3f00
-        mov     bx, [es:file_handle]
-        mov     cx, 0x1000
-        int     0x21
-
-       ;
-       ;  Check DOS MZ Header
-       ;
-       mov     bx, dx
-       mov     ax, word [bx + e_magic]
+       call    load_module1
+
+       ;;
+       ;; Read in the DOS EXE header
+       ;;
+       mov     ah, 0x3f
+       mov     bx, [_current_filehandle]
+       mov     cx, pe_doshdr_size
+       mov     dx, _cpe_doshdr
+       int     0x21
+       jnc     .header_read
+       mov     dx, error_file_read_failed
+       jmp     error
+.header_read
+
+       ;;
+       ;; Check the DOS EXE magic
+       ;;
+       mov     ax, word [_cpe_doshdr + e_magic]
        cmp     ax, 'MZ'
        je      .mz_hdr_good
-        push    es
-        pop     ds
-       mov     dx, bad_mz_msg
-       mov     di, dx
-       call    print_string
-       jmp     .error
-
-.mz_hdr_good:
-       ;
-       ;  Check PE Header
-       ;
-       mov     eax, dword [bx + e_lfanew]
-DPRINT 'lfanew %A ', 0
-       add     bx, ax
-       mov     eax, dword [bx + nth_sig]
-       cmp     eax, 0x00004550
-       je      .pe_hdr_good
-        push    es
-        pop     ds
-       mov     dx, bad_pe_msg
-       mov     di, dx
-       call    print_string
-       jmp     .error
+       mov     dx, error_bad_mz
+       jmp     error
+.mz_hdr_good
+
+       ;;
+       ;; Find the BSS size
+       ;;
+       mov     ebx, dword [_multiboot_mods_count]
+       cmp     ebx, 0
+       jne     .not_first
        
-.pe_hdr_good:
-       ;
-       ;  Get header size and bump next_load_base
-       ;
-       mov     eax, [bx + nto_hdr_sz]
-DPRINT 'header size %A ', 0
-       add     dword [es:next_load_base], eax
-
-       ;
-       ;  Setup section pointer
-       ;
-       mov     ax, [bx + ntf_num_secs]
-DPRINT 'num sections %a', 13, 10, 0
-       mov     [es:num_sections], ax
-       add     bx, NT_HDRS_size
-       mov     [es:cur_section], bx
-       mov     [es:cur_section + 2], ds
-       ;
-       ;  Load each section or fill with zeroes
-       ;
-.scn_loop:
-       ;
-       ;  Compute size of data to load from file
-       ;
-       mov     eax, [bx + se_rawsz]
-DPRINT 'raw size %A ', 0
-       cmp     eax, 0
-       jne     .got_data
-       jmp     .no_data
-.got_data:
-        mov     [es:size_mod_4k], ax
-        and     word [es:size_mod_4k], 0x0fff
-        shr     eax, 12
-        mov     dword [es:size_div_4k], eax
-
-       ;
-       ;  Seek to section offset
-       ;
-       mov     eax, [bx + se_raw_ofs]
-DPRINT 'raw offset %A ', 0
+       mov     edx, 0
+       mov     ax, 0x4200
+       mov     cx, 0
+       mov     dx, 0x1004
+       mov     bx, [_current_filehandle]
+       int     0x21
+       jnc     .start_seek1
+       mov     dx, error_file_seek_failed
+       jmp     error
+.start_seek1:
+       mov     ah, 0x3F
+       mov     bx, [_current_filehandle]
+       mov     cx, 32
+       mov     dx, _mb_magic
+       int     0x21
+       jnc     .mb_header_read
+       mov     dx, error_file_read_failed
+       jmp     error
+.mb_header_read:
+       jmp     .first
+       
+.not_first:
+       mov     dword [_mb_bss_end_addr], 0
+.first:
+
+       call  load_module2
+       call  load_module3
+       ret
+
+load_module1:
+       ;;
+       ;; Open file
+       ;;
+       mov     ax, 0x3d00
+       int     0x21
+       jnc     .file_opened
+       mov     dx, error_file_open_failed
+       jmp     error
+.file_opened:
+
+       ;;
+       ;; Save the file handle
+       ;;
+       mov     [_current_filehandle], ax
+
+       ;;
+       ;; Print space
+       ;;
+       mov     ah,02h
+       mov     dl,' '
+       int     021h
+
+       ;;
+       ;; Seek to the start of the file
+       ;;
+       mov     ax, 0x4200
+       mov     bx, [_current_filehandle]
+       mov     cx, 0
+       mov     dx, 0
+       int     0x21
+       jnc     .seek_start
+       mov     dx, error_file_seek_failed
+       jmp     error
+.seek_start:
+       ret
+
+load_module2:
+       ;;
+       ;; Seek to the end of the file to get the file size
+       ;;
+       mov     edx, 0
+       mov     ax, 0x4202
+       mov     dx, 0
+       mov     cx, 0
+       mov     bx, [_current_filehandle]
+       int     0x21
+       jnc     .start_end
+       mov     dx, error_file_seek_failed
+       jmp     error
+.start_end
+       shl     edx, 16
        mov     dx, ax
-       shr     eax, 16
-       mov     cx, ax
-        mov     ax,0x4200
-        mov     bx, [es:file_handle]
-        int     0x21
-       jnc     .seek_good
-        jmp    .error
-.seek_good:
-
-       ;
-       ;  Load the base pointer
-       ;
-        mov     edi,[es:next_load_base]
-        call    convert_to_seg
-        mov     dx, di
-        push    fs
-        pop     ds
-
-        ;
-        ;  Read data in 4k chunks
-        ;
-.do_chunk:
-        ;
-        ; Check if we have read it all
-        ;
-        mov     eax, [es:size_div_4k]
-        cmp     eax, 0
-        je      .chunk_done
-
-        ;
-        ; Make the call (dx was loaded above)
-        ;
-        mov     ax, 0x3f00
-        mov     bx, [es:file_handle]
-        mov     cx, 0x1000
-        int     0x21               
-       ; FIXME: should check return status and count
-
-        ;
-        ; We move onto the next pointer by altering ds
-        ;
-        mov     ax, ds
-        add     ax, 0x0100
-        mov     ds, ax
-        dec     word [es:size_div_4k]
-        jmp     .do_chunk
-
-.chunk_done:
-        ;
-        ; Read the last section
-        ;
-        mov     ax, 0x3f00
-        mov     bx, [es:file_handle]
-        mov     cx, [es:size_mod_4k]
-        int     0x21
-       jnc     .last_read_good
-        jmp    .error
-.last_read_good:
-
-.no_data:
-       ;
-       ;  Zero out uninitialized data sections
-       ;
-       lds     bx, [es:cur_section]
-mov    eax, dword [bx + se_chars]
-DPRINT 'section chars %A', 13, 10, 0
-       test    dword [bx + se_chars], 0x80
-       jz      .no_fill
+       mov     [_current_size], edx
+       mov     [_current_file_size], edx
        
-       ;
-       ;  Compute size of section to zero fill
-       ;
-       mov     eax, [bx + se_vsz]
-       cmp     eax, 0
-       je      .no_fill
-        mov     [es:size_mod_4k], ax
-        and     word [es:size_mod_4k], 0x0fff
-        shr     eax, 12
-        mov     [size_div_4k], eax
-
-       ;
-       ;  Load the base pointer
-       ;
-        mov     edi,[es:next_load_base]
-        call    convert_to_seg
-        mov     dx, di
-        push    fs
-        pop     ds
-
-.do_fill:
-        ;
-        ; Check if we have read it all
-        ;
-        mov     eax, [es:size_div_4k]
-        cmp     eax, 0
-        je      .fill_done
-
-        ;
-        ; Zero out a chunk
-        ;
-       mov     ax, 0x0000      
-        mov     cx, 0x1000
-       push    di
-       push    es
-       push    ds
-       pop     es
-rep    stosb
-       pop     es
-       pop     di
+       mov     edx, 0
+       mov     ax, 0x4200
+       mov     dx, 0
+       mov     cx, 0
+       mov     bx, [_current_filehandle]
+       int     0x21
+       jnc     .start_seek
+       mov     dx, error_file_seek_failed
+       jmp     error
+.start_seek
+       
+       mov     edi, [next_load_base]
+       
+.read_next:
+       cmp     dword [_current_size], 32768
+       jle     .read_tail
 
-        ;
-        ; We move onto the next pointer by altering ds
-        ;
-        mov     ax, ds
-        add     ax, 0x0100
-        mov     ds, ax
-        dec     word [es:size_div_4k]
-        jmp     .do_fill
-
-.fill_done:
-        ;
-        ; Read the last section
-        ;
-       mov     ax, 0x0000      
-        mov     cx, [es:size_mod_4k]
-       push    di
-       push    es
+       ;;
+       ;; Read in the file data
+       ;;
        push    ds
-       pop     es
-rep    stosb
-       pop     es
-       pop     di
+       mov     ah, 0x3f
+       mov     bx, [_current_filehandle]
+       mov     cx, 32768
+       mov     dx, 0x9000
+       mov     ds, dx
+       mov     dx, 0
+       int     0x21
+       jnc     .read_data_succeeded
+       pop     ds
+       mov     dx, error_file_read_failed
+       jmp     error
+.read_data_succeeded:
+%ifndef NDEBUG
+       mov     ah,02h
+       mov     dl,'#'
+       int     021h
+%endif
 
-.no_fill:
+       ;;
+       ;; Copy the file data just read in to high memory
+       ;;
+       pop     ds
+       mov     esi, 0x90000
+       mov     ecx, 32768
+       call    _himem_copy
+%ifndef NDEBUG
+       mov     ah,02h
+       mov     dl,'$'
+       int     021h
+%else
+       mov     ah,02h
+       mov     dl,'.'
+       int     021h
+%endif
 
-       ;
-       ;  Update raw data offset in section header
-       ;
-       lds     bx, [es:cur_section]
-       mov     eax, [es:next_load_base]
-       sub     eax, [es:load_base]
-DPRINT 'new raw offset %A ', 0
-       mov     [bx + se_raw_ofs], eax
-       
-       ;
-       ;  Update next_load_base
-       ;
-       mov     eax, [bx + se_vsz]
-DPRINT 'scn virtual sz %A ', 0
-       and     eax, 0xfffff000
-       add     dword [es:next_load_base], eax
-       test    dword [bx + se_vsz], 0xfff
-       jz      .even_scn
-       add     dword [es:next_load_base], 0x1000
-
-.even_scn:
-mov    eax, [es:next_load_base]
-DPRINT 'next load base %A', 13, 10, 0
-
-       ;
-       ;  Setup for next section or exit loop
-       ;
-       dec     word [es:num_sections]
-       jz      .scn_done
-       add     bx, SCN_HDR_size
-       mov     [es:cur_section], bx
-       jmp     .scn_loop
-
-.scn_done:
-       ;
-       ;  Update module_length
-       ;
-       mov     eax, [es:next_load_base]
-       sub     eax, [es:load_base]
-       mov     esi, [es:_nr_files]
-       mov     [es:_module_lengths + esi * 4], eax
-
-        inc     dword [es:_nr_files]
+       sub     dword [_current_size], 32768
+       jmp     .read_next
 
+.read_tail
+       ;;
+       ;; Read in the tailing part of the file data
+       ;;
+       push    ds
+       mov     eax, [_current_size]
+       mov     cx, ax
+       mov     ah, 0x3f
+       mov     bx, [_current_filehandle]
+       mov     dx, 0x9000
+       mov     ds, dx
+       mov     dx, 0
+       int     0x21
+       jnc     .read_last_data_succeeded
        pop     ds
-       pop     dx
-       ret
+       mov     dx, error_file_read_failed
+       jmp     error
+.read_last_data_succeeded:
+%ifndef NDEBUG
+       mov     ah,02h
+       mov     dl,'#'
+       int     021h
+%endif
 
-.error:
-       push    es
+       ;;
+       ;; Copy the tailing part to high memory
+       ;;
        pop     ds
-        mov     di, err_msg
-        call    print_string
-        jmp     exit
+       mov     ecx, [_current_size]
+       mov     esi, 0x90000
+       call    _himem_copy
+%ifndef NDEBUG
+       mov     ah,02h
+       mov     dl,'$'
+       int     021h
+%else
+       mov     ah,02h
+       mov     dl,'.'
+       int     021h
+%endif
 
-;
-; Handle of the currently open file
-;
-file_handle dw 0
+       mov     edx, [_mb_bss_end_addr]
+       cmp     edx, 0
+       je      .no_bss
+       mov     edi, edx        
+.no_bss:               
+       test    di, 0xfff
+       jz      .no_round
+       and     di, 0xf000
+       add     edi, 0x1000
+.no_round:
+       ret
 
-;
-; Size of the current file mod 4k
-;
-size_mod_4k dw 0
+load_module3:  
+       mov     bx, [_multiboot_mods_count]
+       imul    bx, bx, multiboot_module_size
+       add     bx, _multiboot_modules
+       
+       mov     edx, [next_load_base]
+       mov     [bx + mbm_mod_start], edx
+       mov     [bx + mbm_mod_end], edi
+       mov     [next_load_base], edi
+       mov     dword [bx + mbm_reserved], 0
+       
+       inc     dword [_multiboot_mods_count]
 
-;
-; Size of the current file divided by 4k
-;
-size_div_4k dd 0
+       mov     eax, 1
+       
+       ret
 
-load_base      dd      0
-num_sections   dw      0
-cur_section    dd      0
+       ;;
+       ;; On error print a message and return zero
+       ;;
+error:
+       mov     ah, 0x9
+       int     0x21
+       mov     eax, 0
+       ret
 
-;
-;
-;
-last_addr dw 0
+       ;;
+       ;; Copy to high memory
+       ;; ARGUMENTS
+       ;;      ESI = Source address
+       ;;      EDI = Destination address
+       ;;      ECX = Byte count
+       ;; RETURNS
+       ;;      EDI = End of the destination region
+       ;;      ECX = 0
+       ;; 
+_himem_copy:
+       push    ds              ; Save DS
+       push    es              ; Save ES
+       push    eax
+       push    esi
+
+       cmp     eax, 0
+       je      .l3
+       
+       cli                     ; No interrupts during pmode
+       
+       mov     eax, cr0        ; Entered protected mode
+       or      eax, 0x1
+       mov     cr0, eax
+
+       jmp     .l1             ; Flush prefetch queue
+.l1:
+       
+       mov     eax, KERNEL_DS  ; Load DS with a suitable selector
+       mov     ds, ax
+       mov     eax, KERNEL_DS
+       mov     es, ax
+
+       cld
+       a32 rep movsb
+;.l2:
+;      mov     al, [esi]       ; Copy the data
+;      mov     [edi], al
+;      dec     ecx
+;      inc     esi
+;      inc     edi
+;      cmp     ecx, 0
+;      jne     .l2
+
+       mov     eax, cr0        ; Leave protected mode
+       and     eax, 0xfffffffe
+       mov     cr0, eax
+       
+       jmp     .l3
+.l3:   
+       sti
+       pop     esi
+       pop     eax
+       pop     es
+       pop     ds
+       ret
 
 ;
-; Generic error message
+; Loading message
 ;
-err_msg                db      'Error during operation',10, 13, 0
-bad_mz_msg     db      'Module has bad MZ header', 10, 13, 0
-bad_pe_msg     db      'Module has bad PE header', 10, 13, 0
-rostitle       db      '',0
 loading_msg    db      'Loading: ',0
-death_msg      db      'death', 0
-
-filelength_lo  dw 0
-filelength_hi  dw 0
 
-kernel_page_directory_base dd 0
-system_page_table_base dd 0
-lowmem_page_table_base dd 0
+;;
+;; Next free address in high memory
+;;
 next_load_base dd 0
-_start_kernel dd 0
-
-boot_param_struct_base dd 0
 
-;
-; These variables are passed to the kernel (as a structure)
-;
-align 4
-_boot_param_struct:
-_magic:
-        dd 0
-_cursorx:
-        dd 0
-_cursory:
-        dd 0
-_nr_files:
-        dd 0
-_start_mem:
-        dd 0
-_end_mem:
-        dd 0
-_module_lengths:
-        times 64 dd 0
-_end_boot_param_struct
-             
 ;
 ; Needed for enabling the a20 address line
 ;
 empty_8042:
-        jmp     $+3
-        jmp     $+3
-        in      al,064h
-        test    al,02h
-        jnz     empty_8042
+       jmp     $+3
+       jmp     $+3
+       in      al,064h
+       test    al,02h
+       jnz     empty_8042
        ret
 
 ;
@@ -853,307 +1148,124 @@ empty_8042:
 align 8
 gdt_descr:
 gdt_limit:
-        dw (3*8)-1
+       dw      (5*8)-1
 gdt_base:
-        dd gdt
-
-
-_to_pmode:
-        ;
-        ; Setup kernel parameters
-        ;
-        mov     dword [_magic],0xdeadbeef
-
-        ;
-        ; Save cursor position
-        ;
-        mov     ax,3          ;! Reset video mode
-        int     10h
-
-
-        mov     bl,10
-        mov     ah,12
-        int     10h
-        
-;      mov     ax,1112h      ;! Use 8x8 font
-;      xor     bl,bl
-;      int     10h
-        mov     ax,1200h      ;! Use alternate print screen
-        mov     bl,20h
-        int     10h
-        mov     ah,1h         ;! Define cursor (scan lines 6 to 7)
-        mov     cx,0607h
-        int     10h
-
-        mov     ah,1
-        mov     cx,0600h
-        int     10h
-
-        MOV       AH,6        ;SCROLL ACTIVE PAGE UP
-        MOV       AL,32H     ;CLEAR 25 LINES
-        MOV       CX,0H       ;UPPER LEFT OF SCROLL
-        MOV       DX,314FH    ;LOWER RIGHT OF SCROLL
-        MOV       BH,1*10h+1       ;USE NORMAL ATTRIBUTE ON BLANKED LINE
-        INT       10H         ;VIDEO-IO
-
-
-        mov     dx,0
-        mov     dh,0
-
-        mov     ah,02h
-        mov     bh,0
-        int     10h
-
-        mov     dx,0
-        mov     dh,0
-
-        mov     ah,02h
-        mov     bh,0
-        int     010h
-          
-        mov     ah,03h
-        mov     bh,0h
-        int     010h
-        movzx   eax,dl
-        mov     [_cursorx],eax
-        movzx   eax,dh
-        mov     [_cursory],eax
-
-        mov     bx,ds
-        movzx   eax,bx
-        shl     eax,4
-        add     eax,_boot_param_struct
-        mov     [boot_param_struct_base],eax        
-
-        cli
-
-        ;
-        ; Zero out the kernel page directory
-        ;
-        ;
-        mov     edi,[kernel_page_directory_base]
-        call    convert_to_seg
-
-        mov     cx,1024
-l10:
-        mov     dword [fs:di],0
-        add     di,4
-        loop    l10
-
-        ;
-        ; Map in the lowmem page table (and reuse it for the identity map)
-        ;
-        mov     edi,[kernel_page_directory_base]
-        call    convert_to_seg
-
-        mov     eax,[lowmem_page_table_base]
-        add     eax,07h
-        mov     [fs:di],eax
-        mov     [fs:di+(0xd0000000/(1024*1024))],eax
-       
-       ;
-       ; Map the page tables from the page table
-       ;
-       mov     eax,[kernel_page_directory_base]
-       add     eax,07h
-       mov     [fs:di+(0xf0000000/(1024*1024))],eax
-       
-        ;
-        ; Map in the kernel page table
-        ;
-        mov     eax,[system_page_table_base]
-        add     eax,07h
-        mov     [fs:di+3072],eax
-
-        ;
-        ; Setup the lowmem page table
-        ;
-        mov     edi,[lowmem_page_table_base]
-        call    convert_to_seg
-
-        mov     ebx,0
-l9:
-        mov     eax,ebx
-        shl     eax,12        ; ebx = ebx * 4096
-        add     eax,07h       ; user, rw, present
-        mov     [fs:edi+ebx*4],eax
-        inc     ebx
-        cmp     ebx,1024
-        jl      l9
-
-        ;
-        ; Setup the system page table
-        ;
-        mov     edi,[system_page_table_base]
-        call    convert_to_seg
-
-        mov     eax,07h
-l8:
-        mov     edx,eax
-        add     edx,[_start_kernel]
-        mov     [fs:edi],edx
-        add     edi,4
-        add     eax,1000h
-        cmp     eax,100007h
-        jl      l8
-        
-        ;
-        ; Load the page directory into cr3
-        ;
-        mov     eax,[kernel_page_directory_base]
-        mov     cr3,eax
-
-        ;
-        ; Setup various variables
-        ;
-        mov     bx,ds
-        movzx   eax,bx
-        shl     eax,4
-        add     [gdt_base],eax
-
-        ;
-        ; Enable the A20 address line (to allow access to over 1mb)
-        ;
-       call    empty_8042
-        mov     al,0D1h                ; command write
-        out     064h,al
-       call    empty_8042
-        mov     al,0DFh                ; A20 on
-        out     060h,al
-       call    empty_8042
-
-        ;
-        ; Reprogram the PIC because they overlap the Intel defined
-        ; exceptions 
-        ;
-        mov     al,011h                ; initialization sequence
-        out     020h,al                ; send it to 8259A-1
-        dw   0x00eb,0x00eb           ; jmp $+2, jmp $+2
-        out     0A0h,al                ; and to 8259A-2
-        dw   0x00eb,0x00eb
-        mov     al,040h                ; start of hardware int's (0x20)
-        out     021h,al
-        dw   0x00eb,0x00eb
-        mov     al,048h                ; start of hardware int's 2 (0x28)
-        out     0A1h,al
-        dw   0x00eb,0x00eb
-        mov     al,04h                ; 8259-1 is master
-        out     021h,al
-        dw  0x00eb,0x00eb
-        mov     al,002h                ; 8259-2 is slave
-        out     0A1h,al
-        dw   0x00eb,0x00eb
-        mov     al,01h                ; 8086 mode for both
-        out     021h,al
-        dw  0x00eb,0x00eb
-        out     0A1h,al
-        dw   0x00eb,0x00eb
-        mov     al,0FFh                ; mask off all interrupts for now
-        out     021h,al
-        dw   0x00eb,0x00eb
-        out     0A1h,al
-
-        ;
-        ; Load stack
-        ;
-        mov     bx,ds
-        movzx   eax,bx
-        shl     eax,4
-        add     eax,real_stack_end
-        mov     [real_stack_base],eax
-        mov     esp,[real_stack_base]
-        mov     edx,[boot_param_struct_base]
-
-        ;
-        ; load gdt
-        ;
-        lgdt    [gdt_descr]
-
-        ;       
-        ; Enter pmode and clear prefetch queue
-        ;
-        mov     eax,cr0
-        or      eax,0x80000001
-        mov     cr0,eax
-        jmp     next
-next:
-        ;
-        ; NOTE: This must be position independant (no references to
-        ; non absolute variables)
-        ;
-
-        ;
-        ; Initalize segment registers
-        ;
-        mov     ax,KERNEL_DS
-        mov     ds,ax
-        mov     ss,ax        
-        mov     es,ax
-        mov     fs,ax
-        mov     gs,ax
-
-        ;
-        ; Initalize eflags
-        ;
-        push    dword 0
-        popf
-
-        ;
-        ; Jump to start of 32 bit code at c0000000
-        ;
-        push    edx
-        push    dword 0
-        jmp     dword KERNEL_CS:(KERNEL_BASE+0x1000)
-
+       dd      _gdt
 
-;
-; Our initial stack
-;
+       ;;
+       ;; Our initial stack
+       ;;
 real_stack times 1024 db 0
 real_stack_end:
 
-real_stack_base dd 0
-
-
-;
-; Global descriptor table
-;
-align 8
-gdt:
-        dw 0               ; Zero descriptor
-        dw 0
-        dw 0
-        dw 0
-                                
-        ;dw 00000h          ; User code descriptor
-        ;dw 00000h          ; base: 0h limit: 3gb
-        ;dw 0fa00h
-        ;dw 000cch
-                               
-        ;dw 00000h          ; User data descriptor
-        ;dw 00000h          ; base: 0h limit: 3gb
-        ;dw 0f200h
-        ;dw 000cch
-                            
-        ;dw 00000h          
-        ;dw 00000h         
-        ;dw 00000h
-        ;dw 00000h
-
-        dw 0ffffh          ; Kernel code descriptor 
-        dw 00000h          ; 
-        dw 09a00h          ; base 0h limit 4gb
-        dw 000cfh
-                               
-        dw 0ffffh          ; Kernel data descriptor
-        dw 00000h          ; 
-        dw 09200h          ; base 0h limit 4gb
-        dw 000cfh
-
-                                
-        ;times NR_TASKS*8 db 0
-
-_end:
-
-
-
+       ;;
+       ;; DOS commandline buffer
+       ;;
+dos_cmdline times 256 db 0
+dos_cmdline_end dw 0
+
+       ;;
+       ;; Boot information structure
+       ;;
+_multiboot_info_base:
+       dd      0x0
+
+_multiboot_info:
+_multiboot_flags:
+       dd      0x0
+_multiboot_mem_lower:
+       dd      0x0
+_multiboot_mem_upper:
+       dd      0x0
+_multiboot_boot_device:
+       dd      0x0
+_multiboot_cmdline:    
+       dd      0x0
+_multiboot_mods_count:
+       dd      0x0
+_multiboot_mods_addr:
+       dd      0x0
+_multiboot_syms:
+       times 12 db 0
+_multiboot_mmap_length:
+       dd      0x0
+_multiboot_mmap_addr:
+       dd      0x0
+_multiboot_drives_count:
+       dd      0x0
+_multiboot_drives_addr:
+       dd      0x0
+_multiboot_config_table:
+       dd      0x0
+_multiboot_boot_loader_name:
+       dd      0x0
+_multiboot_apm_table:
+       dd      0x0
+
+_multiboot_modules:    
+       times (64*multiboot_module_size) db 0
+_multiboot_module_strings:
+       times (64*256) db 0
+
+_multiboot_address_range_descriptor_size dd 0
+
+_multiboot_address_ranges:
+       times (64*multiboot_address_range_size) db 0
+
+_multiboot_kernel_cmdline:
+       db 'multi(0)disk(0)rdisk(0)partition(1)\reactos /DEBUGPORT=SCREEN'
+       times 255-($-_multiboot_kernel_cmdline) db 0
+
+       ;;
+       ;; Global descriptor table
+       ;;
+_gdt:  
+       dw      0x0             ; Zero descriptor
+       dw      0x0
+       dw      0x0
+       dw      0x0
+
+       dw      0xffff          ; Kernel code descriptor
+       dw      0x0000
+       dw      0x9a00
+       dw      0x00cf
+
+       dw      0xffff          ;  Kernel data descriptor
+       dw      0x0000
+       dw      0x9200
+       dw      0x00cf
+
+       dw      0xffff          ;  Loader code descriptor
+_loader_code_base_0_15:
+       dw      0x0000
+_loader_code_base_16_23:
+       db      0x00
+       db      0x9a
+       dw      0x0000
+       
+       dw      0xffff          ;  Loader data descriptor
+_loader_data_base_0_15:
+       dw      0x0000
+_loader_data_base_16_23:
+       db      0x00
+       db      0x92
+       dw      0x0000
+
+error_pmode_already:
+       db      'Error: The processor is already in protected mode'
+       db      0xa, 0xd, '$'
+error_file_open_failed:
+       db      'Error: Failed to open file'
+       db      0xa, 0xd, '$'
+error_file_seek_failed:
+       db      'Error: File seek failed'
+       db      0xa, 0xd, '$'
+error_file_read_failed:
+       db      'Error: File read failed'
+       db      0xa, 0xd, '$'
+error_coff_load_failed:
+       db      'Error: Failed to load COFF file'
+       db      0xa, 0xd, '$'
+error_bad_mz:
+       db      'Error: Bad DOS EXE magic'
+       db      0xa, 0xd, '$'