modified: README.md
modified: compiler/create_crosscompiler.sh deleted: notes modified: src/.gdb_history deleted: src/amd64_vol2.pdf modified: src/bootloader/bios_functions/bios_disk.asm modified: src/bootloader/bios_functions/print.asm modified: src/bootloader/bootloader.asm modified: src/bootloader/cpu_check.asm modified: src/bootloader/enter_kernel.asm deleted: src/bootloader/enter_kernel_backup modified: src/bootloader/gdt.asm deleted: src/bootloader/multicore.asm deleted: src/bootloader/notes new file: src/debug/gdbinit.gdb deleted: src/indigo_os modified: src/kernel/include/libc.h modified: src/kernel/include/paging.h modified: src/kernel/include/video.h modified: src/kernel/kernel.c modified: src/kernel/libs/acpi.c modified: src/kernel/libs/drivers/serial.c modified: src/kernel/libs/drivers/video.c modified: src/kernel/libs/libc.c modified: src/kernel/libs/page.c modified: src/link.ld modified: src/makefile new file: tools/README.md modified: tools/page/page.py
This commit is contained in:
parent
13000d6f44
commit
14b109ea24
README.md
compiler
notessrc
.gdb_historyamd64_vol2.pdf
bootloader
bios_functions
bootloader.asmcpu_check.asmenter_kernel.asmenter_kernel_backupgdt.asmmulticore.asmnotesdebug
indigo_oskernel
link.ldmakefiletools
26
README.md
26
README.md
@ -1,17 +1,12 @@
|
||||
# IndigoOS
|
||||
|
||||
This project is in it's infancy. There's a lot to clean up (bootloader), and this is for my own entertainment. I'll likely be working on it on and off, and only updating the branch after major steps forward.
|
||||
IndigoOS (name likely to change) will be a unix-like operating system for x86-64 computers. I'm hoping to impliment many things a modern operating system would have, including a desktop enviornment, pre-emptive multithreading, ASLR, and memory protection. I'd also like to port games such as DOOM.
|
||||
|
||||
##Questions and answers
|
||||
### Why are you already parsing APCI tables?
|
||||
When I first started this project, it was intended to be a bare metal mandelbrotset, then an operating system. This way I could set up an enviornment and become comftorable with the x86 architecture. I was going to have a pretty simple multi-core SMP setup to acheive a higher speed. However, as I worked more and more, I realized that this plan was counter productive. The main reason for this is that I'd be doing a lot of "static" work (for lack of a better word). It would be too hard to modify an existing project into an operating system, due to all the code I'd need to discard.
|
||||
This project is in it's infancy. However, I'm making quick progress. I'll only commit major changes to keep the commit history clean.
|
||||
|
||||
### Will you support UEFI?
|
||||
Maybe some day. What I have so far of the bootloader was a lot of work, so I need to take a break on it for now.
|
||||
|
||||
##Cleaning list
|
||||
## Cleaning list
|
||||
- [] clean RSDP v1 vs v2+ ugly unison code
|
||||
- [] clean static paging code if possible
|
||||
- [] clean static paging code
|
||||
- [] fallback to best compatable video mode if not found
|
||||
- [] find out when and why checksum of binary vs debug binary stripped is occationally diffrent (maybe linker script?)
|
||||
|
||||
@ -19,7 +14,7 @@ Maybe some day. What I have so far of the bootloader was a lot of work, so I nee
|
||||
##debugging
|
||||
- [x] get debugging into into a seperate elf for GDB
|
||||
- [] md5sum of striped binary is the same as one built without debugging info
|
||||
_Almost_ always, there was one time when it wasn't. Can't seem to reproduce. Check linker sizes.
|
||||
_Almost_ always, there was one time when it wasn't. Can't seem to reproduce. Check linker sizes and included sections.
|
||||
|
||||
##bootloader
|
||||
- [x] make USB bootable as floppy
|
||||
@ -34,14 +29,15 @@ _Almost_ always, there was one time when it wasn't. Can't seem to reproduce. Che
|
||||
- [x] boot into kernel long mode
|
||||
|
||||
##kernel (listed in order of dependency)
|
||||
###Memory
|
||||
- [x] static page mapping
|
||||
- [] dynamic page allocation - 3/24/21, almost done, will likely finish soon.
|
||||
- [] remap paging to higher/more available physical address
|
||||
- [] remap kernel to higher virtual address
|
||||
|
||||
###ACPI
|
||||
- [x] find, check, and parse RSDP
|
||||
- [x] find, check, and parse RSDT or XSDT
|
||||
- [x] static page mapping
|
||||
- [] remap paging to higher/more available physical address
|
||||
- [] remap kernel to higher virtual address
|
||||
- [] re-create page tables to accomidate amount of ram in system without becoming too big
|
||||
- [] dynamic page allocation
|
||||
|
||||
###multicpu
|
||||
- [] boot cpus
|
||||
|
@ -18,7 +18,8 @@ mkdir src/build_gcc
|
||||
lftp -c "set xfer:clobber on; connect ftp.gnu.org; get -O src/packs/ gnu/binutils/$(lftp -c 'connect ftp.gnu.org; ls gnu/binutils/binutils*.tar.gz' | awk '{print $NF}' | sort -V | tail -n 1)"
|
||||
|
||||
#download gcc
|
||||
#yes, I know, I'm making too many connections, I'm tired as fuck rn
|
||||
# TODO clean up this script so we only need one connection
|
||||
|
||||
latest_gcc=$(lftp -c 'connect ftp.gnu.org; ls -d gnu/gcc/gcc-*' | grep -E "^d" | awk '{print $NF}' | sort -V | tail -1)
|
||||
lftp -c "set xfer:clobber on; connect ftp.gnu.org; get -O src/packs/ gnu/gcc/$latest_gcc/$latest_gcc.tar.gz"
|
||||
|
||||
|
23
notes
23
notes
@ -1,23 +0,0 @@
|
||||
| type start end size |
|
||||
| 1 1 0x0000000000000000 0x000000000009FC00 0x000000000009FC00 |
|
||||
| 2 1 0x000000000009FC00 0x00000000000A0000 0x0000000000000400 |
|
||||
| 2 1 0x00000000000E0000 0x0000000000100000 0x0000000000020000 |
|
||||
| 1 1 0x0000000000100000 0x00000000BA6E4000 0x00000000BA5E4000 |
|
||||
| 2 1 0x00000000BA6E4000 0x00000000BA868000 0x0000000000184000 |
|
||||
| 3 1 0x00000000BA868000 0x00000000BA878000 0x0000000000010000 |
|
||||
| 4 1 0x00000000BA878000 0x00000000BB67A000 0x0000000000E02000 |
|
||||
| 2 1 0x00000000BB67A000 0x00000000BCA37000 0x00000000013BD000 |
|
||||
| 1 1 0x00000000BCA37000 0x00000000BCA38000 0x0000000000001000 |
|
||||
| 4 1 0x00000000BCA38000 0x00000000BCC3E000 0x0000000000206000 |
|
||||
| 1 1 0x00000000BCC3E000 0x00000000BD083000 0x0000000000445000 |
|
||||
| 2 1 0x00000000BD083000 0x00000000BD7F4000 0x0000000000771000 |
|
||||
| 1 1 0x00000000BD7F4000 0x00000000BD800000 0x000000000000C000 |
|
||||
| 1 1 0x0000000100001000 0x000000043F000000 0x000000033EFFF000 |
|
||||
| 2 1 0x00000000F8000000 0x00000000FC000000 0x0000000004000000 |
|
||||
| 2 1 0x00000000FEC00000 0x00000000FEC01000 0x0000000000001000 |
|
||||
| 2 1 0x00000000FEC10000 0x00000000FEC11000 0x0000000000001000 |
|
||||
| 2 1 0x00000000FEC20000 0x00000000FEC21000 0x0000000000001000 |
|
||||
| 2 1 0x00000000FED00000 0x00000000FED01000 0x0000000000001000 |
|
||||
| 2 1 0x00000000FED61000 0x00000000FED71000 0x0000000000010000 |
|
||||
| 2 1 0x00000000FED80000 0x00000000FED90000 0x0000000000010000 |
|
||||
| 2 1 0x00000000FEF00000 0x0000000100000000 0x0000000001100000 |
|
452
src/.gdb_history
452
src/.gdb_history
@ -1,256 +1,256 @@
|
||||
x 0x7FFE1667
|
||||
x 0x7FFE1667
|
||||
x 0x200000
|
||||
quit
|
||||
break main
|
||||
x 0x1
|
||||
next
|
||||
break bzero
|
||||
c
|
||||
next
|
||||
stepi
|
||||
condition 3 i == 98268
|
||||
quit
|
||||
quit
|
||||
break bzero
|
||||
c
|
||||
c
|
||||
quit
|
||||
break panic
|
||||
c
|
||||
quit
|
||||
break map_page
|
||||
c
|
||||
next
|
||||
break bzero
|
||||
d 2
|
||||
c
|
||||
next
|
||||
x 0x200000
|
||||
return
|
||||
next
|
||||
x 0x20000
|
||||
x 0x20000 4096
|
||||
dq 0x20000 (4096/8)
|
||||
dq 0x20000 1
|
||||
dq 0x20000 2
|
||||
dq 0x20000 3
|
||||
dq 0x200000 3
|
||||
print rsdp.v1->rsdp
|
||||
print rsdp->v1.rsdt_addr
|
||||
print (void*)rsdp->v1.rsdt_addr
|
||||
print (page table*)0x4000
|
||||
print (page_table*)0x4000
|
||||
print (page_table*)0x4000->pml4e
|
||||
print (page_table*)0x4000.pml4e
|
||||
print (page_table*)0x4000->pml4e
|
||||
print *(page_table*)0x4000->pml4e
|
||||
print (page_table*)0x4000.pml4e
|
||||
print (page_table*)0x4000.pml4e[0]
|
||||
print (page_table*)0x4000->pml4e[0]
|
||||
print (page_table*)0x4000.pml4e[0]
|
||||
print (page_table*)0x4000.pdpe
|
||||
print (page_table*)0x4000.pde
|
||||
print (page_table*)0x4000
|
||||
print *(page_table*)0x4000
|
||||
print *((page_table*)0x4000)
|
||||
print *((page_table*)0x4000).pde
|
||||
print *((page_table*)0x4000).pml4e
|
||||
print *((page_table*)0x3000).pml4e
|
||||
print *((page_table*)0x4000).pml4e
|
||||
print *((page_table*)0x4000).pde
|
||||
print *((page_table*)0x4000).pte
|
||||
print rsdp.v1.base_addr
|
||||
print rsdp.v1.rsdt_addr
|
||||
print (void*)rsdp.v1.rsdt_addr
|
||||
print *((page_table*)0x4000).pte
|
||||
print *((page_table*)0x4000).pte[1]
|
||||
print *((page_table*)0x4000).pte
|
||||
print *((page_table*)0x4000)->pte[1]
|
||||
print *((page_table*)0x4000).pte
|
||||
print *((page_table*)0x4000).pte[0]
|
||||
print ((page_table*)0x4000).pte
|
||||
print ((page_table*)0x4000)->pte
|
||||
print ((page_table*)0x4000)->pte[0]
|
||||
print ((page_table*)0x4000)->pte[1]
|
||||
print ((page_table*)0x4000)->pte[2]
|
||||
print ((page_table*)0x4000)->pte[3]
|
||||
print ((page_table*)0x4000)->pte[4]
|
||||
print ((page_table*)0x4000)->pte[5]
|
||||
print ((page_table*)0x4000)->pte[10]
|
||||
print ((page_table*)0x4000)->pte[1512]
|
||||
print ((page_table*)0x4000)->pte[512]
|
||||
print ((page_table*)0x4000)->pte[513]
|
||||
print ((page_table*)0x4000)->pte[512]
|
||||
print ((page_table*)0x4000)->pte[511]
|
||||
print ((page_table*)0x4000)->pte[510]
|
||||
print ((page_table*)0x4000)->pte
|
||||
stack
|
||||
quit
|
||||
break main
|
||||
quit
|
||||
break bzero
|
||||
c
|
||||
page_table *table = (page_table *)PAGEMAP_LOCATION
|
||||
print page_table *table = (page_table *)PAGEMAP_LOCATION
|
||||
print (page_table *)PAGEMAP_LOCATION
|
||||
print (page_table *)0x4000
|
||||
print *(page_table *)0x4000
|
||||
print (page_table *)0x4000.pml4
|
||||
print (page_table *)0x4000.pml4e
|
||||
print (page_table *)0x4000->pml4e
|
||||
print *((page_table *)0x4000).pml4e
|
||||
print *((page_table *)0x4000).pml4e[0]
|
||||
print ((page_table *)0x4000).pml4e[0]
|
||||
print ((page_table *)0x4000).pml4e[2]
|
||||
print ((page_table *)0x4000).pml4e[3]
|
||||
print ((page_table *)0x4000).pml4e[4]
|
||||
print ((page_table *)0x4000).pml4e[1]
|
||||
print ((page_table *)0x4000).pml4e[1]
|
||||
print ((page_table *)0x4000).pml4e[1]
|
||||
print ((page_table *)0x4000).pml4e[1]
|
||||
print ((page_table *)0x4000).pml4e[0]
|
||||
print ((page_table *)0x4000).pde[0]
|
||||
print ((page_table *)0x4000).pde[1]
|
||||
print ((page_table *)0x4000).pde[0]
|
||||
print ((page_table *)0x4000).pde[20]
|
||||
print ((page_table *)0x4000).pde[10]
|
||||
print ((page_table *)0x4000).pde[0]
|
||||
print ((page_table *)0x4000).pde[1]
|
||||
print ((page_table *)0x4000).pde[2]
|
||||
print ((page_table *)0x4000).pde[0]
|
||||
print ((page_table *)0x4000).pde[1]
|
||||
print ((page_table *)0x4000).pde[0]
|
||||
print ((page_table *)0x4000).pde[1]
|
||||
print ((page_table *)0x4000).pde[2]
|
||||
print ((page_table *)0x4000).pde[2]
|
||||
print ((page_table *)0x4000).pde[21]
|
||||
print ((page_table *)0x4000).pde[1]
|
||||
c
|
||||
next
|
||||
print rsdp.v1.rsdt_addr
|
||||
print (void*)rsdp.v1.rsdt_addr
|
||||
break bzero
|
||||
c
|
||||
c
|
||||
next
|
||||
watch i
|
||||
c
|
||||
info breakpoints
|
||||
d 4 3 2
|
||||
info watchpoitns
|
||||
info watchpoints
|
||||
watch i
|
||||
c
|
||||
c
|
||||
info breakpoints
|
||||
c
|
||||
d 5
|
||||
next
|
||||
watch i
|
||||
c
|
||||
condition 6 i == 9999999
|
||||
c
|
||||
x 0
|
||||
x 1
|
||||
nexti
|
||||
break bzero
|
||||
c
|
||||
next
|
||||
watch i
|
||||
condition 8 i == 16359
|
||||
c
|
||||
x 0x1fffb8
|
||||
next
|
||||
print p1[o]i]
|
||||
print p1[i]
|
||||
print p1
|
||||
stack
|
||||
quit
|
||||
break bzero
|
||||
c
|
||||
next
|
||||
watch i
|
||||
condition i == 16359
|
||||
c
|
||||
condition 3 i == 16359
|
||||
c
|
||||
x 0
|
||||
print p1
|
||||
print p1[i]
|
||||
print &p1[i]
|
||||
print &(p1[i])
|
||||
x p1
|
||||
x p1[i]
|
||||
nexti
|
||||
next
|
||||
quit
|
||||
c
|
||||
quit
|
||||
c
|
||||
quit
|
||||
quit
|
||||
quit
|
||||
quit
|
||||
next
|
||||
break mina
|
||||
break main
|
||||
c
|
||||
break main
|
||||
c
|
||||
quit
|
||||
break bzero
|
||||
c
|
||||
next
|
||||
next
|
||||
quit
|
||||
break bzero
|
||||
c
|
||||
next
|
||||
print p1
|
||||
next
|
||||
nexti
|
||||
info reg rax
|
||||
next
|
||||
c
|
||||
quit
|
||||
c
|
||||
quit
|
||||
break bzero
|
||||
c
|
||||
next
|
||||
watch i
|
||||
condition 3 i == 1000000
|
||||
c
|
||||
quit
|
||||
break bzero
|
||||
c
|
||||
next
|
||||
watch i
|
||||
condition 3 i == 100000
|
||||
c
|
||||
quit
|
||||
break bzero
|
||||
c
|
||||
next
|
||||
watch i
|
||||
condition 3 i == 100000
|
||||
c
|
||||
x 0x0000000000204000
|
||||
info reg
|
||||
info reg rip
|
||||
quit
|
||||
break bzero
|
||||
c
|
||||
next
|
||||
watch i
|
||||
condition 3 i == 20454
|
||||
c
|
||||
quit
|
||||
break bzer
|
||||
break bzero
|
||||
c
|
||||
next
|
||||
condition i = 16360
|
||||
condition 3 i == 16360
|
||||
watch i
|
||||
condition 3 i == 16360
|
||||
c
|
||||
print (struct page_table)0x5000
|
||||
print (page_table)0x5000
|
||||
print (page_table *)0x5000
|
||||
print (page_table *)0x4000
|
||||
print (page_table *)0x4000.pml4e[0]
|
||||
print (page_table *)0x4000->pml4e[0]
|
||||
print (page_table *)0x4000->pml4e[
|
||||
print (page_table *)0x4000->pml4e
|
||||
print ((page_table *)0x4000).pml4e
|
||||
print ((page_table *)0x4000).pml4e[0]
|
||||
print ((page_table *)0x4000).pde[0]
|
||||
print ((page_table *)0x4000).pde[1]
|
||||
print ((page_table *)0x4000).pde[0]
|
||||
print ((page_table *)0x4000).pde[2]
|
||||
print ((page_table *)0x4000).pde[1]
|
||||
print ((page_table *)0x4000).pde[0]
|
||||
print ((page_table *)0x4000).pde[1]
|
||||
print ((page_table *)0x4000).pde[0]
|
||||
print ((page_table *)0x4000).pde[1]
|
||||
print ((page_table *)0x4000).pde[2]
|
||||
print ((page_table *)0x4000).pde[3]
|
||||
quit
|
||||
break mod_page_pde
|
||||
break map_page
|
||||
c
|
||||
next
|
||||
print table->pde
|
||||
print table->pde[1]
|
||||
next
|
||||
print table->pde[1]
|
||||
quit
|
||||
break map_page
|
||||
c
|
||||
next
|
||||
print size
|
||||
next
|
||||
print table->pde[pde_i]
|
||||
next
|
||||
print table->pde[pde_i]
|
||||
next
|
||||
print table->pde[pde_i]
|
||||
next
|
||||
print table->pde[pde_i]
|
||||
print table->pte[pte_i]
|
||||
next
|
||||
print table->pte[pte_i]
|
||||
next
|
||||
x 0x20000
|
||||
dq 0x20000 30
|
||||
dq 0x20000 40
|
||||
print table->pte[pte_i]
|
||||
context
|
||||
quit
|
||||
break map_page
|
||||
c
|
||||
next
|
||||
print table->pte[pte_i0
|
||||
print table->pte[pte_i]
|
||||
mext
|
||||
next
|
||||
print table->pde[pde_i]
|
||||
quit
|
||||
r
|
||||
c
|
||||
quit
|
||||
c
|
||||
quit
|
||||
break panic
|
||||
c
|
||||
x 0x7ffe1000
|
||||
quit
|
||||
break panic
|
||||
c
|
||||
x 0x200000
|
||||
dq 0x200000
|
||||
dq 0x200000 4
|
||||
dq 0x200000 8
|
||||
search -4 FACP
|
||||
search -4 FACP
|
||||
search -4 'FACP'
|
||||
search -s 'FACP'
|
||||
search -s 'ACPI'
|
||||
search -s 'RSDT'
|
||||
x 0x200000 + 0x667
|
||||
dq 0x200000 + 0x667
|
||||
dq (0x200000 + 0x667)
|
||||
x 0x200000 + 0x667
|
||||
x/20i 0x200000 + 0x667
|
||||
x/20x 0x200000 + 0x667
|
||||
x/100x 0x200000 + 0x667
|
||||
x/400x 0x200000 + 0x667
|
||||
x/400x 0x200000 + 0x1000
|
||||
x/400x 0x200000 + (0x1000)
|
||||
x/400x 0x200000 + (0x1000-8)
|
||||
x/400x 0x200000 + (0x1000-8)
|
||||
quit
|
||||
break panic
|
||||
c
|
||||
x 0x2000
|
||||
x 0x20000
|
||||
x 0x200000
|
||||
x 0x2000000
|
||||
x 0x200000
|
||||
x 0x2000000
|
||||
x 0x200000
|
||||
x 0x202000
|
||||
x 0x20b000
|
||||
x 0x20b000+8
|
||||
x 0x20b000
|
||||
x 0x202000
|
||||
x 0x201000
|
||||
x 0x200000
|
||||
x 0x201000
|
||||
x 0x201000-8
|
||||
x 0x200000-8
|
||||
x 0x200000
|
||||
quit
|
||||
break panic
|
||||
c
|
||||
0x200000
|
||||
x 0x200000
|
||||
x/s 0x200000
|
||||
quit
|
||||
break panic
|
||||
c
|
||||
quit
|
||||
break panic
|
||||
c
|
||||
quit
|
||||
break panic
|
||||
c
|
||||
quit
|
||||
break panic
|
||||
c
|
||||
x 0x20000
|
||||
x 0x21667
|
||||
x 0x20667
|
||||
x 0x200000
|
||||
x 0x200667
|
||||
x 0x200667
|
||||
x/s 0x200667
|
||||
quit
|
||||
break panic
|
||||
c
|
||||
x apic
|
||||
quit
|
||||
break main
|
||||
break map_page
|
||||
c
|
||||
next
|
||||
pirnt apic
|
||||
print apic
|
||||
print rsdp
|
||||
print apic
|
||||
print *apic
|
||||
(struct apic_header *)((uint64_t)0x200000 + (rsdp->v1.rsdt_addr % 0x1000)
|
||||
print (struct apic_header *)((uint64_t)0x200000 + (rsdp->v1.rsdt_addr % 0x1000)
|
||||
print table->pde[pde_i]
|
||||
next
|
||||
quit
|
||||
break panic
|
||||
c
|
||||
prit apic
|
||||
print apic
|
||||
print acpi
|
||||
print *acpi
|
||||
print acpi
|
||||
print acpi.sig
|
||||
quit
|
||||
break main
|
||||
break map_page
|
||||
c
|
||||
next
|
||||
print apic
|
||||
ptype apic_header
|
||||
quit
|
||||
ptype acpi
|
||||
ptype acpi_header
|
||||
break main
|
||||
break init_memory
|
||||
c
|
||||
next
|
||||
print apic
|
||||
print acpi
|
||||
print acpi.*
|
||||
context
|
||||
print apic
|
||||
quit
|
||||
break main
|
||||
next
|
||||
break map_page
|
||||
c
|
||||
return
|
||||
next
|
||||
print apic
|
||||
print apci_header
|
||||
ptype apci_header
|
||||
ptype apci_header
|
||||
quit
|
||||
break main
|
||||
c
|
||||
next
|
||||
print acpi
|
||||
next
|
||||
print acpi
|
||||
quit
|
||||
print acpi
|
||||
break main
|
||||
c
|
||||
print acpi
|
||||
next
|
||||
print acpi
|
||||
next
|
||||
print acpi
|
||||
next
|
||||
print acpi
|
||||
next
|
||||
print acpi
|
||||
ptype acpi_header
|
||||
quit
|
||||
quit
|
||||
quit
|
||||
pirnt map
|
||||
quit
|
||||
|
Binary file not shown.
@ -3,6 +3,8 @@ bios_disk:
|
||||
pusha
|
||||
mov es, dx
|
||||
|
||||
; TODO when our kernel gets to big to fit in one track, we need to just switch over to LHS with extended bios functions.
|
||||
|
||||
mov ah, 0x02 ; read disc sectors
|
||||
mov ch, 0x00 ; track 0
|
||||
mov dh, 0x00 ; head 0
|
||||
|
@ -1,25 +1,24 @@
|
||||
;TODO fix null problem, allow direct passes
|
||||
;TODO fix null problem, allow passing value insted of pointer
|
||||
bios_print:
|
||||
;push ax ; we need to use ax, so let's push it in case whoever called needs it
|
||||
pusha
|
||||
mov ah, 0x0e ; tells bios we're in tty mode
|
||||
mov ah, 0x0e
|
||||
|
||||
.print_loop:
|
||||
mov al, [bx] ; al is the char MEANT TO BE CX
|
||||
cmp al, 0 ; compare the char we're about to print with null
|
||||
je .fini ; if it is null, we gonna scoot the fuck outta here
|
||||
mov al, [bx]
|
||||
cmp al, 0
|
||||
je .fini
|
||||
|
||||
test cx, cx ; if cx is zero, ascii, otherwise hex string
|
||||
jne .print_hex
|
||||
int 0x10 ; bios call, actually prints the char
|
||||
int 0x10
|
||||
.print_hex_ret:
|
||||
inc bx ; adds to the pointer
|
||||
jmp .print_loop ; goes back to loop start
|
||||
inc bx
|
||||
jmp .print_loop
|
||||
|
||||
.fini:
|
||||
mov al, 0xd ; \r
|
||||
mov al, 0xd
|
||||
int 0x10
|
||||
mov al, 0xa ; \n
|
||||
mov al, 0xa
|
||||
int 0x10
|
||||
popa
|
||||
ret
|
||||
@ -32,7 +31,7 @@ int 0x10
|
||||
mov al, 'x'
|
||||
int 0x10
|
||||
|
||||
mov al, [bx] ; shift bits to get first nibble
|
||||
mov al, [bx]
|
||||
shr al, 4
|
||||
call .bios_print_nibble
|
||||
|
||||
@ -47,13 +46,13 @@ jmp .print_hex_ret
|
||||
|
||||
|
||||
.bios_print_nibble:
|
||||
cmp al, 9 ; see if letter worthy
|
||||
cmp al, 9
|
||||
ja .print_hex_letter
|
||||
add al, 0x30 ;'1'
|
||||
add al, 0x30
|
||||
int 0x10
|
||||
ret
|
||||
|
||||
.print_hex_letter:
|
||||
add al, 0x57 ;'a'
|
||||
add al, 0x57
|
||||
int 0x10
|
||||
ret
|
||||
|
@ -3,7 +3,6 @@
|
||||
[extern _bootloader_stage1_size]
|
||||
[extern _kernel_loc]
|
||||
|
||||
;TODO clean up unreal mode
|
||||
jmp stage0
|
||||
times 3-($-$$) db 0x90 ; a temporary dirty fix to emulate a floppy disk insted of a hard risk
|
||||
times 59 db 0 ; (TODO support hard disks)
|
||||
@ -59,7 +58,6 @@ dw 0xaa55
|
||||
%include "bootloader/gdt.asm"
|
||||
|
||||
boot_msg:
|
||||
.debugmsg: db "debugeroni", 0
|
||||
.kernel_loaded: db `Kernel loaded!\r\nBooting to protected, then long mode...`, 0
|
||||
.stage2_loaded: db `Done loading bootloader!\r\nLoading kernel...`, 0
|
||||
|
||||
@ -94,9 +92,10 @@ mov cr0, eax
|
||||
|
||||
pop ds
|
||||
sti
|
||||
|
||||
;we are now in unreal mode
|
||||
|
||||
mov cl, 5 ; starting sector TODO automate this
|
||||
mov cl, 5
|
||||
mov edi, _kernel_loc
|
||||
.loop:
|
||||
mov al, 0x1 ; sector count
|
||||
@ -114,10 +113,6 @@ mov ecx, 512
|
||||
a32 rep movsb
|
||||
nop
|
||||
|
||||
mov bx, boot_msg.debugmsg
|
||||
mov cx, 0
|
||||
call bios_print
|
||||
|
||||
pop cx
|
||||
|
||||
cmp cl, _kernel_size
|
||||
@ -142,4 +137,5 @@ jmp $
|
||||
%include "bootloader/cpu_check.asm"
|
||||
%include "bootloader/video.asm"
|
||||
%include "bootloader/enter_kernel.asm"
|
||||
|
||||
times 2048 - ($ - $$) db 0
|
||||
|
@ -1,38 +1,41 @@
|
||||
; TODO move this file to something like "system_check", now that we do ram checks here
|
||||
[extern _meminfo_loc]
|
||||
detect_arch:
|
||||
; todo: figure out how to just handle invalid opcode exceptions, it would be faster and (maybe?) easier
|
||||
; todo: digest this part a little better when it's _not_ 1am.
|
||||
pushfd ; pushes eflags to stack
|
||||
pushfd ; pushes eflags to stack a second time
|
||||
xor dword [esp], 0x00200000 ; inverses the ID bit to see if cpuid is a thing
|
||||
pop eax ;gets our modified cpuid back
|
||||
xor eax, [esp] ; checks with the first time we pushed it; the OG eflag
|
||||
popfd ; pops the flags back I guess?
|
||||
and eax, 0x00200000 ; checks to see if the bit was inverted
|
||||
jz .print_cpuid_error
|
||||
;now we detect if we support long slong (aka 64 bit)
|
||||
|
||||
;https://www.amd.com/system/files/TechDocs/25481.pdf page 21
|
||||
;So apperently some dumbass engineers thought it would be funny to sell CPUs that have the long mode bit set without it being supported, dispite including it in their own documentation.
|
||||
;there's a work around by checking other bits, and it's a low priority TODO. However, I really think us coming accross this will be extremely rare.
|
||||
; detect CPUID
|
||||
|
||||
pushfd
|
||||
pushfd
|
||||
xor dword [esp], 0x00200000
|
||||
pop eax
|
||||
xor eax, [esp]
|
||||
popfd
|
||||
and eax, 0x00200000
|
||||
jz .print_cpuid_error
|
||||
|
||||
; detect long mode
|
||||
|
||||
mov eax, 0x80000001
|
||||
cpuid ;cpuid returns into edx
|
||||
and edx, 0x0020000000 ; the 21st bit is cpuid.
|
||||
cpuid
|
||||
and edx, 0x0020000000
|
||||
jz .print_long_error
|
||||
|
||||
; APIC
|
||||
mov eax, 0x00000001
|
||||
cpuid
|
||||
and edx, 0x00000200
|
||||
test edx, 0x00000200
|
||||
jz .print_apic_error
|
||||
|
||||
; SSE (you might be able to remove this, I think it's a standard requirement)
|
||||
test edx, 0x2000000
|
||||
jz .print_sse_error
|
||||
|
||||
|
||||
mov bx, .no_error
|
||||
mov cx, 0
|
||||
call bios_print
|
||||
|
||||
|
||||
;mapping memory
|
||||
; get memory mappings
|
||||
mov ax, 0
|
||||
mov es, ax
|
||||
mov ax, _meminfo_loc
|
||||
@ -71,7 +74,7 @@ call bios_print
|
||||
jmp $
|
||||
|
||||
.print_long_error:
|
||||
mov bx, .arch_error ; lets just test for now
|
||||
mov bx, .arch_error
|
||||
mov cx, 0
|
||||
call bios_print
|
||||
jmp $
|
||||
@ -80,11 +83,19 @@ jmp $
|
||||
mov bx, .apic_error
|
||||
mov cx, 0
|
||||
call bios_print
|
||||
jmp $
|
||||
|
||||
.print_mem_error:
|
||||
mov bx, .mem_error
|
||||
mov cx, 0
|
||||
call bios_print
|
||||
jmp $
|
||||
|
||||
.print_sse_error:
|
||||
mov bx, .sse_error
|
||||
mov cx, 0
|
||||
call bios_print
|
||||
jmp $
|
||||
|
||||
|
||||
.cpuid_error:
|
||||
@ -95,6 +106,8 @@ call bios_print
|
||||
db "No apic support", 0x0
|
||||
.mem_error:
|
||||
db "Could not get information on memory!", 0x0
|
||||
.sse_error:
|
||||
db "This OS requires SSE", 0x0
|
||||
.no_error:
|
||||
db "CPU info gathered!", 0x0
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
[extern main]
|
||||
[extern _kernel_stack_loc]
|
||||
[extern _stage1_pagetable]
|
||||
enter_longmode:
|
||||
cli
|
||||
|
||||
@ -29,7 +30,7 @@ mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
|
||||
mov edi, 0x4000 ; 0x3000
|
||||
mov edi, _stage1_pagetable ; 0x3000
|
||||
mov cr3, edi
|
||||
mov eax, 0
|
||||
mov ecx, 0xc00 ; 0x1000
|
||||
@ -37,14 +38,14 @@ rep stosd
|
||||
mov edi, cr3
|
||||
|
||||
|
||||
mov DWORD [edi], 0x5003 ; pml4e[0] = pdpe
|
||||
mov DWORD [edi], _stage1_pagetable + 0x1003 ; pml4e[0] = pdpe
|
||||
add edi, 0x1000
|
||||
mov DWORD [edi], 0x6003 ; pdpe[0] = pde
|
||||
mov DWORD [edi], _stage1_pagetable + 0x2003 ; pdpe[0] = pde
|
||||
add edi, 0x1000
|
||||
mov DWORD [edi], 0x83 ; pde[0] = pte
|
||||
|
||||
mov eax, cr4
|
||||
or eax, 1 << 5
|
||||
or eax, 0x620
|
||||
mov cr4, eax
|
||||
|
||||
;end of setting up pages
|
||||
@ -65,9 +66,11 @@ or eax, 1 << 8
|
||||
wrmsr
|
||||
|
||||
mov eax, cr0
|
||||
or eax, 1 << 31
|
||||
and ax, 0xfffb
|
||||
or eax, 0x80000002
|
||||
mov cr0, eax
|
||||
|
||||
|
||||
lgdt [long_gdt.descriptor]
|
||||
|
||||
jmp LONG_CODE_SEGMENT:enter_kernel
|
||||
|
@ -1,87 +0,0 @@
|
||||
[extern main]
|
||||
[extern _kernel_stack_loc]
|
||||
enter_longmode:
|
||||
cli
|
||||
|
||||
; TODO check if a20 is already set
|
||||
mov al, 0x92
|
||||
or al, 2
|
||||
out 0x92, al
|
||||
|
||||
lgdt [protected_gdt.descriptor]
|
||||
mov eax, cr0
|
||||
or eax, 0x1
|
||||
mov cr0, eax
|
||||
|
||||
mov eax, 0x8
|
||||
mov ds, eax
|
||||
|
||||
jmp 0x8:init_longmode
|
||||
|
||||
bits 32
|
||||
init_longmode:
|
||||
mov ebp, 0xffff
|
||||
mov esp, ebp
|
||||
mov ax, PROTECTED_DATA_SEGMENT
|
||||
mov ds, ax
|
||||
mov ss, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
|
||||
mov edi, 0x3000 ; this is where our page tables will be
|
||||
mov cr3, edi
|
||||
mov eax, 0 ; what we'll be putting there
|
||||
mov ecx, 4096 ; how many times we'll put it there
|
||||
rep stosd ; kinda like memset(&edi, ecx, edi)
|
||||
mov edi, cr3
|
||||
|
||||
mov DWORD [edi], 0x4003 ; pml4e[0] = pdpe
|
||||
add edi, 0x1000
|
||||
mov DWORD [edi], 0x5003 ; pdpe[0] = pde
|
||||
add edi, 0x1000
|
||||
mov DWORD [edi], 0x6003 ; pde[0] = pte
|
||||
add edi, 0x1000
|
||||
|
||||
mov ebx, 0x00000003 ; the flags
|
||||
mov ecx, 512; the loop counter, will map 2 mib
|
||||
|
||||
.idmap_pte_loop:
|
||||
mov DWORD [edi], ebx
|
||||
add ebx, 0x1000 ; physical address. Should leave us at 0x7000
|
||||
add edi, 8 ; position in page table
|
||||
loop .idmap_pte_loop
|
||||
|
||||
mov eax, cr4
|
||||
or eax, 1 << 5
|
||||
mov cr4, eax
|
||||
|
||||
mov ecx, 0xc0000080
|
||||
rdmsr
|
||||
or eax, 1 << 8
|
||||
wrmsr
|
||||
|
||||
mov eax, cr0
|
||||
or eax, 1 << 31 | 1 << 0 ; this is where we set paging and protected mode (respectively)!
|
||||
mov cr0, eax
|
||||
|
||||
|
||||
mov ecx, 0xc0000080
|
||||
rdmsr
|
||||
or eax, 1 << 8
|
||||
wrmsr
|
||||
|
||||
mov eax, cr0
|
||||
or eax, 1 << 31
|
||||
mov cr0, eax
|
||||
|
||||
lgdt [long_gdt.descriptor]
|
||||
|
||||
jmp LONG_CODE_SEGMENT:enter_kernel
|
||||
enter_kernel:
|
||||
bits 64
|
||||
mov rbp, _kernel_stack_loc
|
||||
mov rsp, _kernel_stack_loc
|
||||
call main ; where we actually call the kernel
|
||||
jmp $
|
||||
ret
|
@ -49,8 +49,6 @@ db 10011010b ;1st flags and type. The first four bits (1010) are type, and the
|
||||
db 10101111b ;1111 is segment limit continued. 0: available, 0: 64 bit (change?), 1: 32 bit segment, 1: granularity (shifts 3 hex didgets to get all of memory)
|
||||
db 0
|
||||
|
||||
; the data GDT is the exact same, and it overlaps. We don't care, we'll be booting into long mode right after then programming in C
|
||||
; TODO: clarify once you figure out what you're doing
|
||||
.gdt_data:
|
||||
dw 0
|
||||
dw 0
|
||||
|
@ -1,10 +0,0 @@
|
||||
multicore_boot:
|
||||
jmp $
|
||||
|
||||
mov ecx, 0x0000001b
|
||||
rdmsr
|
||||
;mov [apic_register] dx:ax
|
||||
|
||||
apic_register: dq 0
|
||||
multicore_msg1: db "CPUs available: ", 0
|
||||
|
4
src/debug/gdbinit.gdb
Normal file
4
src/debug/gdbinit.gdb
Normal file
@ -0,0 +1,4 @@
|
||||
target remote localhost:1234
|
||||
symbol-file debug/debug_syms.o
|
||||
break *0x7c00
|
||||
continue
|
BIN
src/indigo_os
BIN
src/indigo_os
Binary file not shown.
@ -7,4 +7,6 @@ int strncmp(const char *str1, const char *str2, size_t n);
|
||||
void strcpy(char *dest, char *src);
|
||||
void memcpy(void *dest, void *src, size_t n); //TODO
|
||||
int memcmp(const void *s1, const void *s2, size_t n);
|
||||
void bzero(const void *dest, size_t size);
|
||||
int ceil(float n1);
|
||||
#endif
|
||||
|
@ -24,7 +24,7 @@ typedef struct __attribute__((packed)) {
|
||||
unsigned int software_marks : 3; // available for our own use, I doubt we'll use it in such a simple thing
|
||||
|
||||
uintptr_t base_ptr : 40;
|
||||
unsigned int available:11;
|
||||
unsigned int sign:11;
|
||||
} page_entry;
|
||||
|
||||
|
||||
@ -35,11 +35,11 @@ typedef struct __attribute__((packed)) {
|
||||
page_entry pte[512];
|
||||
} page_table;
|
||||
|
||||
#define MEM_AVAILABLE 0
|
||||
#define MEM_RESERVED 1
|
||||
#define MEM_APCI_RECLAIMABLE 2
|
||||
#define MEM_APCI_NVS 3
|
||||
#define MEM_BAD 4
|
||||
#define MEM_AVAILABLE 1
|
||||
#define MEM_RESERVED 2
|
||||
#define MEM_APCI_RECLAIMABLE 3
|
||||
#define MEM_APCI_NVS 4
|
||||
#define MEM_BAD 5
|
||||
|
||||
#define PAGE_SIZE_4K 12
|
||||
#define PAGE_SIZE_2M 21
|
||||
@ -49,12 +49,23 @@ struct memory_table {
|
||||
uint64_t base;
|
||||
uint64_t length;
|
||||
uint32_t type;
|
||||
uint32_t ACPI; //we'll never use this
|
||||
uint32_t ACPI;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct phys_map {
|
||||
uint64_t map_size; //this way we won't have to calculate it every time
|
||||
void *chunk_start;
|
||||
uint64_t chunk_size;
|
||||
uint64_t *buddies;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
extern void* _meminfo_loc;
|
||||
extern void* _stage2_pagetable;
|
||||
|
||||
bool map_page(uintptr_t virtual_addr, uintptr_t physical_addr, uint8_t PAGE_SIZE);
|
||||
bool map_page(void *virtual_addr, void *physical_addr, uint8_t PAGE_SIZE);
|
||||
void debug_print_memory();
|
||||
void create_pagetable_stage2(uint64_t free_mem);
|
||||
void init_memory();
|
||||
#endif
|
||||
|
||||
|
@ -47,3 +47,5 @@ struct vbe_infoblock {
|
||||
uint32_t videomodeptr;
|
||||
uint16_t total_memory;
|
||||
} __attribute__((packed));
|
||||
|
||||
extern void *_vbe_infoblock;
|
||||
|
@ -15,28 +15,20 @@ void main() {
|
||||
if(!(init_serial(COM1))) {
|
||||
printf("\nKernal started on CPU 1!\n"); // will detect cpu later
|
||||
}
|
||||
|
||||
|
||||
rsdp_t *rsdp;
|
||||
struct memory_table *table = (struct memory_table *)&_meminfo_loc;
|
||||
struct vbe_infoblock *vbe_info = (struct vbe_infoblock *)0x500;
|
||||
debug_print_memory();
|
||||
|
||||
rsdp = find_RSDP();
|
||||
if(!(rsdp)) {
|
||||
printf("Couldn't find the RSDP... uhh, not sure what to do now.\n");
|
||||
printf("Couldn't find the RSDP... not sure what to do now.\n");
|
||||
panic();
|
||||
}
|
||||
dump_video();
|
||||
|
||||
if(rsdp->v1.version) {
|
||||
map_page(0x200000, (rsdp->v2.xsdt_addr / 0x1000) * 0x1000, PAGE_SIZE_4K);
|
||||
}
|
||||
else {
|
||||
map_page(0x200000, (rsdp->v1.rsdt_addr / 0x1000) * 0x1000, PAGE_SIZE_4K);
|
||||
struct acpi_header *acpi = (struct acpi_header *)((uint64_t)0x200000 + (rsdp->v1.rsdt_addr % 0x1000));
|
||||
}
|
||||
|
||||
printf("kernel is done, you can ignore this panic\n");
|
||||
|
||||
dump_video();
|
||||
debug_print_memory();
|
||||
|
||||
init_memory();
|
||||
|
||||
panic();
|
||||
|
||||
}
|
||||
|
@ -31,16 +31,13 @@ static int RSDP_verify(void *rsdp_pointer) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TODO: move these when you gain your sanity
|
||||
rsdp_t *find_RSDP() { // finds root descriptor
|
||||
rsdp_t *find_RSDP() {
|
||||
const char sig[9] = "RSD PTR ";
|
||||
uintptr_t *p = (void *)0x040e;
|
||||
uintptr_t *ebda_unshifted = (void *)p;
|
||||
|
||||
// TODO you REALLY need to verify this.
|
||||
void *ebda = (void *)((uintptr_t)ebda_unshifted << (uintptr_t)4 & (uintptr_t)0xfffff);
|
||||
|
||||
|
||||
for(void *i = ebda; i <= ebda + 64000; i += 16) {
|
||||
if(!(memcmp(sig, i, 8))) {
|
||||
if(RSDP_verify(i)) {
|
||||
|
@ -1,10 +1,6 @@
|
||||
#include <stdint.h>
|
||||
#include <serial.h>
|
||||
//you can add more options if you need to later
|
||||
// PORT + 3: values are from bit zero (right) to left
|
||||
// dlab(1) | misteryyy bone(1) | paraty(3) | stop bits (1) | character length (2)
|
||||
static inline void outb(uint16_t port, uint8_t value) {
|
||||
//here "a" is the a register, and "Nd" is inteter (I think?) in the d register
|
||||
asm volatile(
|
||||
"outb %0, %1" :: "a"(value), "Nd"(port)
|
||||
);
|
||||
@ -19,14 +15,14 @@ static inline uint8_t inb(uint16_t port) {
|
||||
}
|
||||
|
||||
int init_serial(uint16_t port) {
|
||||
outb(port + 1, 0x00); // disable them fuckin interupts
|
||||
outb(port + 3, 0x80); // sets dlab, allowing custom serial speeds
|
||||
outb(port + 0, 0x06); // speed is 115200/6
|
||||
outb(port + 1, 0x00);
|
||||
outb(port + 3, 0x80);
|
||||
outb(port + 0, 0x06);
|
||||
outb(port + 1, 0x00);
|
||||
outb(port + 3, 0x03); // disables dlab, as well as 8 bit char len, 1 stop bit, no paraty, no mystery
|
||||
outb(port + 2, 0xc7); // I have no fucking clue what this means
|
||||
outb(port + 4, 0x0b); // don't know what this means eather... delete if you can
|
||||
outb(port + 4, 0x1e); // loopback mode (where the hell is this documented????)
|
||||
outb(port + 3, 0x03);
|
||||
outb(port + 2, 0xc7);
|
||||
outb(port + 4, 0x0b);
|
||||
outb(port + 4, 0x1e);
|
||||
|
||||
outb(port + 0, 0xae); // test char
|
||||
|
||||
@ -38,6 +34,6 @@ int init_serial(uint16_t port) {
|
||||
}
|
||||
|
||||
void _putchar_serial(uint16_t port, char msg) {
|
||||
while(!(inb(port + 5) & 0x20)); //wait for transmit to be doneroni
|
||||
while(!(inb(port + 5) & 0x20)); //wait for transmit to be done
|
||||
outb(port, msg);
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
#include <printf.h>
|
||||
#include <video.h>
|
||||
|
||||
//to be implimented when paging is set up
|
||||
|
||||
void dump_video() {
|
||||
struct mode_info *video = (struct mode_info *)0x600;
|
||||
printf("Video info:\nx:\t%u\ny:\t%u\nbbp:\t%u\nloc:\t0x%p\n", video->width, video->height, video->bpp, video->framebuffer);
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
//#include <printf.h>
|
||||
// you need to sort all these into diffrent files! TODO
|
||||
// TODO clean up variable names
|
||||
int strncmp(const char *s1, const char *s2, unsigned int n) {
|
||||
int i;
|
||||
for(i = 0; ((i <= n) && (s1[i] != '\0') && (s2[i] != '\0')); i++) {
|
||||
@ -23,7 +22,7 @@ int strcmp(const char *s1, const char *s2) {
|
||||
}
|
||||
|
||||
int memcmp(const void *s1, const void *s2, size_t n) {
|
||||
const unsigned char *p1 = s1; // Why is c such a bitch?
|
||||
const unsigned char *p1 = s1;
|
||||
const unsigned char *p2 = s2;
|
||||
int i;
|
||||
for(i = 0; i < n; i++) {
|
||||
@ -45,3 +44,17 @@ void memcpy(char *dest, char *src, size_t n) {
|
||||
dest[i] = src[i];
|
||||
}
|
||||
}
|
||||
|
||||
void bzero(void *dest, size_t size) {
|
||||
unsigned char *p1 = dest;
|
||||
for(uint64_t i = 0; i < size; i++) {
|
||||
p1[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//TODO move this function to a seperate math library
|
||||
int ceil(float n) {
|
||||
int low_n = (int)n;
|
||||
if(n == (float)low_n) return(low_n);
|
||||
return(low_n + 1);
|
||||
}
|
||||
|
@ -1,14 +1,7 @@
|
||||
#include <printf.h>
|
||||
#include <paging.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// for now, this will always remain the same.
|
||||
// If this ever isn't the case, we'll add paramaters to the paging functions.
|
||||
// We will also never need to mess with many bits,
|
||||
// as we are not implimenting security for a bare metal fractal generator.
|
||||
// Also, is this really the cleanest way to do things?
|
||||
|
||||
//after we get paging working, we can probably remove these structs and replace them with plain old uint_16ts.
|
||||
#include <libc.h>
|
||||
|
||||
void debug_print_memory() {
|
||||
struct memory_table *memtable = (struct memory_table *)&_meminfo_loc;
|
||||
@ -22,33 +15,89 @@ void debug_print_memory() {
|
||||
}
|
||||
|
||||
|
||||
//uses buddy system allocation
|
||||
void init_memory() {
|
||||
struct memory_table *memtable = (struct memory_table *)&_meminfo_loc;
|
||||
struct phys_map *map = (struct phys_map*)0x200000;
|
||||
uintptr_t onpage = 0x200000;
|
||||
unsigned int i, x, buddy_size, buddy_bitsize, prev_buddy_bsize;
|
||||
uint64_t *buddy_ptr;
|
||||
|
||||
map_page((void*)0x200000, (void*)0x200000, PAGE_SIZE_2M);
|
||||
void *next_page = (void *)onpage + 0x200000;
|
||||
// at this point, we are declaring our header and kernel itself as free (so don't forget to fix that!)
|
||||
|
||||
for(i = 0; memtable[i].length > 0; i++) {
|
||||
if((memtable[i].type == MEM_AVAILABLE) && (memtable[i].ACPI & 1)) {
|
||||
|
||||
map->chunk_start = (void*)memtable[i].base;
|
||||
map->chunk_size = memtable[i].length;
|
||||
buddy_ptr = (void*)&map->buddies;
|
||||
|
||||
|
||||
for(x = 0; x < 8; x++) {
|
||||
|
||||
buddy_bitsize = memtable[i].length / (0x1000 * (1 << x));
|
||||
buddy_size = ceil(buddy_bitsize / (float)8);
|
||||
|
||||
if((void *)buddy_ptr + buddy_size >= next_page) {
|
||||
map_page(next_page, next_page, PAGE_SIZE_2M);
|
||||
next_page += 0x200000;
|
||||
}
|
||||
|
||||
bzero(buddy_ptr, buddy_size); //meant to be /8?
|
||||
|
||||
if((buddy_bitsize * 2) != prev_buddy_bsize) {
|
||||
buddy_ptr[-1] |= (1 << ((prev_buddy_bsize % 8) - 1));
|
||||
}
|
||||
|
||||
buddy_ptr += buddy_size;
|
||||
|
||||
prev_buddy_bsize = buddy_bitsize;
|
||||
|
||||
}
|
||||
map->map_size = buddy_ptr - (uint64_t*)map;
|
||||
map = (struct phys_map *)map + map->map_size;
|
||||
|
||||
if((void *)map + 24 >= next_page) {
|
||||
map_page(next_page, next_page, PAGE_SIZE_2M);
|
||||
next_page += 0x200000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//TODO this function was deleted due to it being wrong.
|
||||
//I'll create it once I have the physical paging prerequisite set up.
|
||||
void create_pagetable_stage2(uint64_t free_mem) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* You can critisise the quality of this function all you want, it's messy due to planning mistakes
|
||||
* and I'm planning on sanatising it.
|
||||
* BUT, don't critisise it _just_ for using goto, that's bullshit. See the following links.
|
||||
*
|
||||
* https://www.kernel.org/doc/html/v4.17/process/coding-style.html "goto" section
|
||||
* https://koblents.com/Ches/Links/Month-Mar-2013/20-Using-Goto-in-Linux-Kernel-Code/
|
||||
* BIG TODO:
|
||||
* Paging turned out to be simpler then I thought. I've temporarily fixed the code, but needs to be rewritten/simplified.
|
||||
* Let's get rid of those nasty GOTOs if we can.
|
||||
* Also, once we get physical memory allocator up and running, impliment that in this function.
|
||||
**/
|
||||
|
||||
bool map_page(uintptr_t virtual_addr, uintptr_t physical_addr, uint8_t size) {
|
||||
printf("map page called\n");
|
||||
if((virtual_addr % (1 << size)) || (physical_addr % (1 << size))) {
|
||||
bool map_page(void *virtual_addr, void *physical_addr, uint8_t size) {
|
||||
//printf("map page called\n");
|
||||
uintptr_t va_ptr = (uintptr_t)virtual_addr;
|
||||
uintptr_t pa_ptr = (uintptr_t)physical_addr;
|
||||
if((va_ptr % (1 << size)) || (pa_ptr % (1 << size))) {
|
||||
return 0;
|
||||
}
|
||||
page_table *table = (page_table *)PAGEMAP_LOCATION;
|
||||
int pte_i = (virtual_addr >> 12) & 0x1ff;
|
||||
int pde_i = (virtual_addr >> 21) & 0x1ff;
|
||||
int pdpe_i = (virtual_addr >> 30) & 0x1ff;
|
||||
int pml4e_i = (virtual_addr >> 39) & 0x1ff;
|
||||
//TODO remove this debugging info
|
||||
printf("Virtual offsets:\npte:\t\t%i\npde:\t\t%i\npdpe:\t\t%i\npml4e\t\t%i\n", pte_i, pde_i, pdpe_i, pml4e_i);
|
||||
int pte_i = (va_ptr >> 12) & 0x1ff;
|
||||
int pde_i = (va_ptr >> 21) & 0x1ff;
|
||||
int pdpe_i = (va_ptr >> 30) & 0x1ff;
|
||||
int pml4e_i = (va_ptr >> 39) & 0x1ff;
|
||||
|
||||
if(table->pml4e[pml4e_i].present) {
|
||||
if(table->pml4e[pml4e_i].base_ptr != (uintptr_t)&table->pdpe[pdpe_i] >> 12) goto error;
|
||||
if(table->pdpe[pdpe_i].present) {
|
||||
if(size == PAGE_SIZE_1G) {
|
||||
if(table->pdpe[pdpe_i].base_ptr == (uintptr_t)physical_addr >> 30 & 0x1ff)
|
||||
if(table->pdpe[pdpe_i].base_ptr == (uintptr_t)pa_ptr >> 30 & 0x1ff)
|
||||
return true;
|
||||
goto error;
|
||||
}
|
||||
@ -56,13 +105,13 @@ bool map_page(uintptr_t virtual_addr, uintptr_t physical_addr, uint8_t size) {
|
||||
|
||||
if(table->pde[pde_i].present) {
|
||||
if(size == PAGE_SIZE_2M) {
|
||||
if(table->pde[pde_i].base_ptr == (uintptr_t)physical_addr >> 21 & 0x1ff)
|
||||
if(table->pde[pde_i].base_ptr == (uintptr_t)pa_ptr >> 21 & 0x1ff)
|
||||
return true;
|
||||
goto error;
|
||||
}
|
||||
if(table->pde[pde_i].base_ptr != (uintptr_t)&table->pte[pte_i] >> 12) goto error;
|
||||
if(table->pte[pte_i].present) {
|
||||
if(table->pte[pte_i].base_ptr != ((physical_addr >> 12) & 0x1ff)) goto error;
|
||||
if(table->pte[pte_i].base_ptr != ((pa_ptr >> 12) & 0x1ff)) goto error;
|
||||
return true;
|
||||
}
|
||||
else goto mod_page_pte;
|
||||
@ -77,9 +126,10 @@ bool map_page(uintptr_t virtual_addr, uintptr_t physical_addr, uint8_t size) {
|
||||
table->pml4e[pml4e_i].present = 1;
|
||||
mod_page_pdpe:
|
||||
table->pdpe[pdpe_i].read_write = 1;
|
||||
//TODO you just found out things are a lot more simple then you thought!
|
||||
if(size == PAGE_SIZE_1G) {
|
||||
table->pdpe[pdpe_i].size = 1;
|
||||
table->pdpe[pdpe_i].base_ptr = physical_addr >> 30;
|
||||
table->pdpe[pdpe_i].base_ptr = pa_ptr >> 12;
|
||||
table->pdpe[pdpe_i].present = 1;
|
||||
return true;
|
||||
}
|
||||
@ -89,14 +139,14 @@ mod_page_pde:
|
||||
table->pde[pde_i].read_write = 1;
|
||||
if(size == PAGE_SIZE_2M) {
|
||||
table->pde[pde_i].size = 1;
|
||||
table->pde[pde_i].base_ptr = physical_addr >> 21;
|
||||
table->pde[pde_i].base_ptr = pa_ptr >> 12;
|
||||
table->pde[pde_i].present = 1;
|
||||
return true;
|
||||
}
|
||||
table->pde[pde_i].base_ptr = (uintptr_t)&table->pte[pte_i] >> 12;
|
||||
table->pde[pde_i].present = 1;
|
||||
mod_page_pte:
|
||||
table->pte[pte_i].base_ptr = (physical_addr >> 12);
|
||||
table->pte[pte_i].base_ptr = pa_ptr >> 12;
|
||||
table->pte[pte_i].read_write = 1;
|
||||
table->pte[pte_i].present = 1;
|
||||
return true;
|
||||
|
@ -11,12 +11,12 @@ acpi.o
|
||||
kernel.o
|
||||
)
|
||||
|
||||
/*while we do need to worry about the stack converging on our kernel,
|
||||
this is only temporary, and it will be more noticable then if it were to hit bios (we want to find bugs, not ignore them!)*/
|
||||
_kernel_stack_loc = 0x200000 - 16;
|
||||
_kernel_stack_loc = 0x200000 - 8;
|
||||
_kernel_loc = 0x100000;
|
||||
_meminfo_loc = 0x7000;
|
||||
_vbe_infoblock = 0x500; /* this does not account for segmentation to get over 0xffff*/
|
||||
_vbe_infoblock = 0x500;
|
||||
_stage2_pagetable = 0x200000;
|
||||
_stage1_pagetable = 0x4000;
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
10
src/makefile
10
src/makefile
@ -4,11 +4,10 @@ OBJCPY=../compiler/indigo_gcc/bin/x86_64-elf-objcopy
|
||||
INC=-Ikernel/include
|
||||
|
||||
EMU_CORES=4
|
||||
EMU_RAM=2G
|
||||
EMU_RAM=4G
|
||||
XRES=1024
|
||||
YRES=768
|
||||
|
||||
#TODO clean up make vs debug
|
||||
|
||||
make:
|
||||
nasm -g -felf64 bootloader/bootloader.asm -o objects/bootloader.o
|
||||
@ -32,15 +31,15 @@ endif
|
||||
|
||||
|
||||
run:
|
||||
qemu-system-x86_64 -smp $(EMU_CORES) -m $(EMU_RAM) -nographic -drive format=raw,file=./indigo_os
|
||||
qemu-system-x86_64 -smp $(EMU_CORES) -m $(EMU_RAM) -nographic -no-reboot -drive format=raw,file=./indigo_os
|
||||
|
||||
|
||||
gdb: indigo_os
|
||||
tmux new-session -s os_gdb "qemu-system-x86_64 -smp $(EMU_CORES) -nographic -S -s -drive format=raw,file=./indigo_os -m $(EMU_RAM)"\;\
|
||||
tmux new-session -s os_gdb "qemu-system-x86_64 -smp $(EMU_CORES) -nographic -no-reboot -S -s -drive format=raw,file=./indigo_os -m $(EMU_RAM)"\;\
|
||||
split-window -h "gdb -x debug/gdbinit.gdb; killall qemu-system-x86_64"
|
||||
|
||||
run-graphical:
|
||||
qemu-system-x86_64 -S -s -smp $(EMU_CORES) -serial pipe:debug/serial -device VGA,edid=on,xres=$(XRES),yres=$(YRES) -drive format=raw,file=./indigo_os &\
|
||||
qemu-system-x86_64 -S -s -smp $(EMU_CORES) -m $(EMU_RAM) -no-reboot -serial pipe:debug/serial -device VGA,edid=on,xres=$(XRES),yres=$(YRES) -drive format=raw,file=./indigo_os &\
|
||||
gdb -x debug/gdbinit.gdb; killall qemu-system-x86_64
|
||||
|
||||
clean:
|
||||
@ -50,4 +49,3 @@ clean:
|
||||
rm -f debug/debug_syms.o
|
||||
rm -f debug/serial.in
|
||||
rm -f debug/serial.out
|
||||
rm -f indigo_os.elf
|
||||
|
2
tools/README.md
Normal file
2
tools/README.md
Normal file
@ -0,0 +1,2 @@
|
||||
# You can probably ignore this directory for now.
|
||||
These were just tools I used to check my sanity in the early stages of my bootloader.
|
@ -24,6 +24,6 @@ def get_table_size(addr):
|
||||
|
||||
return((pte_cnt + pde_cnt + pdpe_cnt + pml4_cnt) * 8)
|
||||
|
||||
ts = get_table_size(68719476736)
|
||||
print(hex(ts))
|
||||
ts = get_table_size(34359738368)
|
||||
print(ts)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user