about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-12-19 21:09:05 -0800
committerKartik Agaram <vc@akkartik.com>2020-12-19 21:09:05 -0800
commit1e46a0f6b25bc6fdc6042d13fcf691c85fe235be (patch)
treea80795f2575d3d7d333985ea5bab8565561d2226
parenta84fadd65d923fbb71c5c2b9884972114a0c2928 (diff)
downloadmu-1e46a0f6b25bc6fdc6042d13fcf691c85fe235be.tar.gz
7356
-rw-r--r--apps/bos/4.asm124
-rw-r--r--apps/bos/gdt.asm46
-rw-r--r--apps/bos/print_string.asm11
-rw-r--r--apps/bos/print_string_pm.asm21
-rw-r--r--apps/bos/switch_to_pm.asm34
5 files changed, 115 insertions, 121 deletions
diff --git a/apps/bos/4.asm b/apps/bos/4.asm
index ae079446..067ae95f 100644
--- a/apps/bos/4.asm
+++ b/apps/bos/4.asm
@@ -5,11 +5,6 @@
 ;   qemu-system-i386 boot.bin
 ; Or:
 ;   bochs  # bochsrc loads boot.bin
-#
-# Expected output inside emulator:
-#   Started in 16-bit Real Mode
-#   Successfully landed in 32-bit Protected Mode
-# Look for the second line at the top of the emulated screen.
 
 ; A boot sector that enters 32-bit protected mode.
 [org 0x7c00]
@@ -24,10 +19,121 @@
 
   jmp $
 
-%include "print_string.asm"
-%include "gdt.asm"
-%include "print_string_pm.asm"
-%include "switch_to_pm.asm"
+print_string:
+    pusha
+    mov ah, 0x0e
+loop:
+    mov al, [bx]
+    int 0x10
+    add bx, 1
+    cmp al, 0
+    jne loop
+    popa
+    ret
+
+; GDT
+gdt_start:
+
+gdt_null:  ; the mandatory null descriptor
+  dd 0x0  ; ’dd’ means define double word (i.e. 4 bytes)
+  dd 0x0
+
+gdt_code: ; the code segment descriptor
+  ; base=0x0, limit=0xfffff,
+  ; 1st flags: (present)1 (privilege)00 (descriptor type)1 -> 1001b
+  ; type flags: (code)1 (conforming)0 (readable)1 (accessed )0 -> 1010b
+  ; 2nd flags: (granularity)1 (32-bit default)1 (64-bit seg)0 (AVL)0 -> 1100b
+  dw 0xffff     ; Limit (bits 0-15)
+  dw 0x0        ; Base (bits 0-15)
+  db 0x0        ; Base (bits 16 -23)
+  db 10011010b  ; 1st flags, type flags
+  db 11001111b  ; 2nd flags, Limit (bits 16-19)
+  db 0x0        ; Base (bits 24 -31)
+
+gdt_data: ;the  data segment descriptor
+  ; Same as code segment except for the type flags:
+  ; type flags: (code)0 (expand down)0 (writable)1 (accessed)0 -> 0010b
+  dw 0xffff    ; Limit (bits 0-15)
+  dw 0x0       ; Base (bits 0-15)
+  db 0x0       ; Base (bits 16 -23)
+  db 10010010b ; 1st flags, type flags
+  db 11001111b ; 2nd flags, Limit (bits 16-19)
+  db 0x0       ; Base (bits 24 -31)
+
+gdt_end:       ; The reason for putting a label at the end of the
+               ; GDT is so we can have the assembler calculate
+               ; the size of the GDT for the GDT decriptor (below)
+
+; GDT descriptor
+gdt_descriptor:
+  dw gdt_end - gdt_start - 1  ; Size of our GDT, always less one
+                              ; of the true size
+  dd gdt_start                ; Start address of our GDT
+
+; Define some handy constants for the GDT segment descriptor offsets, which
+; are what segment registers must contain when in protected mode. For example,
+; when we set DS = 0x10 in PM , the CPU knows that we mean it to use the
+; segment described at offset 0x10 (i.e. 16 bytes) in our GDT, which in our
+; case is the DATA segment (0x0 -> NULL; 0x08 -> CODE; 0x10 -> DATA)
+CODE_SEG equ gdt_code - gdt_start
+DATA_SEG equ gdt_data - gdt_start
+
+[bits  32]
+; Define  some  constants
+VIDEO_MEMORY  equ 0xb8000
+WHITE_ON_BLACK  equ 0x0f
+; prints a null -terminated  string  pointed  to by EDX
+print_string_pm:
+  pusha
+  mov edx, VIDEO_MEMORY  ; Set  edx to the  start  of vid  mem.
+print_string_pm_loop:
+  mov al, [ebx]          ; Store  the  char at EBX in AL
+  mov ah, WHITE_ON_BLACK ; Store  the  attributes  in AH
+  cmp al, 0         ; if (al == 0), at end of string , so
+  je print_string_pm_done
+  mov [edx], ax     ; Store  char  and  attributes  at  current
+                    ; character  cell.
+  add ebx , 1       ; Increment  EBX to the  next  char in  string.
+  add edx , 2       ; Move to next  character  cell in vid  mem.
+  jmp  print_string_pm_loop   ; loop  around  to  print  the  next  char.
+print_string_pm_done:
+  popa
+  ret               ; Return  from  the  function
+
+[bits 16]
+; Switch to protected mode
+switch_to_pm:
+  cli                     ; We must switch of interrupts until we have
+                          ; set up the protected mode interrupt vector
+                          ; otherwise interrupts will run riot.
+
+  lgdt [gdt_descriptor]   ; Load our global descriptor table, which defines
+                          ; the protected mode segments (e.g. for code and data)
+
+  mov eax, cr0            ; To make the switch to protected mode, we set
+  or eax, 0x1             ; the first bit of CR0, a control register
+  mov cr0, eax
+
+  jmp CODE_SEG:init_pm    ; Make a far jump (i.e. to a new segment) to our 32-bit
+                          ; code. This also forces the CPU to flush its cache of
+                          ; prefetched and real-mode decoded instructions, which can
+                          ; cause problems.
+
+[bits 32]
+; Initialise registers and the stack once in PM.
+init_pm:
+
+  mov ax, DATA_SEG        ; Now in PM, our old segments are meaningless,
+  mov ds, ax              ; so we point our segment registers to the
+  mov ss, ax              ; data selector we defined in our GDT
+  mov es, ax
+  mov fs, ax
+  mov gs, ax
+
+  mov ebp, 0x90000        ; Update our stack position so it is right
+  mov esp, ebp            ; at the top of the free space.
+
+  call BEGIN_PM           ; Finally, call some well-known label
 
 [bits 32]
 ; This is where we arrive after switching to and initialising protected mode.
