Saturday, 30 January 2010

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]);
...
}

Friday, 29 January 2010

Can't help but mention it.

Apparently it's been on the news all over the place. It starts with a horrible name, and it just goes down-hill from there to make what can only be described as a horribly anti-human device. What was it again, the iMaxiPadTouch? Ho ho.

The name is bad, but then again, mums are buying wee's aren't they.

The hardware is pretty limited too. Ok so they have an interesting multi-core (arm?)-ish ARM processor, but the screen resolution isn't that high, the device isn't that light, and for the price the storage is pretty limited. But the real anti-customer feature is the lack of standard connectivity options. Sure you can get an ugly USB dongle, or an ugly SD-card dongle (but not at the same time). But why aren't they built in? What about HDMI? Could it be they don't want you to expand it on your own? Not even a camera? Props for the CPU and battery life, but the rest is a (big) fail mark. Even a PSP has more connectivity and expansion options built in!

And the software. It's a phone os. They might be ok on phones, but really, what sort of nonsense is it putting a phone os on what is really a general purpose computer? A locked down proprietary system that only allows you to get software from a closed network service. What year is this again, is this 1990 calling? The lack of multitasking is inexcusable - that's 1980 calling. Not having macromedia flash seems reasonable to understand (flash does suck) until you realise it's just another vector for controlling what media you can access, particularly, and specifically I suggest, locking out free media and those horrible free games (that people nonetheless love to play). This is the same reason Java is not supported. It's not about performance or security, it's about control.

Which brings me neatly to the media aspect. This is a device whose specific aims (if any can really be discerned) is to turn the free internet into a paid-for proprietary and locked-down service. It wants to turn everyone into a 'consumer' of corporate produced paid-for content channeled through their own toll-booth. I don't think a more anti-customer, anti-choice, anti-web '2.0', anti-progress and anti-freedom device has ever been created (a title that would make even Microsoft blush).

This is a very strange device. None of the benefits of a phone or media player (small size, camera) and none of the benefits of a laptop or even 'netbook' (open platform, expansion and connectivity options, real keyboard). It's too big to carry everywhere, and it's too useless to want to - it's really just a hand-held TV/set top box combo you can use to read the paper on the toilet (but isn't as useful if you run out of dunny paper), but there's no reason to take it further than your front gate. And apart from just being 'bad value' like most Apple Inc hardware, this device should be avoided like the plague if you have any respect for our cultural progress due to its draconian control of media content and software.

