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
					
				
							
								
								
									
										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
	 Brett Weiland
						Brett Weiland