Fix spelling errors in first posts (yikes).
This commit is contained in:
parent
adeb3cf394
commit
80e734855c
|
@ -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
|
Following boot we immediately initialize the global descriptor table (GDT) and
|
||||||
interrupt descriptor table (IDT). The **GDT** is mostly irrelevant for x86-64,
|
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
|
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
|
which expects two copies of the user-space segment descriptors to allow
|
||||||
to 32bit code from a 64 bit OS. Right now the system doesn't support 32 bit code
|
returning to 32bit code from a 64 bit OS. Right now the system doesn't support
|
||||||
(and likely never will) so we just duplicate the 64 bit code segment.
|
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
|
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
|
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
|
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
|
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
|
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
|
For **virtual memory management** I keep the higher half (kernel) mappings
|
||||||
identical in each address space. Most of the kernel mappings are already
|
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
|
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
|
and most objects are inserted in ascending order (i.e. it is essentially a
|
||||||
linked list).
|
linked list).
|
||||||
|
|
||||||
|
@ -213,7 +214,7 @@ The kernel provides APIs to:
|
||||||
* Allocate memory and map it into an address space.
|
* Allocate memory and map it into an address space.
|
||||||
* Communicate with other processes using Endpoints, Ports, and Channels.
|
* Communicate with other processes using Endpoints, Ports, and Channels.
|
||||||
* Register IRQ handlers.
|
* Register IRQ handlers.
|
||||||
* Manage Capabilites.
|
* Manage Capabilities.
|
||||||
* Print debug information to the VM output.
|
* Print debug information to the VM output.
|
||||||
|
|
||||||
### IPC
|
### IPC
|
||||||
|
|
|
@ -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),
|
code](https://wiki.osdev.org/PCI#Class_Codes) - Class Code 0x1 (Storage Device),
|
||||||
Subclass 0x6 (SATA Controller), Subtype 0x1 (AHCI).
|
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
|
0x24 (called the ABAR for AHCI Base Address) which points to the start of the
|
||||||
GHC registers.
|
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
|
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
|
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.
|
field is set to 0x30 for the hard drive and 0x70 for the optical drive.
|
||||||
|
|
||||||
I was able to find a [OSDev Forum
|
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
|
DIAGNOSTIC command (0x90) to the device. It notes that this is largely
|
||||||
undocumented behavior but at least this information offers some clarity on the
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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.
|
fields in just the first page of the spec.
|
||||||
|
|
||||||
![IDENTIFY DEVICE Response](images/IDENTIFY_DEVICE.png)
|
![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
|
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
|
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
|
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
|
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
|
the possible commands, making the logical jump to the Register Host To Device
|
||||||
FIS feels damn near impossible.
|
FIS feels damn near impossible.
|
||||||
|
@ -379,7 +379,7 @@ Device FIS is as follows:
|
||||||
![Register Host to Device FIS Layout](images/RegisterHostToDeviceFIS.png)
|
![Register Host to Device FIS Layout](images/RegisterHostToDeviceFIS.png)
|
||||||
|
|
||||||
We don't need to initialize most of the fields here because the IDENTIFY_DEVICE
|
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
|
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
|
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.
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
`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
|
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)
|
![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
|
sector count. Following that we set the PRDT values (although we still only use
|
||||||
one slot).
|
one slot).
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue