From 80e734855cc1f8aa48f81390d31d91168163b0bb Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Tue, 23 Jan 2024 23:14:03 -0800 Subject: [PATCH] Fix spelling errors in first posts (yikes). --- content/blog/2023/12/acadia-0.1.0/index.md | 15 ++++++++------- content/blog/2024/01/ahci-driver/index.md | 20 ++++++++++---------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/content/blog/2023/12/acadia-0.1.0/index.md b/content/blog/2023/12/acadia-0.1.0/index.md index 27a031a..f57474d 100644 --- a/content/blog/2023/12/acadia-0.1.0/index.md +++ b/content/blog/2023/12/acadia-0.1.0/index.md @@ -111,13 +111,14 @@ On top of the things mentioned above, we use the limine protocol to: Following boot we immediately initialize the global descriptor table (GDT) and interrupt descriptor table (IDT). The **GDT** is mostly irrelevant for x86-64, however it was interesting trying to get it to work with the sysret function -which expects two copies of the user-space segment descriptors to allow returing -to 32bit code from a 64 bit OS. Right now the system doesn't support 32 bit code -(and likely never will) so we just duplicate the 64 bit code segment. +which expects two copies of the user-space segment descriptors to allow +returning to 32bit code from a 64 bit OS. Right now the system doesn't support +32 bit code (and likely never will) so we just duplicate the 64 bit code +segment. The **IDT** is fairly straightforward and barebones for now. I slowly add more debugging information to faults as I run into them and it is useful. One of the -biggest improvements was setting up a seperate kernel stack for Page Faults and +biggest improvements was setting up a separate kernel stack for Page Faults and General Protection Faults. That way if I broke memory related to the current stack frame I get useful debugging information rather than an immediate triple fault. I also recently added some very sloppy stack unwind code so I can more @@ -153,9 +154,9 @@ earlier than they need to be it is obvious because things break. For **virtual memory management** I keep the higher half (kernel) mappings identical in each address space. Most of the kernel mappings are already -availble from the bootloader but some are added for heaps and additional stacks. +available from the bootloader but some are added for heaps and additional stacks. For user memory we maintain a tree of the mapped in objects to ensure that none -intersect. Right now the tree is innefficient because it doesn't self balance +intersect. Right now the tree is inefficient because it doesn't self balance and most objects are inserted in ascending order (i.e. it is essentially a linked list). @@ -213,7 +214,7 @@ The kernel provides APIs to: * Allocate memory and map it into an address space. * Communicate with other processes using Endpoints, Ports, and Channels. * Register IRQ handlers. -* Manage Capabilites. +* Manage Capabilities. * Print debug information to the VM output. ### IPC diff --git a/content/blog/2024/01/ahci-driver/index.md b/content/blog/2024/01/ahci-driver/index.md index b0d0c8e..c84486a 100644 --- a/content/blog/2024/01/ahci-driver/index.md +++ b/content/blog/2024/01/ahci-driver/index.md @@ -110,7 +110,7 @@ The short story is that we are looking for the device with the right [class code](https://wiki.osdev.org/PCI#Class_Codes) - Class Code 0x1 (Storage Device), Subclass 0x6 (SATA Controller), Subtype 0x1 (AHCI). -Once we have the correct configuration space we cn read the address at offset +Once we have the correct configuration space we can read the address at offset 0x24 (called the ABAR for AHCI Base Address) which points to the start of the GHC registers. @@ -319,7 +319,7 @@ type and any errors from the interrupt since we aren't sending any commands. Something I'm not sure about is that as soon as we enable interrupts we seem to receive a FIS from the device with an error bit set. Both the hard drive and the -optical drive on qemu send a FIS with error bit 0x1 set. Additionally the status +optical drive on QEMU send a FIS with error bit 0x1 set. Additionally the status field is set to 0x30 for the hard drive and 0x70 for the optical drive. I was able to find a [OSDev Forum @@ -328,7 +328,7 @@ referencing that this behavior is caused by the reset sending an EXECUTE DEVICE DIAGNOSTIC command (0x90) to the device. It notes that this is largely undocumented behavior but at least this information offers some clarity on the outputs. Reading the ATA Command Set section 7.9.4 we can see that the command -ouputs code 0x01 to the error bits when `Device 0 passed, Device 1 passed or not +outputs code 0x01 to the error bits when `Device 0 passed, Device 1 passed or not present`. According a footnote we can "See the appropriate transport standard for the definition of device 0 and device 1." I really thought I was already looking at the "appropriate transport standard" but alas. All that to say we'll @@ -340,7 +340,7 @@ Now that the AHCI ports are initialized and can handle an interrupt, we can send commands to them. To start with lets send the IDENTIFY DEVICE command to each device. This command asks the device to send 512 bytes of information about itself back to us. These bytes contain 40 years of certified-crufty backwards -compatability. I mean just feast your eyes on the number of retired and obsolete +compatibility. I mean just feast your eyes on the number of retired and obsolete fields in just the first page of the spec. ![IDENTIFY DEVICE Response](images/IDENTIFY_DEVICE.png) @@ -350,7 +350,7 @@ and sector count from the drive. To do so we need to figure out how to send a command to the device. To be honest I feel like the specs fall down here in actually explaining this. The trick is to send a Register Host to Device FIS in one of the command slots. This FIS type has a field for the command as well as some -common parameters such as lba and count. In retrospect it is fairly clear once +common parameters such as LBA and count. In retrospect it is fairly clear once you are aware of it, but if you are just reading the SATA spec and looking at the possible commands, making the logical jump to the Register Host To Device FIS feels damn near impossible. @@ -379,7 +379,7 @@ Device FIS is as follows: ![Register Host to Device FIS Layout](images/RegisterHostToDeviceFIS.png) We don't need to initialize most of the fields here because the IDENTIFY_DEVICE -call doesn't rely on an lba or sector count. One of the keys is setting the high +call doesn't rely on an LBA or sector count. One of the keys is setting the high bit "C" in the byte that contains PM Port which indicates to the HBA that this FIS contains a new command (I spent a while trying to figure out why this wasn't working without that). The code for this is relatively straightforward. @@ -429,9 +429,9 @@ port_struct_->command_issue |= (1 << slot); ``` But wait! How will we know when this command has completed? We somehow need to -wait until we receive an interrupt for this command to proccess the data it +wait until we receive an interrupt for this command to process the data it sent. To handle this we can add a semaphore for each port command slot to allow -signalling when we recieve a completion interrupt for that command. I think it +signalling when we receive a completion interrupt for that command. I think it might make sense to have some sort of callback instead so we can pass errors back to the caller instead of just a completion signal. However I'm not sure what type of errors exist that are resolvable by the caller so for now this @@ -469,7 +469,7 @@ void AhciPort::HandleIrq() { } ``` -Ok now that we have retrieved the information from the drive we can parse it. +OK now that we have retrieved the information from the drive we can parse it. For the sector size, the default is 512 bytes which we will use unless the `LOGICAL SECTOR SIZE SUPPORTED` bit is set in double word 106, bit 12. If that is set we can check the double words at 117 and 118 to get the 32 bit sector @@ -531,7 +531,7 @@ that truly only a mother could love: ![Register Host to Device Layout LBA](images/RegisterHostToDeviceFISLBA.png) -That asside we simply update the FIS construction to set the command, LBA, and +That aside we simply update the FIS construction to set the command, LBA, and sector count. Following that we set the PRDT values (although we still only use one slot).