1*49410SkarelsNOTE: this description applies to the hp300 system with the old BSD 2*49410Skarelsvirtual memory system. It has not been updated to reflect the new, 3*49410SkarelsMach-derived VM system, but should still be useful. 4*49410SkarelsThe new system has no fixed-address "u.", but has a fixed mapping 5*49410Skarelsfor the kernel stack at 0xfff00000. 6*49410Skarels 7*49410Skarels-------------------------------------------------------------------------- 8*49410Skarels 949409SkarelsSome quick notes on the HPBSD VM layout and kernel debugging. 1049409Skarels 1149409SkarelsPhysical memory: 1249409Skarels 1349409SkarelsPhysical memory always ends at the top of the 32 bit address space; i.e. the 1449409Skarelslast addressible byte is at 0xFFFFFFFF. Hence, the start of physical memory 1549409Skarelsvaries depending on how much memory is installed. The kernel variable "lowram" 1649409Skarelscontains the starting locatation of memory as provided by the ROM. 1749409Skarels 1849409SkarelsThe low 128k (I think) of the physical address space is occupied by the ROM. 1949409SkarelsThis is accessible via /dev/mem *only* if the kernel is compiled with DEBUG. 2049409Skarels[ Maybe it should always be accessible? ] 2149409Skarels 2249409SkarelsVirtual address spaces: 2349409Skarels 2449409SkarelsThe hardware page size is 4096 bytes. The hardware uses a two-level lookup. 2549409SkarelsAt the highest level is a one page segment table which maps a page table which 2649409Skarelsmaps the address space. Each 4 byte segment table entry (described in 2749409Skarelshp300/pte.h) contains the page number of a single page of 4 byte page table 2849409Skarelsentries. Each PTE maps a single page of address space. Hence, each STE maps 2949409Skarels4Mb of address space and one page containing 1024 STEs is adequate to map the 3049409Skarelsentire 4Gb address space. 3149409Skarels 3249409SkarelsBoth page and segment table entries look similar. Both have the page frame 3349409Skarelsin the upper part and control bits in the lower. This is the opposite of 3449409Skarelsthe VAX. It is easy to convert the page frame number in an STE/PTE to a 3549409Skarelsphysical address, simply mentally mask out the low 12 bits. For example 3649409Skarelsif a PTE contains 0xFF880019, the physical memory location mapped starts at 3749409Skarels0xFF880000. 3849409Skarels 3949409SkarelsKernel address space: 4049409Skarels 4149409SkarelsThe kernel resides in its own virtual address space independent of all user 4249409Skarelsprocesses. When the processor is in supervisor mode (i.e. interrupt or 4349409Skarelsexception handling) it uses the kernel virtual mapping. The kernel segment 4449409Skarelstable is called Sysseg and is allocated statically in hp300/locore.s. The 4549409Skarelskernel page table is called Systab is also allocated statically in 4649409Skarelshp300/locore.s and consists of the usual assortment of SYSMAPs. 4749409SkarelsThe size of Systab (Syssize) depends on the configured size of the various 4849409Skarelsmaps but as currently configured is 9216 PTEs. Both segment and page tables 4949409Skarelsare initialized at bootup in hp300/locore.s. The segment table never changes 5049409Skarels(except for bits maintained by the hardware). Portions of the page table 5149409Skarelschange as needed. The kernel is mapped into the address space starting at 0. 5249409Skarels 5349409SkarelsTheoretically, any address in the range 0 to Syssize * 4096 (0x2400000 as 5449409Skarelscurrently configured) is valid. However, certain addresses are more common 5549409Skarelsin dumps than others. Those are (for the current configuration): 5649409Skarels 5749409Skarels 0 - 0x800000 kernel text and permanent data structures 5849409Skarels 0x917000 - 0x91a000 u-area; 1st page is user struct, last k-stack 5949409Skarels 0x1b1b000 - 0x2400000 user page tables, also kmem_alloc()ed data 6049409Skarels 6149409SkarelsUser address space: 6249409Skarels 6349409SkarelsThe user text and data are loaded starting at VA 0. The user's stack starts 6449409Skarelsat 0xFFF00000 and grows toward lower addresses. The pages above the user 6549409Skarelsstack are used by the kernel. From 0xFFF00000 to 0xFFF03000 is the u-area. 6649409SkarelsThe 3 PTEs for this range map (read-only) the same memory as does 0x917000 6749409Skarelsto 0x91a000 in the kernel address space. This address range is never used 6849409Skarelsby the kernel, but exists for utilities that assume that the u-area sits 6949409Skarelsabove the user stack. The pages from FFF03000 up are not used. They 7049409Skarelsexist so that the user stack is in the same location as in HPUX. 7149409Skarels 7249409SkarelsThe user segment table is allocated along with the page tables from Usrptmap. 7349409SkarelsThey are contiguous in kernel VA space with the page tables coming before 7449409Skarelsthe segment table. Hence, a process has p_szpt+1 pages allocated starting 7549409Skarelsat kernel VA p_p0br. 7649409Skarels 7749409SkarelsThe user segment table is typically very sparse since each entry maps 4Mb. 7849409SkarelsThere are usually only two valid STEs, one at the start mapping the text/data 7949409Skarelspotion of the page table, and one at the end mapping the stack/u-area. For 8049409Skarelsexample if the segment table was at 0xFFFFA000 there would be valid entries 8149409Skarelsat 0xFFFFA000 and 0xFFFFAFFC. 8249409Skarels 8349409SkarelsRandom notes: 8449409Skarels 8549409SkarelsAn important thing to note is that there are no hardware length registers 8649409Skarelson the HP. This implies that we cannot "pack" data and stack PTEs into the 8749409Skarelssame page table page. Hence, every user page table has at least 2 pages 8849409Skarels(3 if you count the segment table). 8949409Skarels 9049409SkarelsThe HP maintains the p0br/p0lr and p1br/p1lr PCB fields the same as the 9149409SkarelsVAX even though they have no meaning to the hardware. This also keeps many 9249409Skarelsutilities happy. 9349409Skarels 9449409SkarelsThere is no seperate interrupt stack (right now) on the HPs. Interrupt 9549409Skarelsprocessing is handled on the kernel stack of the "current" process. 9649409Skarels 9749409SkarelsFollowing is a list of things you might want to be able to do with a kernel 9849409Skarelscore dump. One thing you should always have is a ps listing from the core 9949409Skarelsfile. Just do: 10049409Skarels 10149409Skarels ps klaw vmunix.? vmcore.? 10249409Skarels 10349409SkarelsException related panics (i.e. those detected in hp300/trap.c) will dump 10449409Skarelsout various useful information before panicing. If available, you should 10549409Skarelsget this out of the /usr/adm/messages file. Finally, you should be in adb: 10649409Skarels 10749409Skarels adb -k vmunix.? vmcore.? 10849409Skarels 10949409SkarelsAdb -k will allow you to examine the kernel address space more easily. 11049409SkarelsIt automatically maps kernel VAs in the range 0 to 0x2400000 to physical 11149409Skarelsaddresses. Since the kernel and user address spaces overlap (i.e. both 11249409Skarelsstart at 0), adb can't let you examine the address space of the "current" 11349409Skarelsprocess as it does on the VAX. 11449409Skarels-------- 11549409Skarels 11649409Skarels1. Find out what the current process was at the time of the crash: 11749409Skarels 11849409SkarelsIf you have the dump info from /usr/adm/messages, it should contain the 11949409SkarelsPID of the active process. If you don't have this info you can just look 12049409Skarelsat location "Umap". This is the PTE for the first page of the u-area; i.e. 12149409Skarelsthe user structure. Forget about the last 3 hex digits and compare the top 12249409Skarels5 to the ADDR column in the ps listing. 12349409Skarels 12449409Skarels2. Locating a process' user structure: 12549409Skarels 12649409SkarelsGet the ADDR field of the desired process from the ps listing. This is the 12749409Skarelspage frame number of the process' user structure. Tack 3 zeros on to the 12849409Skarelsend to get the physical address. Note that this doesn't give you the kernel 12949409Skarelsstack since it is in a different page than the user-structure and pages of 13049409Skarelsthe u-area are not physically contiguous. 13149409Skarels 13249409Skarels3. Locating a process' proc structure: 13349409Skarels 13449409SkarelsFirst find the process' user structure as described above. Find the u_procp 13549409Skarelsfield at offset 0x200 from the beginning. This gives you the kernel VA of 13649409Skarelsthe proc structure. 13749409Skarels 13849409Skarels4. Locating a process' page table: 13949409Skarels 14049409SkarelsFirst find the process' user structure as described above. The first part 14149409Skarelsof the user structure is the PCB. The second longword (third field) of the 14249409SkarelsPCB is pcb_ustp, a pointer to the user segment table. This pointer is 14349409Skarelsactually the page frame number. Again adding 3 zeros yields the physical 14449409Skarelsaddress. You can now use the values in the segment table to locate the 14549409Skarelspage tables. For example, to locate the first page of the text/data part 14649409Skarelsof the page table, use the first STE (longword) in the segment table. 14749409Skarels 14849409Skarels5. Locating a process' kernel stack: 14949409Skarels 15049409SkarelsFirst find the process' page table as described above. The kernel stack 15149409Skarelsis near the end of the user address space. So, locate the last entry in the 15249409Skarelsuser segment table (base+0xFFC) and use that entry to find the last page of 15349409Skarelsthe user page table. Look at the last 256 entries of this page 15449409Skarels(pagebase+0xFE0) The first is the PTE for the user-structure. The second 15549409Skarelswas intended to be a read-only page to protect the user structure from the 15649409Skarelskernel stack. Currently it is read/write and actually allocated. Hence 15749409Skarelsit can wind up being a second page for the kernel stack. The third is the 15849409Skarelskernel stack. The last 253 should be zero. Hence, indirecing through the 15949409Skarelsthird of these last 256 PTEs will give you the kernel stack page. 16049409Skarels 16149409SkarelsAn alternate way to do this is to use the p_addr field of the proc structure 16249409Skarelswhich is found as described above. The p_addr field is at offset 0x10 in the 16349409Skarelsproc structure and points to the first of the PTEs mentioned above (i.e. the 16449409Skarelsuser structure PTE). 16549409Skarels 16649409Skarels6. Interpreting the info in a "trap type N..." panic: 16749409Skarels 16849409SkarelsAs mentioned, when the kernel crashes out of hp300/trap.c it will dump some 16949409Skarelsuseful information. This dates back to the days when I was debugging the 17049409Skarelsexception handling code and had no kernel adb or even kernel crash dump code. 17149409Skarels"trap type" (decimal) is as defined in hp300/trap.h, it doesn't really 17249409Skarelscorrelate with anything useful. "code" (hex) is only useful for MMU 17349409Skarels(trap type 8) errors. It is the concatination of the MMU status register 17449409Skarels(see hp300/cpu.h) in the high 16 bits and the 68020 special status word 17549409Skarels(see the 020 manual page 6-17) in the low 16. "v" (hex) is the virtual 17649409Skarelsaddress which caused the fault. "pid" (decimal) is the ID of the process 17749409Skarelsrunning at the time of the exception. Note that if we panic in an interrupt 17849409Skarelsroutine, this process may not be related to the panic. "ps" (hex) is the 17949409Skarelsvalue of the 68020 status register (see page 1-4 of 020 manual) at the time 18049409Skarelsof the crash. If the 0x2000 bit is on, we were in supervisor (kernel) mode 18149409Skarelsat the time, otherwise we were in user mode. "pc" (hex) is the value of the 18249409SkarelsPC saved on the hardware exception frame. It may *not* be the PC of the 18349409Skarelsinstruction causing the fault (see the 020 manual for details). The 0x2000 18449409Skarelsbit of "ps" dictates whether this is a kernel or user VA. "sfc" and "dfc" 18549409Skarelsare the 68020 source/destination function codes. They should always be one. 18649409Skarels"p0" and "p1" are the VAX-like region registers. They are of the form: 18749409Skarels 18849409Skarels <length> '@' <kernel VA> 18949409Skarels 19049409Skarelswhere both are in hex. Following these values are a dump of the processor 19149409Skarelsregisters (hex). Check the address registers for values close to "v", the 19249409Skarelsfault address. Most faults are causes by dereferences of bogus pointers. 19349409SkarelsMost such dereferences are the result of 020 instructions using the: 19449409Skarels 19549409Skarels <address-register> '@' '(' offset ')' 19649409Skarels 19749409Skarelsaddressing mode. This can help you track down the faulting instruction (since 19849409Skarelsthe PC may not point to it). Note that the value of a7 (the stack pointer) is 19949409SkarelsALWAYS the user SP. This is brain-dead I know. Finally, is a dump of the 20049409Skarelsstack (user/kernel) at the time of the offense. Before kernel crash dumps, 20149409Skarelsthis was very useful. 20249409Skarels 20349409Skarels7. Converting kernel virtual address to a physical address. 20449409Skarels 20549409SkarelsAdb -k already does this for you, but sometimes you want to know what the 20649409Skarelsresulting physical address is rather than what is there. Doing this is 20749409Skarelssimply a matter of indexing into the kernel page table. In theory we would 20849409Skarelsfirst have to do a lookup in the kernel segment table, but we know that the 20949409Skarelskernel page table is physically contiguous so this isn't necessary. The 21049409Skarelsbase of the system page table is "Sysmap", so to convert an address V just 21149409Skarelsdivide the address by 4096 to get the page number, multiply that by 4 (the 21249409Skarelssize of a PTE in bytes) to get a byte offset, and add that to "Sysmap". 21349409SkarelsThis gives you the address of the PTE mapping V. You can then get the 21449409Skarelsphysical address by masking out the low 12 bits of the contents of that PTE. 21549409SkarelsTo wit: 21649409Skarels 21749409Skarels *(Sysmap+(VA%1000*4))&fffff000 21849409Skarels 21949409Skarelswhere VA is the virtual address in question. 22049409Skarels 22149409SkarelsThis technique should also work for user virtual addresses if you replace 22249409Skarels"Sysmap" with the value of the appropriate processes' P0BR. This works 22349409Skarelsbecause a user's page table is *virtually* contiguous in the kernel 22449409Skarelsstarting at P0BR, and adb will handle translating the kernel virtual addresses 22549409Skarelsfor you. 226