ProudSkibidiTolietAryan
kiwifarms.net
- Joined
- Apr 18, 2025
Well lets start with HOW I did it.I got it working without a kernel source.
I will make a long blogpost detailing HOW I figured out how to get the vmlinux working but it involved tweaking and using big brain moves/ideas in order to get it semi working. I think the UART isn't printing everything that it should. But to get it to even start PRINTING was a pain. But honestly it kinda was a out of the box working thing besides some tweaks. Its kinda insane HOW good qemu is.
View attachment 8299282
So first things first its able to execute a few thousand instructions before seemingly crashing
Well shit thats not good. But hold up think... Think.... Why am I doing this? Well im doing this because the vmlinux IM USING messes up when running the phillips binary because of timings that likely are specifically defined in the main kernel... So that is why instead of using a random vmlinux image I try to run the one that TV uses.
Timings.... Timings WAIT A MINUTE TIMINGS. What if its expected to run at a timing or slight delay, what if the vmlinux is designed around the hardware doing that? Ok so I asked grok for any command lines that might be of use and I was told to do
OH THAT DID IT ITS MOVING MORE, its moving very slowly after the instructions but its moving now.
Alright now lets think. What stage is it likely at? Well we don't know. I dont think many people have studied the assembly output of mipsel vmlinux images... It could very well be at the very first stage for all we know.
What I want to know is if things ARE being printed to the screen if things are being printed to the screen than we will know that its made it past its bootup phase. Problem is that no matter what append options or anything we get nothing printed to the screen. All we have is the assembly output that can be enabled via -d in_asm
Well I have a theory. If we were to get ALL the assembly instructions that got executed by qemu it would be over 410kbs. Which is HUGE. It makes me think that we are WELL past the part of the FIRST console log. I really do believe that it IS printing stuff its just that QEMU does not know where to place it. If it IS past the point to where it would be printing things to the screen then the fact im not seeing anything is likely because the UART memory address for the default malta board do not align with this different board the vmlinux was made for.
So how do we comfirm it? ... RAM. THATS IT. If it got printed I bet that somewhere it would be stored in memory. We JUST HAVE TO GET QEMU TO DUMP THE MEMORY OF THE THING.
Using Qemus terminal we can take a dump of the ram. If anything was being printed to the console it would also show up here. Now we can see if it has gotten far enough to be printing stuff to the console.
Alright so Ive taken a HEXDUMP of the ram and lets see where we can find where its printing to because remember this kernel uses a UART not a normal TTY.
(after a bit of scrolling)
BINGO its at 0x02d7828 we can write a basic UART system in QEMU that basically just reads those memory address and prints them to the console to get things well printed to the console. Malta which is the default board that QEMU uses for mips has different registers and different memory addresses for its text output/uart that dont play well so we can just manually do it.
Well there is a small problem..... Do you remember last time when I said im not on my main modern ryzen processor but on a old shitty laptop running windows from my childhood because my MAIN computer needs to be repaired..... Yeah im still at that stage and compiling QEMU with....
a pre ryzen amd LAPTOP cpu(if you do not know most cpus made before ryzen and after 2010 are considered some of the WORST cpus ever made)
AND ON TOP OF THAT I HAVE TO RUN IT THROUGH WINDOWS LINUX SUBSYSTEM BECAUSE I CANT FORMAT THIS DRIVE WILL ALSO TAKE A PERFORMANCE PENALTY AS WELL. and even worse QEMU uses python now in its build process.. Python takes FOREVER to initialize and will take EVEN LONGER ON THIS CPU... the things I do in the name of extreme autism.
"Hey guys, I guess thats /dev/null"
after a very and i mean VERY long test compile I finally got everything ready and we can start.
I first edit the malta board and because there is a text limit here Ill give you the MAIN important function that does this shit(you dont have to understand it. All it does is read from kernel memory WHERE the tty output is in ram and then just prints it to the screen its ok if you don't get how this works completely its mainly because of other functions that go on to long for me to show. I used grok to clean this up so it will be.... acutally readable to anyone besides myself)
C:
static const MemoryRegionOps pnx_periph_ops = {
.read = pnx_periph_read,
.write = pnx_periph_write,
.endianness = DEVICE_LITTLE_ENDIAN,
};
static struct {
QEMUTimer *poll_timer;
uint32_t last_read_ptr;
bool initialized;
} pnx_console = {0};
static void pnx_console_poll(void *opaque)
{
uint32_t write_ptr, read_ptr;
uint32_t buffer_base, buffer_size;
/* Ring buffer addresses (physical, subtract 0x80000000 from kernel addresses) */
uint32_t write_ptr_addr = 0x02d7828; /* 0x802d7828 - 0x80000000 */
uint32_t read_ptr_addr = 0x02d7810; /* 0x802d7810 - 0x80000000 */
uint32_t base_addr_ptr = 0x02a1c04; /* 0x802a1c04 - 0x80000000 */
uint32_t size_addr_ptr = 0x02a1c00; /* 0x802a1c00 - 0x80000000 */
/* Read ring buffer state */
cpu_physical_memory_read(write_ptr_addr, &write_ptr, 4);
cpu_physical_memory_read(read_ptr_addr, &read_ptr, 4);
if (!pnx_console.initialized) {
pnx_console.last_read_ptr = read_ptr;
pnx_console.initialized = true;
printf("\n[PNX8543 Console Active - Reading kernel messages]\n");
fflush(stdout);
goto reschedule;
}
/* Check for new data */
if (write_ptr != pnx_console.last_read_ptr) {
cpu_physical_memory_read(base_addr_ptr, &buffer_base, 4);
cpu_physical_memory_read(size_addr_ptr, &buffer_size, 4);
/* Sanity check */
if (buffer_size > 0 && buffer_size < 0x100000 &&
buffer_base >= 0x80000000 && buffer_base < 0x90000000) {
uint32_t ptr = pnx_console.last_read_ptr;
int count = 0;
while (ptr != write_ptr && count < 4096) {
uint32_t offset = ptr & (buffer_size - 1);
uint32_t phys_addr = (buffer_base - 0x80000000) + offset;
uint8_t ch;
cpu_physical_memory_read(phys_addr, &ch, 1);
/* Print printable characters and newlines */
if (ch >= 32 && ch <= 126) {
putchar(ch);
} else if (ch == '\n') {
putchar('\n');
} else if (ch == '\r') {
/* Skip carriage returns */
} else if (ch == '\t') {
putchar('\t');
}
ptr++;
count++;
}
if (count > 0) {
fflush(stdout);
}
pnx_console.last_read_ptr = ptr;
}
}
reschedule:
/* Re-arm timer for next poll (every 1ms) */
timer_mod(pnx_console.poll_timer,
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 1000000);
}
Alright NOW WE GOT TEXT OUTPUT. Everything past here begins the work I did yesterday and today. Everything before that I just talked about was done on Wensday and earlier. .(This includes installing a proper IDE as I was using notepad to write ALL OF THIS AND HAD WRITTEN ALL THE CODE AND MORE YOU SEE WITH GROK IN FUCKING NOTEPAD)
SO THATS IT RIGHT??? WE DID IT. well ive kinda cropped that screenshot you see above for a reason...
This gets spammed. And spammed and spammed and spammed.
If you do not know a interrupt is how the computer INTERRUPTS what the CPU is currently doing to do something else. Now if your thinking
"Dear guy on the kiwis of farms if the CPU is currently doing instructions how would it be able to interrupt itself and stop what its doing to go do something else. It can only do one instruction at a time"
This is where the PIC comes in. On your motherboard and on every other form of motherboard there is a device called a PIC(Programmable interrupt controller) This allows the operating system to assign interrupts to almost anything and then when that event happens IE a keyboard press it INTERRUPTS the cpu and tells it to do something. The PIC acts as a separate chip from the CPU so that it can interrupt it at any time as the CPU can only do one instruction at a time and unless the CPU is to check the status of EVERY single interrupt check(IE disk operations keyboard keys being pressed) after EVERY instruction it would be extremely slow. So that's why the PIC is independent from the CPU and works on its own to tell it when to stop what its doing and go handle something else.
Now mips and embedded systems don't have a PIC in the traditional sense. What you will learn about embedded systems is that almost NOTHING is unifed. You don't just grab a random linux image and boot from that device, No you have to BUILD the operating system for your device or build the board around the operating system image if your emulating. And this includes interrupt tables.
Now that spam is likely the values of the interrupts(0x07 belonging to the TIMER interrupt 3 belonging to etc) are likely out of order because the MALTA board for qemu is of course different from the one taken from a random TV.
Now here is the good news, the good news is that I was able to by viewing the strings of the kernel figure out that the board for it was a "NXP PNX8543/TV543" and ill tell you right now I orginally had the WRONG idea. I originally thought that I should be searching online for schematics. Really I should have just checked the linux kernel to see if they had support for the device and just viewed the data there and inferred stuff. But ill show you how THAT rabbithole went towards
Schematic Hell
Alright the goal is to find the interrupt table/Schematics for the interrupt table that we can use to reconfigure the malta source code
Alright so lets do a search for TV543 and HEY LOOK WE ALRIGHT FOUND A DATASHEET/SchematicAlright now this. THIS looks promising. Lets just scroll down and.
Thats it..... Thats the whole fucking thing.......
Ok well obviously that did not get us far and I cant find anything so lets search by oh I don't know PNX8543.
Alright so I cant find a EXACT datasheet for the PNX8543 I know its a chip or board.. Or well its either a CPU or board..
BUT I was able to find a HUGE service sheet for a TV(Q552.2L LA) with a PNX8543 by Philips and after going through over 203 PAGES.(And to anyone 10 years in the future where society has collapsed and your looking for this datasheet. Check the attached files) of codewords
Electrical engineering sheets
VGA pinouts
And by the way I do not know WHAT service engineer would need this stuff considering that its not like they can change the circuitry of this shit. Anyone who knows well... ANYTHING about electrical engineering feel free to quote and tell me why a service repairman would want/need to know this.
and "I don't even know what what the fuck this is or can describe it"
I came up with absolutely nothing.... Maybe its because im not exactly a electrical engineer and can BARELY understand the circut shit. Maybe its because they dont give the circuitry of the INTERNALS of the chip just the outside internals that communicate with it. Only things related to interrupts were little raillines that had the label of IRQ but never told us where it was going.
Alright so now we have to throw ALL of this out the window and try a new solution.
Realizing that ALL the time I spent was for nothing.
Now on google PNX8543 shows nothing in terms of files or github repository's however eventually I stumbled upon a file relating to the linux kernel to the PNX833xx
Now admittly I could have used this but I knew in the back of my mind what if i spend the next week desinging this board around the info of a similar enough chip only to find out that things are completely different and the "PNX8543" is almost completely different from "PNX83xxx"(xs just mean generic). Don't want that to happen. So I searched a 2010 linux kernel archive for PNX85XXX and while I did not find anything I did find PNX8550 which although not PNX8543 may be just a generic name. PNX8550 may not be a specific chip but rather support for a FAMILY of chips under PNX85XX which is what im hoping for. And guess what this PNX85XX folder has
A ENTIRE TABLE OF THE HARDWARE INTERRUPTS AND WHICH EACH ONE BELONGS TO.
So we can now edit QEMUS Malta board to align with what THIS board expects..
after some basic GIC work and a entire day of testing and going back and forth I eventually just came to a conclusion.
Setup basic initialization stubs for the GIC(general interrupt controller which is where ONE interrupt IE 0x02, acts as a function to where it will read a memory address and take the value of that and then return/do/act based on that. Allowing you to have MUCH more interrupts than what a standard chip/board provides 70 in fact in this case. You don't have to understand this explination because what im giving is very basic and if you want more feed what I put into chatgpt or something).
And then we just disable ALL interrupts except 0x07 or the timer interrupt.
And what do you know after that and days of testing, waiting 9 seconds to compile ONE SINGLE CHANGED FILE at a time, and over well ive kinda lost track I want to say 2 weeks on this piece of shit laptop.
We did it.
Well not really.
Remember when I said "Some things between the malta board and this random board are mismatched and expect different stuff" Well that applies to IO.. So no matter what I attach it will not properly mount or even acknologe that a disk exists. But hey I mean this is further than I thought id EVER get. But BELIEVE me I spent alot of time
trying before and after I came to that conclusion.
ALOT OF STUFF
So yeah not TECHNICALLY working but that is where im at.
Some other things I figured out today
Yeah so I learned how to use binwalk PROPERLY(apparently if there is a file like .BMP binwalk will like a dumbass refuse to extract it. you have to add --dd="bitmap:bmp" in order to extract it)
So was cool i guess, using that I rescanned the Phillips(Main TV application) Binary and found the SONY little bootup logo. If you ever wanted it here it is.
I cant upload the MAIN bmp as both for some reason imgur and kiwifarms refuse to display it but ill add a catbox link in a sec
Anyways I need to clarify for this that I have 2 MAIN sources I use for emulating this thing.
I have a NAND dump I found online
and a UPDATE file.
Now because of bad jffs2 tools I was not able to find this file in the NAND but I was in the update. I want to present to you THIS IMAGE.
It was found in the update files and at first looks like just a random Forest right. Well look at the name BRAVIA.jpg. Could just be a placeholder but NOWHERE and i do mean NOWHERE I checked does this little image appear in the menus or anything.
Maybe its just a DEMO asset, used to show the picture quality when set to some demo mode and put at a store.
That could be but look at the upgrade file and the importance of the image(ALL the other images are stored in images.img by the way which makes this even more strange)
Writing Bravia Image? I mean all the other files like PANEL settings and all that apperently is not important enough to be printed but this RANDOM jpeg is?
I then realized that this JPEG is actually a hidden secret file. It most likely
- Hides a encryption/singing key or is ITSELF a signing/encryption key
- Used to detect if the NAND is corrupted by checking on bootup or something?
- Used as a calibration image by the auto calibrate software(although unlikely considering there is only ONE image here)
Now yes I did find the source of this image and yes I did manage to do this all in a day as well as decode and fix the interrupt table, decode BMP files, spend hours tweaking and fixing shit with mtdblocks before I realized that the malta board is just incompatible without tweaks and then trying a bit more regardless before trying to manually fix it by fixing the source again, and also now figuring out secret images and tracing the exact location of them.
To be honest it was not even that hard.
Inside the JPEG are strings for adobe photoshop and "Gettyimages" and the EXACT place. So just searching Oirase river japan. Which is what the metadata says followed by "gettyimages" gave me this.
Now admittedly the colors are off but like common, its a exact 1:1 of the image taken at the EXACT same position with the exact same little details. They could have just changed the colors.
Attachments
-
0850dd25d9242559fd842a6a07637d0e3f01d6e233adfef8c87ed99649547db1.pdf10.1 MB · Views: 19
-
1766188155606.png13 KB · Views: 15 -
1766185039294.png57.6 KB · Views: 9 -
image.png76.7 KB · Views: 13 -
1766066714177.png8.3 KB · Views: 13 -
1766193127306.png15 KB · Views: 6 -
1766193155106.png15 KB · Views: 444
Last edited: