OK, that did in fact fix the immediate problem of how the code section is getting written to. The current version of the loading code (which I will push to the repo ASAP) is
Code: Select all
load_kernel_code:
push ax
push es
mov si, kernel_filename
mov di, word [bp - stg2_parameters.directory_buffer]
mov cx, Root_Entries
mov bx, dir_entry_size
call near seek_directory_entry
cmp di, word 0
jnz .read_directory
write no_kernel
jmp local_halt_loop
.read_directory:
call read_directory_details
write kernel_file_found
; reset the disk drive
call near reset_disk
mov di, word [bp - stg2_parameters.fat_0]
mov ax, kernel_raw_base
mov es, ax
mov si, kernel_raw_offset
call near fat_to_file
pop es
pop ax
write kernel_loaded
find_kernel_code_block:
push gs
mov ax, kernel_raw_base
mov gs, ax
mov al, byte gs:[kernel_raw_offset + ELF32_Header.magic]
cmp al, byte ELF_Magic
je .test_signature
write invalid_elf_magic
jmp local_halt_loop
.test_signature:
mov cx, 3
mov di, kernel_raw_offset + ELF32_Header.sig
push es
mov ax, kernel_raw_base
mov es, ax
mov si, ELF_Sig
repe cmpsb
pop es
je .test_elf_endianness
write invalid_elf_sig
jmp local_halt_loop
.test_elf_endianness:
mov al, byte gs:[kernel_raw_offset + ELF32_Header.endianness]
cmp al, ELF_little_endian
je .test_elf_isa
write elf_big_endian
jmp local_halt_loop
.test_elf_isa:
mov al, byte gs:[kernel_raw_offset + ELF32_Header.isa]
cmp al, ELF_ISA_x86
je .test_elf_executable
write elf_not_x86
jmp local_halt_loop
.test_elf_executable:
mov ax, word gs:[kernel_raw_offset + ELF32_Header.type]
cmp ax, ELF_type_executable
je .read_elf_header_table
write non_executable_elf_file
jmp local_halt_loop
.read_elf_header_table:
write valid_elf_file
; set up an offset for the code sections in memory
mov [section_offset], word kcode_offset
mov cx, gs:[kernel_raw_offset + ELF32_Header.program_table_entry_count]
write number_of_sections
mov ax, cx
call print_decimal_word
write newline
; while most of the size fields in the ELF32 header are 32-bit dwords,
; a number of places in this code assume that the amounts in question
; are under 64KiB, and can be read with a 16-bit word. This is a reasonable
; assumption with the current code, but may not hold if the kernel grows
; beyond it's current <64KiB size.
; bx = pointer to the first program header - location must be under 64KiB to work
mov bx, word gs:[kernel_raw_offset + ELF32_Header.program_header_table]
.program_header_loop:
; check to see if the section is loadable
mov ax, gs:[bx + ELF32_Program_Header.p_type]
cmp ax, ELF_Header_loadable_type
jne .loop_continue ; not a loadable section, skip
; found a loadable section
; first, clear the region of memory to load to
push es
mov ax, kernel_base
mov es, ax ; set es to the segment to later map to higher half
mov dx, gs:[bx + ELF32_Program_Header.p_memsz]
memset_rm 0, dx, [section_offset]
; move the code section of the file to the kernel code memory area
; keep ES set to the destination segment
mov dx, [section_offset]
push ds ; temporarily set DS = GS so the macro works on the right segments
mov ax, gs
mov ds, ax
memcopy_rm dx, [bx + ELF32_Program_Header.p_offset], [bx + ELF32_Program_Header.p_filesz]
pop ds
pop es
mov dx, gs:[bx + ELF32_Program_Header.p_memsz]
add [section_offset], dx ; dx = total size to allocate to the kernel code memory area
.loop_continue:
; advance the pointer through the header array
add bx, ELF32_Program_Header_size
add [section_offset], dx ; dx = total size to allocate to the kernel code memory area
loop .program_header_loop
pop gs
The disassembly is now:
Code: Select all
0xc0000000: call 0xc0000008
0xc0000005: hlt
0xc0000006: jmp 0xc0000005
0xc0000008: push %ebp
0xc0000009: mov %esp,%ebp
0xc000000b: sub $0x8,%esp
0xc000000e: call 0xc0000158
0xc0000013: sub $0x8,%esp
0xc0000016: push $0x7
0xc0000018: push $0xc0001000
0xc000001d: call 0xc0000110
0xc0000022: add $0x10,%esp
0xc0000025: nop
0xc0000026: leave
0xc0000027: ret
0xc0000028: push %ebp
0xc0000029: mov %esp,%ebp
0xc000002b: mov 0xc0002004,%eax
0xc0000030: add $0x2,%eax
0xc0000033: mov %eax,0xc0002004
0xc0000038: movzwl 0xc0003002,%eax
0xc000003f: mov $0x50,%edx
0xc0000044: cmp %dx,%ax
0xc0000047: jae 0xc000005b
0xc0000049: movzwl 0xc0003002,%eax
0xc0000050: add $0x1,%eax
0xc0000053: mov %ax,0xc0003002
0xc0000059: jmp 0xc0000085
0xc000005b: movw $0x0,0xc0003002
0xc0000064: movzwl 0xc0003000,%eax
0xc000006b: mov $0x19,%edx
0xc0000070: cmp %dx,%ax
0xc0000073: jae 0xc0000085
0xc0000075: movzwl 0xc0003000,%eax
0xc000007c: add $0x1,%eax
0xc000007f: mov %ax,0xc0003000
0xc0000085: nop
0xc0000086: pop %ebp
0xc0000087: ret
0xc0000088: push %ebp
0xc0000089: mov %esp,%ebp
0xc000008b: sub $0x18,%esp
0xc000008e: mov 0x8(%ebp),%edx
0xc0000091: mov 0xc(%ebp),%eax
0xc0000094: mov %dx,-0x14(%ebp)
0xc0000098: mov %ax,-0x18(%ebp)
0xc000009c: mov $0x19,%eax
0xc00000a1: movzwl %ax,%edx
0xc00000a4: mov $0x50,%eax
0xc00000a9: movzwl %ax,%eax
0xc00000ac: imul %edx,%eax
0xc00000af: add $0xb8000,%eax
0xc00000b4: mov %eax,-0x4(%ebp)
0xc00000b7: mov 0xc0002004,%eax
0xc00000bc: mov %eax,%edx
0xc00000be: mov -0x4(%ebp),%eax
0xc00000c1: add %edx,%eax
0xc00000c3: mov %eax,0xc0002004
0xc00000c8: movzwl -0x14(%ebp),%eax
0xc00000cc: mov %ax,0xc0003002
0xc00000d2: movzwl -0x18(%ebp),%eax
0xc00000d6: mov %ax,0xc0003000
0xc00000dc: nop
0xc00000dd: leave
0xc00000de: ret
0xc00000df: push %ebp
0xc00000e0: mov %esp,%ebp
0xc00000e2: sub $0x8,%esp
0xc00000e5: mov 0x8(%ebp),%edx
0xc00000e8: mov 0xc(%ebp),%eax
0xc00000eb: mov %dl,-0x4(%ebp)
0xc00000ee: mov %al,-0x8(%ebp)
0xc00000f1: mov 0xc0002004,%eax
0xc00000f6: movzbl -0x4(%ebp),%edx
0xc00000fa: mov %dl,(%eax)
0xc00000fc: mov 0xc0002004,%eax
0xc0000101: movzbl -0x8(%ebp),%edx
0xc0000105: mov %dl,0x1(%eax)
0xc0000108: call 0xc0000028
0xc000010d: nop
0xc000010e: leave
0xc000010f: ret
0xc0000110: push %ebp
0xc0000111: mov %esp,%ebp
0xc0000113: sub $0x14,%esp
0xc0000116: mov 0xc(%ebp),%eax
0xc0000119: mov %al,-0x14(%ebp)
0xc000011c: movl $0x0,-0x4(%ebp)
0xc0000123: jmp 0xc0000145
0xc0000125: movzbl -0x14(%ebp),%edx
0xc0000129: mov -0x4(%ebp),%ecx
0xc000012c: mov 0x8(%ebp),%eax
0xc000012f: add %ecx,%eax
0xc0000131: movzbl (%eax),%eax
0xc0000134: movsbl %al,%eax
0xc0000137: push %edx
0xc0000138: push %eax
0xc0000139: call 0xc00000df
0xc000013e: add $0x8,%esp
0xc0000141: addl $0x1,-0x4(%ebp)
0xc0000145: mov -0x4(%ebp),%edx
0xc0000148: mov 0x8(%ebp),%eax
0xc000014b: add %edx,%eax
0xc000014d: movzbl (%eax),%eax
0xc0000150: test %al,%al
0xc0000152: jne 0xc0000125
0xc0000154: nop
0xc0000155: nop
0xc0000156: leave
0xc0000157: ret
0xc0000158: push %ebp
0xc0000159: mov %esp,%ebp
0xc000015b: sub $0x10,%esp
0xc000015e: movl $0x0,-0x4(%ebp)
0xc0000165: jmp 0xc0000177
0xc0000167: push $0x0
0xc0000169: push $0x20
0xc000016b: call 0xc00000df
0xc0000170: add $0x8,%esp
0xc0000173: addl $0x1,-0x4(%ebp)
0xc0000177: mov $0x7d0,%eax
0xc000017c: movzwl %ax,%eax
0xc000017f: cmp %eax,-0x4(%ebp)
0xc0000182: jl 0xc0000167
0xc0000184: nop
0xc0000185: nop
0xc0000186: leave
0xc0000187: ret
It looks as if the code should now run, and it appears that it does when I step into it - except that I now need to debug the terminal-handling code.