diff --git a/apps/bos/gdt.asm b/apps/bos/gdt.asm
deleted file mode 100644
index d9703551..00000000
--- a/apps/bos/gdt.asm
+++ /dev/null
@@ -1,46 +0,0 @@
-; GDT
-gdt_start:
-
-gdt_null:  ; the mandatory null descriptor
-  dd 0x0  ; ’dd’ means define double word (i.e. 4 bytes)
-  dd 0x0
-
-gdt_code: ; the code segment descriptor
-  ; base=0x0, limit=0xfffff,
-  ; 1st flags: (present)1 (privilege)00 (descriptor type)1 -> 1001b
-  ; type flags: (code)1 (conforming)0 (readable)1 (accessed )0 -> 1010b
-  ; 2nd flags: (granularity)1 (32-bit default)1 (64-bit seg)0 (AVL)0 -> 1100b
-  dw 0xffff     ; Limit (bits 0-15)
-  dw 0x0        ; Base (bits 0-15)
-  db 0x0        ; Base (bits 16 -23)
-  db 10011010b  ; 1st flags, type flags
-  db 11001111b  ; 2nd flags, Limit (bits 16-19)
-  db 0x0        ; Base (bits 24 -31)
-
-gdt_data: ;the  data segment descriptor
-  ; Same as code segment except for the type flags:
-  ; type flags: (code)0 (expand down)0 (writable)1 (accessed)0 -> 0010b
-  dw 0xffff    ; Limit (bits 0-15)
-  dw 0x0       ; Base (bits 0-15)
-  db 0x0       ; Base (bits 16 -23)
-  db 10010010b ; 1st flags, type flags
-  db 11001111b ; 2nd flags, Limit (bits 16-19)
-  db 0x0       ; Base (bits 24 -31)
-
-gdt_end:       ; The reason for putting a label at the end of the
-               ; GDT is so we can have the assembler calculate
-               ; the size of the GDT for the GDT decriptor (below)
-
-; GDT descriptor
-gdt_descriptor:
-  dw gdt_end - gdt_start - 1  ; Size of our GDT, always less one
-                              ; of the true size
-  dd gdt_start                ; Start address of our GDT
-
-; Define some handy constants for the GDT segment descriptor offsets, which
-; are what segment registers must contain when in protected mode. For example,
-; when we set DS = 0x10 in PM , the CPU knows that we mean it to use the
-; segment described at offset 0x10 (i.e. 16 bytes) in our GDT, which in our
-; case is the DATA segment (0x0 -> NULL; 0x08 -> CODE; 0x10 -> DATA)
-CODE_SEG equ gdt_code - gdt_start
-DATA_SEG equ gdt_data - gdt_start
diff --git a/apps/bos/print_string.asm b/apps/bos/print_string.asm
deleted file mode 100644
index 555e4d52..00000000
--- a/apps/bos/print_string.asm
+++ /dev/null
@@ -1,11 +0,0 @@
-print_string:
-    pusha
-    mov ah, 0x0e
-loop:
-    mov al, [bx]
-    int 0x10
-    add bx, 1
-    cmp al, 0
-    jne loop
-    popa
-    ret
diff --git a/apps/bos/print_string_pm.asm b/apps/bos/print_string_pm.asm
deleted file mode 100644
index 78904671..00000000
--- a/apps/bos/print_string_pm.asm
+++ /dev/null
@@ -1,21 +0,0 @@
-[bits  32]
-; Define  some  constants
-VIDEO_MEMORY  equ 0xb8000
-WHITE_ON_BLACK  equ 0x0f
-; prints a null -terminated  string  pointed  to by EDX
-print_string_pm:
-  pusha
-  mov edx, VIDEO_MEMORY  ; Set  edx to the  start  of vid  mem.
-print_string_pm_loop:
-  mov al, [ebx]          ; Store  the  char at EBX in AL
-  mov ah, WHITE_ON_BLACK ; Store  the  attributes  in AH
-  cmp al, 0         ; if (al == 0), at end of string , so
-  je print_string_pm_done
-  mov [edx], ax     ; Store  char  and  attributes  at  current
-                    ; character  cell.
-  add ebx , 1       ; Increment  EBX to the  next  char in  string.
-  add edx , 2       ; Move to next  character  cell in vid  mem.
-  jmp  print_string_pm_loop   ; loop  around  to  print  the  next  char.
-print_string_pm_done:
-  popa
-  ret               ; Return  from  the  function
diff --git a/apps/bos/switch_to_pm.asm b/apps/bos/switch_to_pm.asm
deleted file mode 100644
index aeef97c0..00000000
--- a/apps/bos/switch_to_pm.asm
+++ /dev/null
@@ -1,34 +0,0 @@
-[bits 16]
-; Switch to protected mode
-switch_to_pm:
-  cli                     ; We must switch of interrupts until we have
-                          ; set up the protected mode interrupt vector
-                          ; otherwise interrupts will run riot.
-
-  lgdt [gdt_descriptor]   ; Load our global descriptor table, which defines
-                          ; the protected mode segments (e.g. for code and data)
-
-  mov eax, cr0            ; To make the switch to protected mode, we set
-  or eax, 0x1             ; the first bit of CR0, a control register
-  mov cr0, eax
-
-  jmp CODE_SEG:init_pm    ; Make a far jump (i.e. to a new segment) to our 32-bit
-                          ; code. This also forces the CPU to flush its cache of
-                          ; prefetched and real-mode decoded instructions, which can
-                          ; cause problems.
-
-[bits 32]
-; Initialise registers and the stack once in PM.
-init_pm:
-
-  mov ax, DATA_SEG        ; Now in PM, our old segments are meaningless,
-  mov ds, ax              ; so we point our segment registers to the
-  mov ss, ax              ; data selector we defined in our GDT
-  mov es, ax
-  mov fs, ax
-  mov gs, ax
-
-  mov ebp, 0x90000        ; Update our stack position so it is right
-  mov esp, ebp            ; at the top of the free space.
-
-  call BEGIN_PM           ; Finally, call some well-known label