CeDOS - Commit 72d8656a

Moved functions for A20 gate and drive access to separate files
Celina Kalus
Sat, 18 Mar 2023 16:32:26 +0100
3 files changed, 336 insertions(+), 294 deletions(-)
A src/boot/a20.s

@@ -0,0 +1,149 @@

+.section .text +.code16 + # check if A20 gate is enabled +.global enable_a20 +enable_a20: + mov $a20_check_msg, %si + call print + call checkA20 + je enabled + + # A20 is disabled, we need to enable it + mov $disabled_msg, %si + call print + + mov $a20_enable_msg, %si + call print + + # A20 BIOS method +a20_bios: + mov $a20_enable_bios_msg, %si + call print + + movw $0x2401, %ax + int $0x15 + + mov $0x0001, %cx + call delay + + call checkA20 + je enabled + + mov $fail_msg, %si + call print + + # A20 keyboard controller method +a20_keyboard: + mov $a20_enable_kb_msg, %si + call print + + # TODO: implement + + mov $0x0001, %cx + call delay + + call checkA20 + je enabled + + mov $fail_msg, %si + call print + + # fast A20 method +a20_fasta20: + mov $a20_enable_fasta20_msg, %si + call print + + inb $0x92, %al + orb $0x02, %al + andb $0xFE, %al + outb %al, $0x92 + + mov $0x1000, %cx + call delay + + call checkA20 + je enabled + + mov $fail_msg, %si + call print + + mov $a20_fail, %si + call print + + jmp error + + +enabled: + mov $enabled_msg, %si + call print + + ret + + + # ############################################ + # checkA20 + # checks if A20 line is enabled + # equal flag: * clear, if A20 is enabled + # * set, if A20 is disabled + # ############################################ +checkA20: + push %ds + push %es + push %si + push %di + + mov $0x0000, %ax + mov %ax, %ds + mov $0xFFFF, %ax + mov %ax, %es + + mov $0x0500, %si + mov $0x0510, %di + + movw %ds:(%si), %cx + movw %es:(%di), %dx + cmp %cx, %dx + + pop %di + pop %si + pop %es + pop %ds + ret + + + # delays for at least a given number of cycles. + # CX: number of cycles to delay +delay: + nop + loop delay + ret + + +.section .data +a20_check_msg: + .ascii "Checking A20..." + .byte 0 + +a20_enable_msg: + .ascii "Enabling A20 (BIOS)..." + .byte 13 + .byte 10 + .byte 0 + +a20_fail: + .ascii "Could not enable A20 gate. HALT" + .byte 13 + .byte 10 + .byte 0 + +a20_enable_bios_msg: + .ascii " BIOS: " + .byte 0 + +a20_enable_kb_msg: + .ascii " keyboard controller: " + .byte 0 + +a20_enable_fasta20_msg: + .ascii " fast A20 method: " + .byte 0
A src/boot/drives.s

@@ -0,0 +1,174 @@

