- Timestamp:
-
09/18/13 14:48:17 (11 years ago)
- Author:
-
Phipse
- Comment:
-
/* Implementation */ GDB && Open work
Legend:
- Unmodified
- Added
- Removed
- Modified
-
v41
|
v42
|
|
297 | 297 | |
298 | 298 | '''More implementation details''', including source code samples, can be found in the projects [http://phipse.github.io/rtems/ blog!] |
299 | | = Virtualization layer (POK) = |
| 299 | = Virtualization layer && libpart.a (POK) = |
300 | 300 | |
301 | 301 | The virtualization layer is implemented in the user code part of the partitions code. |
302 | 302 | Mostly, it makes a syscall and passes the arguments through. |
303 | | = libpart.a creation (POK) = |
304 | | |
305 | | libpart.a is build after libpok.a but with the same makefile rule. |
| 303 | |
| 304 | libpart.a is build after libpok.a but with the same |
| 305 | [https://github.com/phipse/pok/blob/master/misc/mk/rules-partition.mk makefile rule]. |
306 | 306 | libpart.a consists of libpok.a plus the objects from the user code files. |
307 | 307 | |
… |
… |
|
309 | 309 | |
310 | 310 | I redesigned the interrupt handling in POK. |
| 311 | The way interrupts were handled before and my changes, are described [http://phipse.github.io/rtems/blog/2013/08/17/pok-hardware-interrupt-handling/ here]. |
311 | 312 | Previously there was no way of knowing which interrupt number occurred, as the IDT directly invoked the corresponding handler. |
312 | 313 | I replaced all 16 hardware interrupt handlers with predefined handlers, which know their interrupt number. |
313 | 314 | Then a meta handler is called to look up the registered handlers for this vector number and invokes first a kernel handler and then the partition handlers. |
314 | 315 | The lookup table is an array consisting of objects which have fields for the vector number, the handler list for the number of configured partitions plus one (kernel) and a list to indicate if the partition is waiting for an interrupt. |
315 | | The waiting flag is necessary, because a partition needs to process the interrupt before a new one can be delivered. |
316 | | |
317 | | To register a handler I introduced new syscalls with POK to register and unregister a handler, to enable and disable interrupt delivery to the partition and to acknowledge an interrupt. |
| 316 | The waiting flag is necessary, because a partition needs to process the interrupt before a new one can be delivered, thus imitating hardware behaviour. |
| 317 | |
| 318 | To register a handler I introduced new syscalls with POK to register and unregister a handler, to enable and disable interrupt delivery to the partition and to acknowledge an interrupt. |
318 | 319 | The acknowledge syscall sets the waiting flag mentioned above. |
| 320 | (see [https://github.com/phipse/pok/blob/master/kernel/include/core/syscall.h syscall.h] and |
| 321 | [https://github.com/phipse/pok/blob/master/kernel/core/syscall.c syscall.c] and |
| 322 | [https://github.com/phipse/pok/blob/master/kernel/arch/x86/x86-qemu/bsp.c bsp.c] ) |
319 | 323 | |
320 | 324 | The functions corresponding to these syscalls are implemented in the x86 bsp.c file. |
321 | | There is a new pok_bsp_irq_register_hw function, which is only accepting IRQ values for the hardware IRQ lines (0-15). |
322 | | pok_bsp_irq_register cannot be used to register IRQ handlers for hardware IRQs. |
| 325 | There are new functions: |
| 326 | * pok_bsp_irq_register_hw, |
| 327 | * pok_bsp_irq_unregister_hw, |
| 328 | * pok_bsp_irq_partition_ack, |
| 329 | * pok_bsp_irq_partition_enable and |
| 330 | * pok_bsp_irq_partition_disable. |
| 331 | pok_bsp_register_hw and pok_bsp_unregister_hw only accpet IRQ values for the hardware IRQ lines (0-15) and pok_bsp_irq_register cannot be used to register IRQ handlers for hardware IRQs anymore. |
| 332 | The enable and disable functions will decrease/increase a counter and return the previous state, thus the previous interrupt level can be restored. |
| 333 | |
| 334 | = Be careful with GDB = |
| 335 | |
| 336 | |
| 337 | GDB isn't designed for low level debugging. |
| 338 | To me it seems, it isn't able to handle memory segments. |
| 339 | When you single-step through the kernel space - user space transition, you will see, that GDB won't show anything on the user-stack, if you inspect the memory address, just 0x00000000. |
| 340 | But if you load the values written to %%gs:(%%ebx) back into %%eax, and inspect EAX, it will show the right value. |
| 341 | Debugging this piece of code is only able by loading values into the register and print them step by step. |
| 342 | I asked a question on [http://stackoverflow.com/questions/18869624/how-can-gdb-print-segmentoffset-addresses stack overflow] about this. |
| 343 | |
| 344 | How to use GDB with POK can be found in the pok-devel guide in the section "GDB'ing POK with QEMU". |
| 345 | The guide is located in the doc directory of the repo. |
323 | 346 | |
324 | 347 | = Remaining Issues = |
… |
… |
|
339 | 362 | This needs debugging - but GDB is of no help, because it can't handle segmentation. |
340 | 363 | At time of writing, I need to write documentation before I can go back to debugging. |
| 364 | |
| 365 | == Deliver interrupts occurring, while partition is not able to receive == |
| 366 | |
| 367 | |
| 368 | This can mean to things: Either the partition has registered an interrupt and is not scheduled at the moment or it is busy servicing another interrupt occurred earlier. |
| 369 | I [http://phipse.github.io/rtems/blog/2013/07/09/how-late-is-it/ discussed this] earlier under the term pending interrupts, as undelivered interrupts '''mustn't''' get lost and therefore be stored for later delivery. |
| 370 | I didn't come around to implement this, but a simple ''unsigned array[16]'' for each partition, counting the undelivered but occurred interrupts, should do it. |
| 371 | |
| 372 | The scheduler then has to check this array when it schedules the partition again and care for the delivery of all pending interrupts, either one by one, or by delivering the amount. |
| 373 | If the latter is chosen, the partition needs to be aware of this. |
| 374 | For instance a time_warp function for the clock interrupt is needed. |
| 375 | Claudio da Silva has provided one [https://gist.github.com/cdcs/5874932 here]. |
341 | 376 | = References = |
342 | 377 | |