About

Michael Zucchi

 B.E. (Comp. Sys. Eng.)

  also known as zed
  & handle of notzed

Tags

android (44)
beagle (63)
biographical (98)
blogz (9)
business (1)
code (73)
cooking (31)
dez (7)
dusk (30)
extensionz (1)
ffts (3)
forth (3)
free software (4)
games (32)
gloat (2)
globalisation (1)
gnu (4)
graphics (16)
gsoc (4)
hacking (451)
haiku (2)
horticulture (10)
house (23)
hsa (6)
humour (7)
imagez (28)
java (229)
java ee (3)
javafx (49)
jjmpeg (80)
junk (3)
kobo (15)
libeze (7)
linux (5)
mediaz (27)
ml (15)
nativez (9)
opencl (120)
os (17)
panamaz (3)
parallella (97)
pdfz (8)
philosophy (26)
picfx (2)
players (1)
playerz (2)
politics (7)
ps3 (12)
puppybits (17)
rants (137)
readerz (8)
rez (1)
socles (36)
termz (3)
videoz (6)
vulkan (3)
wanki (3)
workshop (3)
zcl (3)
zedzone (23)
Sunday, 07 February 2010, 18:17

Puppy Bits is born

Although it's still a bit broken, I figured the code was finally good enough to upload, so I've created a google-code project called Puppy Bits.

No 'demo' yet, but most of my library-so-far.

I had some 'lunch' too; damn, 6pm, another day just vanished.

Tagged beagle, hacking, puppybits.
Sunday, 07 February 2010, 15:23

Video Graphics

Well, I've still given up on the TV out and the video encoder, but I did have a bit of success with the rest of the video system. Seems that writing the video code using the register names did pay off after-all.

So instead of enjoying another fantastic, if a little warm, day outside, i've been hacking away (seriously, it must some sort of addiction) at some sort of video/graphics interface. And all i've had to eat today so far is beer ...

I added code to set various video modes - all the basic ones up to 1280x1024. Since i'm using a fixed clock with an integer divider, most of the pixel clocks are wrong, but they work with my monitor as they are 'close enough'. I also separated out the graphics part from the video part, so I can use the hardware more fully, as below.

Anyway, obligatory screen-shot, then some explanation.

First, the video mode is set to 1280x1024, with a light-blue background colour. That's all it will display, until I add a graphical channel.

The dark-blue graphical channel is using channel 0 - the 'graphics' channel, in RGB16 format at 1024x768 resolution, centered on the main video window.

Then the noisy rectangle is using channel 2, again in RGB16 format, although it could also be in UYVU or YUV2 format. i.e. it is a 'video overlay'.

I'll upload it somewhere soon - maybe this week.

Debugging

To help with debugging i've come up with a couple ideas too. First, when I get a fatal exception I now jump to a little 'crash monitor' that lets me examine memory. Well that's all I do now, but it can always be extended. But even that has proven quite handy, e.g. to examine (more of) the stack.

Exception: Data Abort
 pc: 0x80009f00 sr: 0x200001d3
 r0: 0x00000020
 r1: 0x00000040
 r2: 0x48050400
 r3: 0x00000040
 r4: 0x48050400
 r5: 0x480504a0
 r6: 0x80e3fd84
 r7: 0x00000002
 r8: 0x48050400
 r9: 0x00000054
r10: 0x00000002
r11: 0x80e3fdbc
r12: 0x00000066
r13: 0x80e3fd70 0x00000008 0x00000000 0x80e3fe14 0x80009ff4 0x80e3fe14 0x80009b08 0x72747300 0x00797063
r14: 0x80e3fd7c
r15: 0x80009f00
Entering crappy crash monitor.
 ? for help.
#> ?
?               help
m addr len      Show memory as words from addr for len words
#> m 0x80e3fd70 22

0x80e3fd70: 0x00000008 0x00000000 0x80e3fe14 0x80009ff4 0x80e3fe14 0x80009b08 0x72747300 0x00797063
0x80e3fd90: 0x74757064 0x6d6d0063 0x6c665f75 0x5f687375 0x00424c54 0x646e6573 0x7274735f 0x00676e69
0x80e3fdb0: 0x00000001 0x80200000 0x80200000 0x00000280 0x00000200 0x00000000
#> 