+.section .text +.code16 +# read hard drive parameters +.global read_drive_params +read_drive_params: + mov $drive_params_msg, %si + call print + + movw $0x0000, %ax + movw %ax, %es + movw $0x0000, %di + + movb $0x08, %ah + lea bootdriv_id, %si + movb (%si), %dl + int $0x13 + + xor %ax, %ax + movb %dl, %al + lea num_drives, %si + movb %al, (%si) + + xor %ax, %ax + movb %dh, %al + inc %ax + lea num_heads, %si + movw %ax, (%si) + + xor %ax, %ax + movb %cl, %al + shl $2, %ax + movb %ch, %al + inc %ax + lea num_cylinders, %si + movw %ax, (%si) + + xor %ax, %ax + movb %cl, %al + and $0x003F, %ax + lea num_sectors, %si + movw %ax, (%si) + + mov $done_msg, %si + call print + + ret + + + # reset bootdrive +.global reset_drive +reset_drive: + mov $10, %cx +reset_drive_loop: + push %cx + movw $reset_msg, %si + call print + + movb $0x00, %ah + int $0x13 + pop %cx + jnc reset_end + loop reset_drive_loop + jc error +reset_end: + + movw $done_msg, %si + call print + + ret + + + # load second stage into memory starting at adress 0x10000 + # (NOTE: this code can only be jumped to after loading the global descriptor table + # because it uses absolute adresses larger than 16 bit) + # (NOTE2: this routine only loads 0x48 sectors of the second stage into memory + # and is in general pretty whacky. should be replaced with sth more serious) + +# arguments: +# - ax: first sector (LBA) +# - cx: last sector (LBA) +# - bx: address offset +.global load_kernel +load_kernel: + movw $load_msg, %si + call print + + movw $0x0000, %ax + movw %ax, %ds + + movw $0x0008, %ax + movw $0x0088, %cx + movw $0x0000, %bx + +load_sectors_loop: + push %ax + push %cx + push %bx + + movw %bx, %di + + lea num_sectors, %si + movw (%si), %bx + inc %ax + divb %bl + movb %ah, %cl + + xor %ah, %ah + lea num_heads, %si + movw (%si), %bx + divb %bl + movb %ah, %dh + movb %al, %ch + + lea bootdriv_id, %si + movb (%si), %dl + + movw %di, %bx + # movw $0x0000, %bx # buffer address + movw $0x1000, %ax + movw %ax, %es # buffer address (segment) + + movb $0x02, %ah # function 0x02: read a sector + movb $0x01, %al # sectors to read count + # dl (drive) keep as is + int $0x13 + # jc error + + pop %bx + pop %cx + pop %ax + inc %ax + add $0x200, %bx + cmp %ax, %cx + jne load_sectors_loop + +load_end: + movw $0x0000, %si # buffer address + movw $0x1000, %ax + movw %ax, %es + call print + + movw $done_msg, %si + call print + + +.section .data +drive_params_msg: + .ascii "Reading drive parameters..." + .byte 0 + +reset_msg: + .ascii "Resetting bootdrive..." + .byte 0 + +load_msg: + .ascii "Loading kernel..." + .byte 0 + +.section .bss +.global bootdriv_id +bootdriv_id: + .byte 0 + +num_drives: + .byte 0 + +num_sectors: + .word 0 + +num_cylinders: + .word 0 + +num_heads: + .word 0
M src/boot/entry.ssrc/boot/entry.s

@@ -47,6 +47,7 @@ int $0x13

jnc bl_loaded # auxiliary functions +.global error error: movw $fail_msg, %si call print

@@ -59,6 +60,7 @@ # print

# prints out a string on the screen # %si: points to the message to be printed # ############################################ +.global print print: movw $0x0000, %bx movb $0x0E, %ah

@@ -92,208 +94,13 @@ bl_loaded:

mov $done_msg, %si call print - # read hard drive parameters - movw $0x0000, %ax - movw %ax, %es - movw $0x0000, %di - - movb $0x08, %ah - lea bootdriv_id, %si - movb (%si), %dl - int $0x13 - - xor %ax, %ax - movb %dl, %al - lea num_drives, %si - movb %al, (%si) - - xor %ax, %ax - movb %dh, %al - inc %ax - lea num_heads, %si - movw %ax, (%si) - - xor %ax, %ax - movb %cl, %al - shl $2, %ax - movb %ch, %al - inc %ax - lea num_cylinders, %si - movw %ax, (%si) - - xor %ax, %ax - movb %cl, %al - and $0x003F, %ax - lea num_sectors, %si - movw %ax, (%si) - - - # check if A20 gate is enabled - mov $a20_check_msg, %si - call print - call checkA20 - je enabled - - # A20 is disabled, we need to enable it - mov $disabled_msg, %si - call print - - mov $a20_enable_msg, %si - call print - - # A20 BIOS method -a20_bios: - mov $a20_enable_bios_msg, %si - call print - - movw $0x2401, %ax - int $0x15 - - mov $0x0001, %cx - call delay - - call checkA20 - je enabled - - mov $fail_msg, %si - call print - - # A20 keyboard controller method -a20_keyboard: - mov $a20_enable_kb_msg, %si - call print - - # TODO: implement - - mov $0x0001, %cx - call delay - - call checkA20 - je enabled - - mov $fail_msg, %si - call print + call read_drive_params - # fast A20 method -a20_fasta20: - mov $a20_enable_fasta20_msg, %si - call print + call enable_a20 - inb $0x92, %al - orb $0x02, %al - andb $0xFE, %al - outb %al, $0x92 + call reset_drive - mov $0x1000, %cx - call delay - - call checkA20 - je enabled - - mov $fail_msg, %si - call print - - mov $a20_fail, %si - call print - - jmp error_loop - - -enabled: - mov $enabled_msg, %si - call print - - # reset bootdrive - mov $10, %cx -reset: - push %cx - movw $reset_msg, %si - call print - movw $bootdrive_msg, %si - call print - - movb $0x00, %ah - int $0x13 - pop %cx - jnc reset_end - loop reset - jc error -reset_end: - - movw $done_msg, %si - call print - - # load second stage into memory starting at adress 0x10000 - # (NOTE: this code can only be jumped to after loading the global descriptor table - # because it uses absolute adresses larger than 16 bit) - # (NOTE2: this routine only loads 0x48 sectors of the second stage into memory - # and is in general pretty whacky. should be replaced with sth more serious) - -# arguments: -# - ax: first sector (LBA) -# - cx: last sector (LBA) -# - bx: address offset -load_sectors: - movw $load_msg, %si - call print - - movw $0x0000, %ax - movw %ax, %ds - - movw $0x0008, %ax - movw $0x0088, %cx - movw $0x0000, %bx - -load_sectors_loop: - push %ax - push %cx - push %bx - - movw %bx, %di - - lea num_sectors, %si - movw (%si), %bx - inc %ax - divb %bl - movb %ah, %cl - - xor %ah, %ah - lea num_heads, %si - movw (%si), %bx - divb %bl - movb %ah, %dh - movb %al, %ch - - lea bootdriv_id, %si - movb (%si), %dl - - movw %di, %bx - # movw $0x0000, %bx # buffer address - movw $0x1000, %ax - movw %ax, %es # buffer address (segment) - - movb $0x02, %ah # function 0x02: read a sector - movb $0x01, %al # sectors to read count - # dl (drive) keep as is - int $0x13 - # jc error - - pop %bx - pop %cx - pop %ax - inc %ax - add $0x200, %bx - cmp %ax, %cx - jne load_sectors_loop - -load_end: - movw $0x0000, %si # buffer address - movw $0x1000, %ax - movw %ax, %es - call print - - movw $done_msg, %si - call print + call load_kernel movw $gdt_msg, %si call print

