Three days of silliness

Well, I’ve started implementation of both variants of interrupt handling. First in real mode, second one in supervisor mode.

I’m such idiot :) tryed to use call gate to change privelege level from ring 0 to ring 3. Digged memory dumps trying to understand why code causes #GP. Fixed stack changing issues (that was first reason of fault), made correct call gate installation… but problems was still here with me every day and a huge bit of night. the reason is simple, lcall via callgate with decreasing of privelege level is impossible. Hmm. Next time I’ll read Intel specs more times per day even if it’ll consume time I’m spending on reading of Ray Bradbury’s stories. But anyway, this my stupidity helped me to get along with memory dumps in virtual machine and improved my knowledge of AT&T syntax.

The other way of handling, I’m also implementing (may call it “main branch” of project) – handling in real mode via catching reflected to vm86 mode interrupts from vm86 monitor. It’s adopted from Intel PXE SDK with slight differencies.

The main thing to think is interface to packet receiving.

Real mode code now assumes, network operations are performed in cycle from start to end of interexchange operation without interrupting for other needs. Something like this pseudocode (not formatted well, but it’s best I could get…):

pxe_poll() {

if (0 == __pxe_isr_occured)
{ return 0; }

if (pxe_packet_recv())
{ return 1; }

return 0;
}

while(1) {

if (pxe_poll())
{ do_recieve(); }

if (received_all)
{ break; }

check_resend_needed();
}

What problems are here? If we use TCP connection and recieve_all triggered it doesn’t means sender have received our ACK for last needed packet and that he received FIN. After receive_all is true, we begin next stage of working with this file and meanwhile sender may continue sending packets (he lost ACK and FIN for some reasons…), this packets will spam during some time NIC’s receiving queue and will cause queue overflow (the same if we are not checking if we received packet within reasonable time interval). Well, may be it’s not such big thing for http, but anyway is not very clean and shiny solution.

After understanding problem with privilege level and call gates, I’ve thought about a little bit another way.

ISR is executed in ring 0 (CPL0) and performs all recieve/send/resend operations, using user data selectors and code in userspace. If it’ll work, of course. After call gate issue, I’m rather cautious in my thoughts.

So this code will handle interrupt, get all packets that suit to installed packet filters. Packet filters are installed via pxe_socket() calls. If packet fits filter, than it’ll be stored in packet queue (currently it is handled in pxe_core), if not it is dropped. So, tcp related code must also be started in ring 0 (thanks to gods, UDP doesn’t need this). Usercode will query ring 0 via calls or may be via direct access to structures in userspace. the first case is more simple to synchronize packet adding/removing from pxe_core packet queue.

Well, it’s big enough post, it’s time to finish it. And start implementing further more of ICMP (the main goal now to achieve before beginning of summer of code).

Leave a Reply