The second is a sort of crash analyser, that turns addresses into functions. Basically, it takes the output of `objdump -d', and a list of addresses, and then turns them into the function the address resides in, and optionally the assembly language of the function. I've just been using `objdump | less' to do the same thing manually for individual addresses, but once you get more than a couple it gets tedious.

#> m 0x80e3fa00 64
0x80e3fa00: 0x80e3fab8 0x00000000 0x00000000 0x8000c394 0x00000010 0x80022940 0x00000000 0x00000000
0x80e3fa20: 0x00000000 0x8000b89c 0x80e3fab8 0x00000200 0x00000000 0x8000ba68 0x80e3fab8 0x00000200
0x80e3fa40: 0xffffffff 0x00000000 0x00000000 0x8000d0ec 0x80e3fab8 0x00000200 0x00000000 0x80022d68
0x80e3fa60: 0x00000000 0x8000b89c 0x80e3fab8 0x00000200 0x00000000 0x8000ba68 0x80e3fab8 0x00000200
0x80e3fa80: 0x00000010 0x00000000 0x00000000 0x80013294 0x80e3fab8 0x00000200 0x00000003 0x00000000
0x80e3faa0: 0x80e3fcd8 0x81204148 0x00000001 0x80013620 0x80e3fab8 0x00000001 0x00000013 0x000001e1
0x80e3fac0: 0x00000002 0x00000200 0xffffffff 0x00000001 0x00e3fb02 0x80022752 0x8004730b 0x80e3fb00
0x80e3fae0: 0x00000032 0x80008a84 0x80e3fb00 0x80046258 0x00000000 0x00000001 0x812040a0 0x8000851c

Dump that to a file on my workstation, then process it:

$ cat > a
0x80e3fa00: 0x80e3fab8 0x00000000 0x00000000 0x8000c394 0x00000010 0x80022940 0x00000000 0x00000000
 ...
$  cat a | while read line ; do ./crashdump -3 haiku-dump.text $line ; done
8000c31c <_ZN10MemoryDisk6ReadAtEPvxS0_m>:
                ...
8000c388:       e0811004        add     r1, r1, r4
8000c38c:       e1a02006        mov     r2, r6
8000c390:       ebfffba6        bl      8000b230 <memcpy>
                ...
8000b86c <_ZN10Descriptor6ReadAtExPvm>:
                ...