@@ -307,49 +114,12 @@

lidt (IDT_DESCRIPTOR) mov %cr0, %eax - or $1, %eax + or $0x00000001, %eax mov %eax, %cr0 - # jmp error_loop - + # perform long jump to set code segment ljmp $0x8, $protected - # ############################################ - # checkA20 - # checks if A20 line is enabled - # equal flag: * clear, if A20 is enabled - # * set, if A20 is disabled - # ############################################ -checkA20: - push %ds - push %es - push %si - push %di - - mov $0x0000, %ax - mov %ax, %ds - mov $0xFFFF, %ax - mov %ax, %es - - mov $0x0500, %si - mov $0x0510, %di - - movw %ds:(%si), %cx - movw %es:(%di), %dx - cmp %cx, %dx - - pop %di - pop %si - pop %es - pop %ds - ret - - # delays for at least a given number of cycles. - # CX: number of cycles to delay -delay: - nop - loop delay - ret .code32 protected:

@@ -384,67 +154,32 @@ jmp loop

.section .data -a20_check_msg: - .ascii "Checking A20..." - .byte 0 - -a20_enable_msg: - .ascii "Enabling A20 (BIOS)..." - .byte 13 - .byte 10 - .byte 0 - -a20_fail: - .ascii "Could not enable A20 gate. HALT" - .byte 13 - .byte 10 - .byte 0 - -a20_enable_bios_msg: - .ascii " BIOS: " - .byte 0 - -a20_enable_kb_msg: - .ascii " keyboard controller: " - .byte 0 - -a20_enable_fasta20_msg: - .ascii " fast A20 method: " - .byte 0 - -reset_msg: - .ascii "Resett" - .byte 0 - -load_msg: - .ascii "Load" - -bootdrive_msg: - .ascii "ing bootdrive..." - .byte 0 - gdt_msg: .ascii "Setting GDT..." .byte 0 +.global done_msg done_msg: .ascii "done" .byte 13 .byte 10 .byte 0 +.global fail_msg fail_msg: .ascii "fail" .byte 13 .byte 10 .byte 0 +.global enabled_msg enabled_msg: .ascii "enabled" .byte 13 .byte 10 .byte 0 +.global disabled_msg disabled_msg: .ascii "disabled" .byte 13

@@ -457,20 +192,4 @@ .int GDT

IDT_DESCRIPTOR: .word 0 - .int 0 - -.section .bss -bootdriv_id: - .byte 0 - -num_drives: - .byte 0 - -num_sectors: - .word 0 - -num_cylinders: - .word 0 - -num_heads: - .word 0+ .int 0