Compare this to something like the idea of the Touch Book (unfortunately the software in particular isn't quite there yet). Less memory, a bit slower - but lower price. 7(!) usb ports, 4 of which are internal to the machine, a machine you are expressly allowed to open. A replaceable SDHC card for OS and storage. Multiple operating system choices, far wider media support. A user replaceable battery. No digital restrictions management (DRM) telling you what you can do with your own data on your own machine. A half-decent keyboard, or simply use standard USB or blue-tooth keyboards. You can use it to write your own software. music, or create art, and learn about computers, not just consume paid-for content like some sort of slime-mould with no brain or creative spark of your own. The software side is still lacking, but that's only a matter of time before this or another device makes it.

Really the choice couldn't be more stark, and this is a perfect demonstration of why Free Software really matters. Do we want the future of our computers - and thus our society and culture which is now entirely dependent upon them - to be a shuttered, uncreative, paid for, controlled, and censored one, or an open, investigative and free one?

No amount of some balding, badly shaven, middle-aged poof in a black skivvy sitting on La-Z-Boy proclaiming how innovative the iTampon is makes it true. If he really believes that this is the most important product he's launched then you can add senile to that list too, or if he doesn't, then outright liar. The only innovation will be if they somehow convince a large number of people to buy such a nasty, anti-human device.

Wednesday, 27 January 2010

GNU/Linux out-competes another company ...

So Sun has cleared the final (?) hurdle to being bought by Oracle. Well good for them, a lot of smart cookies will keep their jobs to feed themselves for another day. I do feel a bit sad about it - like many, SunOS was my introduction to Unix 19 years ago, and Sun was always one of those 'cool' companies, they made nice looking hardware and weren't just about marketing hype; they had meat under those feathers too. Were they the last true technology company?

In less than 10 years, they've gone from basically running the .com bubble to running out of money, and here's one major reason: GNU/Linux.

Oh sure they could've done things a bit differently - such as free Solaris or Java a bit earlier, but I don't think it would've made much difference in the end. As microsoft are finding - it's pretty hard to compete with `everyone', particularly when it's free. And it's not just the price - free also to take mind-share which is the real killer for any technology company. That GNU/Linux was pretty much a 'Solaris clone' from the start surely didn't help either (I did much of my earliest GNOME code on Solaris - the code was easily ported to Linux).

I wonder which company will be next?

Tuesday, 26 January 2010

You'll be censored!

If I did it right, hopefully you got a (at least) slightly alarming popup box about the planned government censorship during this week. See more details at The Great Australian Internet Blackout site.

I guess 66% of my visitors are from overseas and the other one knows about it already, but I thought it was an interesting form of protest ...

Friday, 22 January 2010

Bumbling along like a ...

Well, A/C supposed to be fixed today. Finally a service tech was called and came yesterday, and a couple of minutes on the roof and he was ordering a new control unit. Dodgy caps not too uncommon apparently. But because of the increased demand they don't have any spares ... hopefully that's all it is, as it's just in the nick of time - weather starting to turn hot.

Kept bumbling along with my FORTH attempt. Would really help if I concentrated a bit better, but lack of sleep and so on. Not entirely switched on. Still, making some progress.

I decided to standardise some of the basic words, which meant a lot of breakage. But I more or less have that going, and implemented DOES>, which jonesforth didn't implement. These changes mean I wont be able to use much of the bootstrap for jonesforth either - but I guess that will just make it a better learning exercise, wont it.

I'm still sticking with assembly where possible, although considering just using c for call-outs to significant processing steps; that's basically how the assembly is written anyway. I'm finding reading the standard a bit tough going - understandably it's target audience is really people who have a lot of experience with FORTH implementations already.

It's a huge mess though, but perhaps now some of the basics are starting to work I can think about cleaning it up a bit. Then add a few bits and pieces and then start trying to use it. I want to add some hardware exception handling at least, so crashes aren't fatal. And I need to be able to input from memory to bootstrap the code. Well something to keep poking at I guess.

Tuesday, 19 January 2010

The saga continues ...

Well to answer the question posed two articles ago - nobody uses those old things anymore. Just had the sparkie around and he wired the a/c on a separate breaker (probably as it should have been in the first place) and moved the kitchen/laundry to a breaker too. He said they only come across those fuses when dismantling old fuse boxes.

So all that done, time for a hot coffee.

But the a/c didn't work either - panel did all the right things, pump too, just no air being pushed ... then it blew the breaker. So another visit from the installation guys basically just to confirm it's just broken and now a call's been lodged with the manufacturer for a 'service call'. Hopefully it's just a bung controller.

The insulation guy eventually rocked up yesterday too - and I had it installed by the end of the day. I suspect there's an awful lot of roofs in Adelaide that fall within the 100sqm limit of the 'average house' (hah, asif). Quite painless, although who knows how effective it is - they split some of the bats up to lay over the old stuff.

FORTH

Mucked about with the FORTH some more, with all the interruptions and comings and goings that didn't happen till the evening - and then about 9pm I noticed it was dark. Not sure if that's a good thing or a bad thing (I definitely know that the 2 packets of chips and beer I had for lunchdinner[sic] was a bad thing though!). But as you'd expect given that it was a new processor to me, and that I was too tired and interrupted most of the time I was working on it - almost everything was wrong. Wrong registers in places, wrong order of registers, incorrect memory calculations and so on and so forth. But after many many iterations of fixing one function at a time I finally got something that compiled basic functions ok.

: a 42 EMIT ;
a
*


Well, "yay".

The current INTERPRET loop processes every character as it receives it - with no line editing and so on, so I thought about improving that. Didn't feel like writing that in assembly, so I fell back to C (TBH the compiler does a very good job with ARM code for the most part - but the core FORTH works better in assembly). I wrote a simple little 'readline' function with basic editing for single line input (cursor keys, delete, backspace etc) using terminal escape codes. That should do the job to start with once I hook it in.

As an exercise I thought i'd port it to FORTH instead. I was quite surprised - it (well, on paper - I don't have enough bootstrapped to build it yet) came out smaller (well no surprise there) and easier to read than the C equivalent. There's a few ugly bits but they can be hidden (or written better - no expert here). That's really what makes FORTH an interesting language, because you actively extend the language or add trivial functions to hide details without any penalty (in runtime or source baggage) for doing so. And it is real language extension including syntax, not just the run-time library. In-fact, since a threaded-interpreted run-time is so small I imagine the original powerful concept was that you could even radically alter that if need-be, although I think standardisation efforts muted the use of that `feature' to some extent.

I do think it falls down a bit on the variable front - they all work as explicit pointers, although I noticed there are now 'newer' concepts like 'values' that abstract some of messiness (and inefficiencies) away. And generally this stuff can be hidden away from most of the code.

Anyway, I'm quite enjoying this, so I'll see where it takes me, i've already got some ideas for tweaking the implementation and so on. Tho I'd better get outside and fill the bin with rubbish today as well, or it'll never get moved.

Monday, 18 January 2010

Freshly Picked

Blah

I knew the day was going to go wrong when I forgot to put coffee in the espresso maker before putting it on the stove.

  1. Aforementioned extra-light coffee. Well I guess it needed a bit of a clean anyway.
  2. The government is running a silly middle-class welfare effort to upgrade or add insulation to homes. Someone rang about it yesterday and was supposed to rock up at 8 (this early rise is almost certainly the cause of the coffee incident). They did call just after 8 to say they'd be late - 10. It's now nigh on 12.
  3. I called the A/C people about my dead A/C. Ok no problem, we'll have a look.
  4. Did 'one last check' before I embarrassed myself, not expecting anything. Lo and behold - it worked.
  5. Called to let them know, but still wanted to talk with a tech. He was busy so they'd call back.
  6. Left it running. Went to make my coffee (coffee in espresso maker this time), I use a microwave to heat the milk. Ahh dead microwave. Threw me - rest of house is working. Ahh blown fuse.
  7. So ... back on the blower. Ok they'll try to get someone out today.
  8. Couldn't work out which fuse it was, so ended up rebooting the whole house one circuit at a time as I checked. No replacement fuses, and the thing doesn't use a wire either. 5km to the nearest hardware store. Might be time for a ride.



Between me and a hot coffee or a cold house. Who the hell still uses these old things anyway?

Sunday, 17 January 2010

Now I'm Just Tired.

*yawn* wow i'm tired. Although I bet it's not a patch on friends whose family just grew by two today! Congrats to Jon and Kate on the twin girls.

Just sat around hacking all day - that wouldn't help. And eating too much pizza - trying to use up the sauce i defrosted! And I had a long day yesterday, ending with a 1st birthday party for another(!) set of twins in my circle of mates.

As it happened, whilst I was was writing the last post my brand spanking new A/C died! Feck! I thought the 'new pad' smell smelt a bit more 'blue smoke' than it had the day before, but didn't take much notice till a few hours later when nothing was working (I was in another room without vents). Ahh well, just as long as it's fixed promptly, at least it's cool for the next few days.

Well I thought i'd take a break from the interrupt stuff and had the notion of playing with FORTH for a change of pace. I never was much of a FORTH hacker but was always intrigued by it from when I was a kid with a Commodore 64 and somehow ended up with a copy. Even the local country-town library had 'Starting Forth', which is a rather novel programming book (and even if you don't like it, you'd never forget it). I think I even wrote a 'parallel cable' loader for the version I had! For my uni computer hardware class I wrote a type of FORTH as a shell on our hand wire-wrapped 68000 based computer so I could interactively write a program to blink the LED rather than having to re-write the EPROM every time I had a bug (yeah an EPROM! The ones you have to erase with strong UV light!). Although FORTH has been used repeatedly as a bootstrap/bios system for many years had no bearing on wanting to try it, it just seemed like a 'fun' thing to look at again.

Thought it'd be a good opportunity to learn a bit more about ARM assembly too. I found a simple forth implementation written in x86 ('jones forth') and so set about porting that (seemed easiest - it's been so long I couldn't remember much, and I know my implementation did a few things wrong). I was making really good progress until I hit some of the larger functions, but that was because I was trying to write reasonably decent code and learn some of the ins and outs of assembly language.

ARM assembly is more powerful than I thought it would be - in every case the code is cleaner and simpler than the x86 equivalent (excepting /mod - no divide instruction) - although x86 is particularly arcane (to be atypically polite of me - in reality, I think it's shithouse), so that is probably to be expected (and given that every instruction is always 32 bits long, it gives a lot of bits to play with). At first having a condition code check on almost every instruction, condition code updates optional, and a 'shift' operation seemed quite obtuse. But it has a sort of synergistic effect, practically giving you all sorts of extra base instructions let alone super-instructions that do two or three things in one. It's probably more compiler friendly than hacker friendly, but the assembler has some support to aid humans, like automatically choosing the best way to load a 32-bit constant (immediate constants are only shifted versions of 8 bits, so often you need a register/pc-relative load).

So far I have managed to get pretty much all of it typed in and assembling at this point, but then I was too tired to try booting it up and fixing all the bugs. It's only 1000 lines of assembly - most of which is 2-3 line functions, comments and meta-data, so it shouldn't too bad.

Friday, 15 January 2010

Interrupted train of thought

So i've been trying to get interrupts working on my beagleboard since yesterday ... bloody hell what a hassle. First I was trying to get a 1Khz clock going but not having any luck I switched to getting the vblank interrupt going. Of course, writing to the registers properly rather than using the offset as an index to an int * went a long way to making progress there. Damnit I keep doing that, envisioning each array access as register indirect with offset, when it isn't quite that. Yesterday I didn't make much progress - the busy workers, the noise, and the ungodly early start to the morning kept me from being able to concentrate on anything too much.

But even after working in it most of today ... it still isn't there. I (finally) get the interrupt ok, but then it never turns off and instantly returns once it's finished. Well either that or causing random crashes in the non-interrupt code. So some problems with the interrupt handler somewhere itself - like clobbering registers - as well as the way it's talking to the hardware (I'm clearing the interrupt everywhere i've discovered it needs clearing - the DISPC and the INTC). Might leave it for the weekend and see if a fresh mind doesn't help.

Oh, I also ran across some curious behaviour with the assembler and/or linker. I had some code intermixed with some constant strings. The code following the strings was all messed up, it was being written to non-aligned addresses (which is wrong for ARM). And even when I fixed that up with a .balign pseudo-op, the memory references within the code were wrong. e.g. a function call jumped to the wrong address - out by 2 bytes. Moving the strings after all the code segments fixed everything up. *shrug*

The A/C got installed ok yesterday - well eventually. The ceilings turned a 3 hour job into a 7.5 hour one. Although I think some of that was just throwing the installation guys off balance a bit. Well, it's all done now. Nice too - managed to sweep away all the stale smelly air in a matter of minutes, which was a nice bonus ontop of the cooling. Now I just need a good stretch of hot weather to test it properly. February is always guaranteed to oblige with that, and is just around the corner. Also cleaned up some of the wood in the yard from the photo in the last post. Not that you'd tell if I took another picture now.

Just went out for a few drinks and was hankering for a pizza on the way home. Nearly dropped by the local joint but needed a wee more than some baked fat. So being the tight-arse hermit I am, I thought i'd make one up rather than venture back into the wilds of the night. I also wanted to try and use some chapati as the base. I've been too lazy to make yeasted bread lately, so chapati has been a bit of a staple when I felt the need for some bread. Had some frozen sauce left over from earlier efforts, chucked on some bacon, cheese, onion, capsicum, chillies and even some thinly sliced squash (i'm drowning in the damn things), bung it in a hot oven, and bob's a dead cousin.

So for something a bit different, here's the chapati recipe I use, although there's not much to it:

  • 1.5 cups plain flour
  • 1 cup wholemeal flour (adds a nice texture)
  • 1 cup water (warm)
  • 0.5 - 1 tbsp olive oil - vital, stops it sticking to everything like glue

Mix together till it forms a dough. Knead for 10 minutes. Rest for 10 minutes wrapped in glad wrap. Break off a 3-4cm ball and roll out flat with a rolling pin to about 2mm thick. Cook on a dry medium-to-hot frying pan or hot plate for 1-2 minutes per side - until it dries out on top and goes dark on the bottom and puffs up a bit. Dough can be kept in the fridge for a day or so until needed, so it's 'single friendly' - it gets a bit tougher which makes a stronger bread too. This will make 6, and they are very filling (each one is approximately equivalent to 2-3 slices of typical wholemeal bread).

The cooking and how thin you roll it is tricky to get right. I've had everything from crunchy `salada' biscuits (which gave me an idea, might try making crackers one day) to something very like naan bread (much preferable with a typical meal). If you cook with some oil it turns it into a sort of fried pastry/tough pancake - tastes great but just has to be bad for you. I've also tried using a pasta maker to roll the dough, if you don't mind it not being round. The layering you get if you keep doubling and running it through the machine also alters the result (don't go too thin of course). It's supposedly possible to have it puff up like a balloon if you finish over a hot flame, but I've never managed it.

For the pizza I undercooked it a bit since it was going in the oven as well, but cooking it a bit first made it a lot easier to handle and put on the pizza stone (something I never managed with bread dough without using baking paper).

Thursday, 14 January 2010

Then a bomb went off.

Finally got out in the yard late yesterday, and this:



became this:



What a mess. Fortunately it was easier than I had anticipated, it only took a couple of hours for all that destruction. The posts were just sitting in the ground so they were pretty easy to remove.

Actually that first shot is from before I removed all the paving and dug the foundation trench for the retaining wall, so it's more like a weeks work between photos (or 6 weeks realtime ;-).

Getting a ducted evapourative a/c installed today - was originally penciled in for Monday so I would presume the guys are quite happy it is a nice 25 today rather than 42. Although they're not that pleased the ceiling is a very old style plaster type, which they didn't quote for, but I guess that's what the salesman gets for being too busy to visit the house first. Looking forward to getting some fresh air through the house, and during the last heatwave having the split system running all day was both expensive and dried the air out to an uncomfortable degree. And it'll be nice having the bedrooms all cooled too.

Wednesday, 13 January 2010

Roar.

Hmmmm, well I was wrong about why newlib was crashing. It's because the 'loader' is just executing the code in place, and the default linker script (that i've modified slightly) was re-aligning the data segment load address, but not the file offset. So again the data wasn't aligning with where the code expected it (rodata was still, which was confusing of course). For now I just removed the realignment of the data segment and yay, libc now seems to work.

It was still crashing in C++ though.

And of course, I downloaded the wrong version of the toolchain, so I didn't have the source to go looking through. But while it's downloading the right version I poked around on the cvsweb interface for newlib and found the right bit of startup code anyway. Ahh, missing a call to _libc_init_array.

Still crashing.

Hmm. At this point i'd developed the exception handler to dump the registers and some of the stack and was looking at finding out where in the C++ code it was crashing, so I recompiled with no optimisations and debug on. Damn, now it started working!

Mostly at least. Something is still wrong with bss in it or something - every time I compiled it it displayed using a different zoom/shear/rotations. Although if I set those explicitly, it all works fine.



Not terribly fast - every lion takes just under a second to render.

I've identified that the C code can't be compiled with optimisation -O2 or higher, so assuming there's no compiler bug, there's something in the dodgy setup code that's out of whack (C++ is compiled with O3 fine, but it isn't doing any of the hardware banging). But that doesn't surprise me in the least (missing volatile's and the like), and for now it can stay being unoptimised.

I've kinda forgotten why I wanted to render 2D polygons in the first place. I think it was to avoid storing big bitmaps, but using C++ seems to drag in stdio (for exception reporting) which blows code size out to about 200K anyway. Might be better off with a small PNG decoder instead.

Tuesday, 12 January 2010

Interrupts and exceptions

Yay, the weather finally turned. By the end it was just getting crazy - I'd accidentally left open a window in the house all day (or for a few days) and half of the house must've been 35 or more. Didn't think it was worth cooling it down - I just barricaded myself in a smaller part of the house with separate ac. A bit of rain too, not really enough but it'll do.

Should've got out digging in the yard this afternoon once the rain stopped but instead i've been poking around trying to get some stuff working on the beagleboard. I was trying to get AGG to render some stuff - but it's C++, and I don't really know enough about the execution environment of C++ to get it to work. But not even malloc() works in C, so for now i'm just trying to get that working (it uses newlib, and it crashes before it gets to calling sbrk()).

Since all I was getting was at best a silent death, I figured I'd work out a little about exceptions too - at least find the address of the crash. I misread the bit about interrupt vectors at first and spent a lot of time chasing that down ... I was writing a vector of addresses to the interrupt vectors, but it's actually a jump table. I found this out early on but forgot to fix the code and went off on a very long-winded goose chase trying to work out what was going on after some mis-direction from the mailing list archive. Well with the hot weather I hadn't been getting much sleep, so perhaps there's an excuse!

Well it told me it was crashing in malloc - but i knew that already. Can't easily figure out what's going on without source (it's something to do with static intialisation), so downloading the newlib source now (actually the whole toolchain), which is gonna take forever since I blew my quota.

Friday, 8 January 2010

Limited success.

Well I had some limited success on the DSI PLL clock front. I found some posts on the newsgroup and decided to look more closely at the kernel source too. Well I sort of got something working, eventually. Using the 72Mhz clock as the source for the PLL anyway. I dunno, it doesn't seem entirely right, and the monitor keeps dropping out every 20 seconds or so, so I might just leave it for now. At least I have a few of the bits needed.

I played a bit more with the matrix code. The snakey things move down the screen and react to things and bounce around like they should. The X-Y zappers move and 'zap' every now and then, planting a seed where they meet. Which ages and then drops off the screen. Even have a sequencer setup that describes the waves.

And I have screenshots! People like pictures don't they? Although it's only using putchar() as the 'rendering engine' at present!

This shows part way through wave 1, with the X-Y zappers just having fired.



And this shows a little later on - the attack ships and XY zappers have moved on a bit, the X-Y zap from the last shot planted a seed, and one of the earlier seeds have died and is currently falling down.



Bugger all code so far. Adding some user-controlled ship and bullet logic should be a doddle on top. Even played a bit with blender to draw some ships (actually I tried gimp first, but I really can't draw at all, not even slightly pleasant looking blobs), although implementing any graphics display is some distance off.

Now for another rant, sort of.

Since i've been back hacking for a while there's one thing i've really noticed. Boy is it much nicer developing using a GNU/Linux box than using Microsoft Windows (and that was XP, which is supposedly the best one). Ok this machine is a bit faster - quad core instead of dual, but the difference goes well beyond calculation speed. Everything is so much smoother and faster. I used to wait around for 30 seconds (I actually timed it) just for the friggan HELP to come up most of the time! Switching applications or desktops (using VirtuaWin) crawled. Even just using the browser ran like a pig after a few tabs were open. Pretty well everything I needed to do, every time i needed to do it, just seemed to illicit a groan of discomfort at the pain I was sharing with the CPU as it struggled to complete the task. I rarely even get the time on this box. And when it does take a while, it's usually obvious why.

Currently I have 5 x emacs, 1 x icecat (with 53tabs), 1 x javam (in icecat), 1 x blender, 1 x evince with 14 documents open (between 4 and 3500 pages long each), 1 x gimp, 1 x transmission, 1 x seamonkey (650MB alone!), 11 x xterms, 1 x xfontsel, 1 x gdb, synaptic, and even mythbackend recording tv as I type. The machine is using 3.5G RAM, and 1G of swap and has been up for 2 weeks.

Yet it just about runs like I just logged on.

Everything is snappy, and stable, I have all the tools I need at my fingertips - without having to use the mouse for every. click! little. click! fucking. click! thing. click! i. click! fucking. click! need. click! to. click! fucking. click! do. click! click!

Not going to enjoy going back to a windoze machine for work, if that's what I get lumped with.

Thursday, 7 January 2010

Well that was a bit of a waste.

Blah. Spent hours and hours trying to figure out some of the clocking on the OMAP. My video output isn't quite correct at the moment - it works with my monitor, but it'd be nice to fix it. But I just couldn't get anything I tried to work. The documentation has strange examples which are a bit hard to decipher. I thought I managed to work out the programming of the clock it was using, but then the serial baud rate changed. Damnit. Tried using the other clock - and that took even more digging the documentation - but I can't get that to work either. The linux source is a bit convoluted but I might have to resort to working that that out to understand what's going on - the clocking system is pretty ... complex (there are dozens of clocks, with many cascaded from others).

My new FSF membership card came in the post - or at least I got it out of the letterbox today. Bit thicker than i'd hoped - it's like a fibreglass PCB, so it might not make my wallet. The Trisquel installation is quite nice too - well setup, quite polished - everything just works. With a good selection of real applications too, like openoffice.org, gimp, inkscape, gthumb, and even evolution. Unlike some distributions with their weird application choices. Pity it's debian based mind you.

Hot again today - garden still alive somehow, at least the bits I remember to water. Getting a few (small) cherry tomatoes off every day - enough for a little salad. I suppose I need anything I can get to help my crappy diet lately. I even managed to get out for a bit - although it was just for groceries. Is it just me or are the roads a lot busier these days? Sigh.

Wednesday, 6 January 2010

gloat 0.1

I'm sure i'll live to regret this (i can already hear the glee of some kid discovering a buffer over-flow - well, in the unlikely event anybody ever downloads it), but i've uploaded my news snarfer 'gloat' to Google Code.

gloat - it's a bit like brag ... err, geddit?

I'm going a bit loopy today. I was up till around 4am working on a 'matrix' clone (C64 - llamasoft), although now i've lost interest in it somewhat. And after a little mucking about in the garden have been solidly stuck behind my machine reading the net, manuals, and poking at bits of code all the way through till nearly 8pm - again. Well I had some lunch and coffee somewhere in all that.

Oh - it was too hot today to do much outside, but I suppose I should be using the weather to go to the beach or do some cycling or something I can't do all the rest of the year.

Tuesday, 5 January 2010

Wrong UART

Well I got serial output working - was using the wrong UART (should've read the docs before assuming UART1 - it's UART3). And Das U-Boot leaves it properly configured so the output function is only 3 lines of code.

Then I hit an issue as soon as I started to use static data - my code wasn't being loaded at the right address (which took me some time to realise, since the code still ran). I don't really know why it works but I fiddled with the Das U-Boot mkimage line and now it's loading everything to the right address - it should be loading at 0x80008000 but I need to tell it to load at 0x80000000 to make it work. *shrug*

I got sick of ripping the SD card out to setup a new 'kernel' image (and a little worried, the SD slot on the beagleboard isn't really designed for repeated use), so I rigged up a rather nasty `runscript' (from minicom) script which uses ymodem to upload the image whenever I reset the machine. While the image is small this makes the testing cycle pretty easy. Just need a serial port thingy for my workstation and then I wont need the laptop anymore either.

Also along the way I wrote up some basic graphics output - just to clear the screen and display text, including a simple printf type thing. I converted my favourite font 'fixed' to a c file and can now dump text to the framebuffer. Originally I just wanted it to get some debugging output since I couldn't work out what was up with serial, but it's still handy to have.

And lastly I had a bit of a play with the DMA engine. And after a LOT of mucking about, finally got it filling rectangular regions. I couldn't for the life of me work out why double-indexed DMA just did nothing - in my haste to avoid reading the docs too closely I missed the bit which says exactly how it calculates the next address after a 'frame'. I had the alignment mucked up so it did absolutely nothing. If nothing else, it can be used for a very basic 2D accelerator - 90 degree rotations and flips, rectangular moves/copies, solid colour fills, and even masked sprites (colour keyed). So now my 'random filled box demo' runs a lot faster than it did before - around 10x actually (not that it was particularly optimised or anything).

I did some research on USB. Man what a mess that is. A few books i 'found' on the topic were useless too, just written from the perspective of windows driver writers at best (when a book uses 'visual basic' for 'portability' you know there's something very very wrong). I found some USB host stacks but they're proprietary, GPL2.x only, or BSD + advertising clause. And in any event tightly coupled to a given OS (as they must necessarily be). The Haiku one is at least X11 licensed, and clean and simple, so apart from being C++ might be the place to start if I decide to hurt myself one day with that pain in the head.

Hmmm, perhaps interrupts next, will have to get my hands dirty with assembly at some point.

Monday, 4 January 2010

Unripe fruit and vegetables

It turns out I kept picking my cucumbers green. Of course, they were just like the ones in the shops - seedless, pretty bland (although not quite so bland) and 'normal' sized.

I missed one for a few days and picked this giant - about 2' long and 5cm in diameter. Wow. That's what cucumbers used to taste like. And of course do - if they're ripe.

Same with the button squash, I'd been picking fiddly little ones, often a little bitter with a very soft skin that spoils easily. Again I missed one for a few days - and it's a world of difference. If they grow to about 10cm across or more and get the harder outer skin they taste much better (a little sweet) and last much longer (i'm also letting one grow 'all the way' to see how big they get/how it goes - it's about 25cm across after a few weeks).

Green limes - fully ripe limes are light yellow. They taste utterly fantastic and have much more juice too. Although certain varieties, such as the Tahitian Lime can get a funny over-ripe taste, so there is some justification for picking them a bit earlier. But not when they're hard and dark green. But most of the time that's all you can find in the shops (let alone the exorbitant price).

People have been trained to buy this unripe fruit, so nothing else sells. How silly. They must be right down on vitamin C and other nutrients as a result.

Why is software so far behind hardware?

For various reasons I was trying to get some binaries from some very large newsgroups - so large that I couldn't find any client that would even list all of the messages without hanging or crashing. Interestingly, I found the mail/news application in seamonkey to be one of the better ones - it worked much better than thunderbird, using far less memory, although it still got stuck very often, and that was only with 200 000 headers rather than the 6 000 000+ in the group.

I saw a few scripts/programmes for grabbing stuff in the repository for this machine so I gave them a go. I can't remember all I tried but `brag' seemed to fit the bill and worked ok on a smaller test group. Well, needless to say it just didn't scale. Either the code is bung or tclsh has a big memory leak or simply isn't up to the task. It managed to download all of the subject lines (meanwhile memory use - ~2.9G!). Well my machine wasn't really swapping so big deal eh? But then when matching the headers memory use continued to climb - even faster. It ran out of 32-bit virtual memory ... well I guess I should've been using a 64-bit OS for such a complex task!

Err, no, that's just bullshit. So I hacked up a quick and dirty C version. Has somewhat fewer features but works more or less the same for what I needed. A bit over 400 lines of code in total, only using libc. No smart algorithms apart from a zero-copy 'read-line', no asynchronous reads or other decoupling of net i/o from disk i/o or processing, etc. Total memory used whilst reading and saving the subject headers of said 6 000 000+ group - about 100K (and most of that is from the C library, I think I malloc about 50 bytes, and have 11K of bss). Total CPU used, about 10 minutes real-time, and about 5 seconds cpu time (top consistently showed 0% cpu usage - well I mean as it should, it's entirely CPU I/O bound!). It takes about 3 seconds to scan the 780MB cache of titles with a regex when they're in the buffer cache, about 10 otherwise (using the same amount of memory).

Alas, this is the world we live in. This is why a `netbook' isn't big enough to run `real' applications - it will just be destined to run slow scripts which proxy the heavy lifting (when it is quite capable of doing an awful lot of the heavy lifting itself). It will be kept busy struggling to show adverts instead (even something my 4 core machine has trouble with, so I turn off animated gifs and flash and block lots of advert pics). This is why, after all the advances in hardware, we now have shitter apps that run more slowly - e.g. for all it's cracked up to be, compare google-writer to say, abiword, or calc to gnumeric - with no other benefits like stability, security, and so forth.

I was looking at javafx again just recently. Someone hacked (and I mean hacked) up a sort of 'space invaders' game. Except it has no sound (could be my use of oss4), no barriers, the aliens don't move properly or speed up, and unusable controls. And it jerks around in an unplayable fashion, with tearing and an utterly atrocious frame-rate. Flash et al are pretty much the same to me. Slow, jerky - crappy games. The machine in question is capable of emulating real hardware faster than that - you can play the real space invaders (or for me, the C64 version) with proper sound, control, and 'game' all in it's glorious full-frame-rate goodness with no problems (and so it should, it's emulating a 30 year old computer!), but it struggles with a half-arsed rip-off.

Poor algorithm choices. Bad language/framework/environment choices. Poorly implemented language/framework/environment. In short, poor engineering and system design.

Computer Science lecturers always say `we don't teach computer programming'. And it's pretty obvious - no, no they don't.

(TBH `brag' does more processing than just a regex match on the titles. It tries to find the filenames, and count the parts, and tries not to grab duplicates. And it uses multiple connections to improve downloading of the actual messages. Still, there's no reason it should use anywhere near that much memory, loading all subjects into memory at once is not ncessary.)

Saturday, 2 January 2010

Coloured Boxes

Was feeling a bit blah and too lazy today so instead of cracking on in the garden I did a bit of hacking. Ok, it's not much but I got a bit of code running on the beagle board that draws random coloured boxes to a framebuffer.



It's being loaded as a kernel image directly from u-boot of course, and then just `banging the hardware'.

I just snarfed the framebuffer init code from the splash screen from an old version of u-boot, with a few tweaks - remove the writes to read-only or unmapped registers and changed the screen size to 1024x768.

Hmm, not sure next. Maybe a serial driver. USB would be nice, but a bit much at this stage. Or the retaining wall!