8000b890:       e1a0000c        mov     r0, ip
8000b894:       e1a0e00f        mov     lr, pc
8000b898:       e594f010        ldr     pc, [r4, #16]
                ...
8000ba28 <read_pos>:
                ...
8000ba5c:       e1a02004        mov     r2, r4
8000ba60:       e1a03005        mov     r3, r5
8000ba64:       ebffff80        bl      8000b86c <_ZN10Descriptor6ReadAtExPvm>
                ...
8000d050 <_ZN4boot9Partition6ReadAtEPvxS1_m>:
                ...
8000d0e0:       e0922004        adds    r2, r2, r4
8000d0e4:       e0a33005        adc     r3, r3, r5
8000d0e8:       ebfffa4e        bl      8000ba28 <read_pos>
                ...
8000b86c <_ZN10Descriptor6ReadAtExPvm>:
                ...
8000b890:       e1a0000c        mov     r0, ip
8000b894:       e1a0e00f        mov     lr, pc
8000b898:       e594f010        ldr     pc, [r4, #16]
                ...
8000ba28 <read_pos>:
                ...
8000ba5c:       e1a02004        mov     r2, r4
8000ba60:       e1a03005        mov     r3, r5
8000ba64:       ebffff80        bl      8000b86c <_ZN10Descriptor6ReadAtExPvm>
                ...
80013218 <_ZN18PartitionMapParser19_ReadPartitionTableExP15partition_table>:
                ...
80013288:       e0962004        adds    r2, r6, r4
8001328c:       e0a73005        adc     r3, r7, r5
80013290:       ebffe1e4        bl      8000ba28 <read_pos>
                ...
800135c8 <_ZN18PartitionMapParser5ParseEPKhP12PartitionMap>:
                ...
80013614:       e3a02000        mov     r2, #0  ; 0x0
80013618:       e3a03000        mov     r3, #0  ; 0x0
8001361c:       ebfffefd        bl      80013218 <_ZN18PartitionMapParser19_ReadPartitionTableExP15partition_table>
                ...
80008a00 <serial_puts>:
                ...
80008a78:       ebffffda        bl      800089e8 <serial_putc>
80008a7c:       e1a00007        mov     r0, r7
80008a80:       ebffffd8        bl      800089e8 <serial_putc>
                ...
800084e0 <dprintf>:
                ...
80008510:       a1a01003        movge   r1, r3
80008514:       e1a0000d        mov     r0, sp
80008518:       eb000138        bl      80008a00 <serial_puts>
                ...

Which is a lot more meaningful than a list of addresses.

Update: both of these are in the puppy bits project

Hmm, time to go in search of food I think.

Oh, turns out I was booting the wrong image with haiku ... so that splash screen really was less than it seemed. However once I changed to using the correct image, I get pretty much the same result - a pretty face but no brains.

Tagged beagle, hacking.
Friday, 05 February 2010, 19:23

Video killed the programming bloke ...

Well I was up till the wee hours working on some video code. Blah. Basically converting a register dump into code with #defined constants and other 'nice' stuff. Pity it doesn't do much more though.

Then I spent pretty much all day today failing at trying to get S-Video output working. But I just can't get it to work. I get some sort of signal out, and it looks like it could be the test pattern, but there doesn't appear to be any sync signal, and it's a bit weak too. At this point I think it might be worth cutting my losses and leaving it. For all I know the video DAC isn't even powered on properly - but to play with it's power you need to use I2C.

Actually that isn't all I did, as well as the video setup, I was `cleaning up' some other basic routines. Some clib-less debug stuff, and better exception handlers. I'm sick of rewriting bits of mess every time I try something new, and maybe this'll let me put it on the 'net at some point too.

I submitted some patches to Haiku too, one of which was applied within a few minutes.

Hmm, forgot to eat too, and now it's evening again. Mates are down the pub asking me along but I just don't fee like it today. Just finished a beer here and all I want to do is sleep now.

Tagged beagle, hacking.
Thursday, 04 February 2010, 16:02

Oops

Ok, so my MMU code was all broken. First I was just using the wrong number of bits in the L2 pages - x86 uses 4K pages with 1K entries, but ARM is only 1K pages with 256 entries, and I can't add up simple 2 digit numbers ... But even that didn't help ... many iterations and hours later ... ahh, I forgot to map the serial port - I was only mapping 16MB of i/o and there's another 1MB to map. Grr. Added that to the Haiku code and suddenly turning on the MMU 'works'.

Well it wasn't all wasted effort, I have a better understanding of the various permission and cache bits now. Better than nothing at least.

So ... ta-da ...

Actually it's nothing to be too excited about - that's all it does, and it's been hacked in very messily.

Tagged beagle, hacking, haiku.
Wednesday, 03 February 2010, 18:21

Damn MMU

I didn't have much time today but I had another go with the MMU, but this time on some stand-alone code.

No dice. It just goes off into la-la land as soon as I turn it on, no exceptions or any indicator of what went wrong. I guess the page tables are bung.

I can see this is going to be fun.

Tagged beagle, hacking.
Wednesday, 03 February 2010, 00:05

Haiku @ Beagle

Another day piss farting about on the PC. Ended up that i was up till 3 last night, so I was a bit tired, and had a nap in the afternoon, and even managed to load up the bin with rubbish from the yard ... but I made some progress, if not much.

So with Haiku I got the booting stuff worked out, loaded it onto an SD card, and tried booting it. Not surprisingly it doesn't get too far. After a lot of playing around I managed to get it far enough that it crashes as soon as it turns on the MMU. The page tables seem to be OK, I think (although it looks to me like it's using old-format tables, and they're not implemented in cortex-a8 afaict - but I tried some variations to no avail), and the other initialisation looks about right ... but as with just about everything i've tried doing on this machine, looking right and being right aren't the same thing.

Might ask about the status on the mailing list, and in the mean-time try some MMU code stand-alone - the load/test cycle is pretty slow going through the old SD card i've been using.

Tagged beagle, haiku.
Monday, 01 February 2010, 22:09

Muckin About

Another day hacking around inside - too lazy/warm to do the yard, and mum was down anyway, so was socialising during the morning. Hacking is more interesting anyway.

Kept poking around with the FORTH code, and managed to fix a couple more things. Silly mistakes like using the jonesforth versions of words rather than the (standard) ones I wrote. Got a rough POSTPONE implemented, but only for non-immediate words. And now, der, i've got a nice chicken and egg since I need it to implement IF (the way i'm doing it) and I need IF to implement POSTPONE properly. Ahh well; just have do it in ASM instead I guess, it's only trivial anyway. So I finally started filling out the higher level words, although not terribly quickly. Need to work out how to bootstrap it too ... ideally I would use a cross-compiler to generate everything into a memory image, but as the code compilation process itself extends the compiler, it makes things a bit more `interesting'. I'll think about whether that's worth worrying about (almost certainly not with this toy implementation), but to start with I guess i'll just compile it as part of the booting process on the target host.

Had a go over of the weekend at trying to get AI-OS (from the Touch Book) to work on the beagleboard, but unfortunately it looks like it no longer works on this hardware. Or I just did something wrong - i'm using a HDD since I don't have a big enough SD card and there's definitely stuff that hardcodes the SD slot. I finally got it to start booting using an Angstrom kernel, ... and then minicom crashed during the boot-up process, so I don't know why it hung - or even if it did at all, but after a few minutes I hit the reset button. And now when I try to boot the kernel just crashes with a NULL pointer, so it must've upset something on the SD card in the process. Ahh well it wasn't like I was expecting much ...

Also read a bit about Google's Go language. I can't remember if i'd heard about it before (maybe I have?), but I never looked too closely until now. Hmm, sounds fairly interesting ... might have to play with that next.

And today I also had another go looking at the ARM port of Haiku. Finally! The compiler builds! No more obscure error which makes no sense! Well that's a pretty good start anyway. Managed to get it to build (with a small fix for a renamed type), but am still working out the disk image building and Das U-Boot stuff so that's as far as i've gotten so far.

Tagged beagle, forth, hacking.
Saturday, 30 January 2010, 20:03

OMAP Exceptions

After basically doing nothing at all for a week apart from eat, sleep, and whine on the internet, I finally got off my arse (figuratively speaking only, sigh) and did a little more hacking.

I got a little exception handling bolted onto the FORTH code so at least now when it crashes I have a hint where it was, as well as don't have to reset the machine. I'd given up on it after wasting hours trying to get anything working a week ago ... all because of a silly missing .align directive. Bummer. And I wasted a few today too.

And I don't even need it anymore anyway!

ABORT: Exception Prefetch Abort
 pc: 52423020 sr: 200001D0
 r0: 8000E5C8
 r1: 00000082
 r2: 8000E5C0
 r3: 00000046
 r4: 8000E5D8
 r5: 8000E61C
 r6: 8001E5BC
 r7: 8000E5C0
 r8: 8000C008
 r9: 00000000
r10: 8000E5D4
r11: 8000D190
r12: 8000C094
r13: 8000E194 00000000 00020010 000008D4 8000B45C 00000000 00020010 000008E1 80009024
r14: 800092CC
r15: 00000000

Well isn't that impressive. Pity it doesn't really help with the bugs in my code. Although at least it does then simply jump back to the FORTH interpreter loop, so at least I don't have to resort to a hardware reset to continue.

I also changed the forth interpreter to run in user mode. Not because I really need to, but because I was too lazy to handle the exception stack pointer properly - since it was running in supervisor mode it uses the same stack pointer as the segfault-type exceptions. Probably it should run in system mode ...

Exception Setup

The following is just info for the few who might be looking for it - it took me a little while to dig it all up solely because I kept looking in the wrong places. It's not terribly interesting unless you're writing a kernel with no prior experience, it's not good code, and it's not even correct in many cases, but maybe there's something useful here for somebody.

The 'exception vectors' on the beagle are stored in the last few bytes of the omap's onboard 64K of RAM, and it is a jump table, not a function pointer array. Although they're actually setup so that there's room to use a function array immediately afterward by doing a pc-relative load, since 4 bytes isn't enough to do much else. The vectors start at 0x4020ffc8, although the Cortex-A8 also has a system control coprocessor register (c12) to move it.

So the init function just copies a 'prototype' image of the code across:

 // initialise exception vectors
 .global ex_init
ex_init:
 ldr r2,=ex_vect
 ldr r3,=0x4020ffc8
 ldr r1,=v_end_vect

1: ldr r0,[r2],#4
 str r0,[r3],#4
 cmp r2,r1
 blo 1b

 bx lr

ex_vect:
        ldr     pc, v_undefined_instruction
        ldr     pc, v_software_interrupt
        ldr     pc, v_prefetch_abort
        ldr     pc, v_data_abort
        ldr     pc, v_not_used
        ldr     pc, v_irq
        ldr     pc, v_fiq

v_undefined_instruction: .word ex_undefined_instruction
v_software_interrupt:    .word ex_software_interrupt
v_prefetch_abort:        .word ex_prefetch_abort
v_data_abort:            .word ex_data_abort
v_not_used:              .word ex_not_used
v_irq:                   .word ex_irq
v_fiq:                   .word ex_fiq
v_end_vect:

Where the ex_* labels mark the exception handlers themselves.

NOTE: it's missing the stuff to muck about with the caches, which is pretty important when you're writing code as data ... but for now it works. Perhaps I could avoid the code copy by just copying the address table ... I just don't know if I can assume that, or just use the system control register to move the table.

This is the first thing being done after Das U-Boot has executed the 'kernel image' - the only other thing i'm doing is setting stack pointer somewhere 'known'. I'm not entirely sure of the whole system state at this point (perhaps 'cpu powered up, and in supervisor mode' is all one can assume), so I don't even know if/what caches are even enabled for example.

Exception usage

Since all I want to do is dump some state and reset the interpreter, my exception handlers all do the same thing (apart from recording which one was invoked), but normally each exception type needs the correct return operations at least. It doesn't handle irqs properly either (right now i'd just like to know if they happen for no reason).

