Hi,
I read the wiki article on the PIT here: https://wiki.osdev.org/PIT#PIT_Channel_0_Example_Code
I read the example code, but I had an issue. The code is written in assembly for x86-32, and my kernel is in x86-64. I could try my hardest to translate the code, but with the sheer volume of code there, I don't think I would be able to pull it off.
Does anyone know any links/resources to PIT initialization example code (preferably in C++) for x86-64?
Initializing the PIT in C++
Initializing the PIT in C++
Skylight: https://github.com/austanss/skylight
I make stupid mistakes and my vision is terrible. Not a good combination.
NOTE: Never respond to my posts with "it's too hard".
I make stupid mistakes and my vision is terrible. Not a good combination.
NOTE: Never respond to my posts with "it's too hard".
Re: Initializing the PIT in C++
On: http://www.osdever.net/bkerndev/Docs/pit.htm
There's a simple example in C. In C++, it will be exactly the same. It's not extremely precise, but it's a start point. With this logic, at 100 Hz, I believe you'll have a clock skew of a few seconds per day. Just replace 1193180 with 1193182.
Note: you'll also need to implement the outportb() function. A possible implementation in GNU C is: Note[2]: it's not possible to have an implementation in ISO C, simply because there's no such feature as the "inline assembly" in the ISO C.
There's a simple example in C. In C++, it will be exactly the same.
Code: Select all
void timer_phase(int hz)
{
int divisor = 1193180 / hz; /* Calculate our divisor */
outportb(0x43, 0x36); /* Set our command byte 0x36 */
outportb(0x40, divisor & 0xFF); /* Set low byte of divisor */
outportb(0x40, divisor >> 8); /* Set high byte of divisor */
}
Note: you'll also need to implement the outportb() function. A possible implementation in GNU C is:
Code: Select all
static inline void outb(unsigned short port, unsigned char val)
{
asm volatile(
"outb %[value], %[port]"
: /* no output */
: [value] "a"(val), [port] "Nd"(port)
);
}
Tilck, a Tiny Linux-Compatible Kernel: https://github.com/vvaltchev/tilck
Re: Initializing the PIT in C++
P.S. the link I sent you is part of the "Bran's Kernel Development Tutorial":
http://www.osdever.net/tutorials/view/b ... t-tutorial
The tutorial is a nice starting point BUT, it has several bugs in it. See our wiki page about that:
https://wiki.osdev.org/Bran%27s_Kernel_ ... Known_Bugs
Still, despite the bugs, you might learn more than a few things there, start experimenting on your own, insult tutorial's author while fixing some of his bugs, and have a lot of fun in the meanwhile
http://www.osdever.net/tutorials/view/b ... t-tutorial
The tutorial is a nice starting point BUT, it has several bugs in it. See our wiki page about that:
https://wiki.osdev.org/Bran%27s_Kernel_ ... Known_Bugs
Still, despite the bugs, you might learn more than a few things there, start experimenting on your own, insult tutorial's author while fixing some of his bugs, and have a lot of fun in the meanwhile
Tilck, a Tiny Linux-Compatible Kernel: https://github.com/vvaltchev/tilck
Re: Initializing the PIT in C++
Have a look at IncludeOS! It implements all these devices, including PIT. Note that it doesn't really use the PIT directly as a timing system, only as a backend for timers when there is nothing better. So, the PIT is mostly just a measurement device to calibrate the LAPIC timer.