For simplicity my exception handlers just set a specific stack pointer on entry to do their work. That's because each processor mode and a few of the exceptions have their own shadow stack and link registers, and the only way to initialise them is to be in the right mode first. Again, too lazy.

After that they save all the register state to memory, and then call some C to dump the state, before jumping back to the FORTH ABORT code, with a reset back to user mode.

So an example of a specific handler (although I use a macro):

ex_prefetch_abort:
 ldr sp,=EX_STACK
 push { r0 }
 ldr r0,=3
 b ex_handle

Then it executes:

ex_handle:
 push { r0 }
 ldr r0, =ex_regsave+4

 // save original registers
 stm r0, { r1-r14 }^

 // save exception type
 pop { r1 }
 str r1,[r0, #-16]
 pop { r1 }
 // save pc, sr, and r0
 str lr, [r0, #-8]
 str r1, [r0, #-4]
 mrs r1, spsr
 str r1, [r0, #-12]

 // display something about it
 sub r0,r0,#16
 bl exception_dump

 // Now we want to reset everything and jump back to the forth loop
 ldr r14,=DOABORT
 movs pc,r14

The final movs also restores the CPSR and thus the processor mode.

Note: This is by no means particularly pretty or nice code. It was just the first thing I got working!

And the data-structure for passing to C:

 .data
ex_type: .word 0
ex_regsr: .word 0
ex_regpc: .word 0
ex_regsave: .word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

And finally the C code.

struct exception_detail {
 uint32 type;
 uint32 sr;
 uint32 pc;
 uint32 reg[16];
};

const char const *extypes[8] = {
 "Reset",
 "Undefined Instruction",
 "Software Interrupt",
 "Prefetch Abort",
 "Data Abort",
 "Not used",
 "IRQ",
 "FIQ"
};

void exception_dump(struct exception_detail *e) {
 int i;

 send("\r\n\r\nABORT: Exception ");
 send(extypes[e->type]);
 ...
}
Tagged beagle, hacking.
Newer Posts | Older Posts
Copyright (C) 2019 Michael Zucchi, All Rights Reserved. Powered by gcc & me!