View attachment 8327739
View attachment 8327741
View attachment 8327750
Im getting closer. Before I just had a kernel panic and now I got the XIO driver to semi load (XIO is a propitary kernel module)
(Here was my previous attempts and how they would go every time)
View attachment 8328128
Ill have a proper sperg post soon.
K so lets go over the problem.
We got it to GET past starting up and getting the VMLINUX working.
Now lets go over the problem xio.
What is xio?
xio is a nand controller that handles flash memory in the linux kernel. Its NOT included in the linux kernel source code and it can NOT be found anywhere on the surface web. There is NO copyright information and so far it is lost to time, So I guess this vmlinux is carrying what is a basically "le heccing lost media". This module is so obsecure that I can not even say 100% who even written it or
- Is this module a open source module or was written by a company
- If it was written by a company if so WHO
- What is its version number
- When it was made
- If xio is even the full name
- Heck I don't even know the copyright information
Now because XIO is the thing that mounts the rootfs we cant just easily add -pflash to qemu and attach a device to mount. And because we cant change the command line options this presents a annoying probem.
See the command line for this VMLINUX is
"console=ttyS0,38400n8 mem=48M tm0size=20M kgdb=ttyS1 root=/dev/mtdblock5 init=/init rw ip=off jffs2_gc_delay=20"
See that root. We cant change it but its wanting a device mtdblock5 to be the rootfs or main partition. Now mtdblock5 does not mean there are 5 different devices but rather it means there is one or more device with multiple PARTITIONS THAT equal 5
And even worse this VMLINUX has NO SYMBOLS, NO sections either, just a PURE RAW binary where every debugging thing was taken away.
Things of note
Now if you do not know ive been using a DUMPED nand of the sony tv I found online to view the squashfs. However last big blogpost ive said ive also been using a update file as a side to get information.
Well that update file has a EXPANDED rootfs that has some interesting things of note that I promise is relevant. Lets look at the HOME folder in the extracted squashfs that I got from the update file.
0 files? oh well at least we have some intresting folder names.
Lets try looking up "easi-oe" on google
Huhh.... yeah something tells me we are not going to find anything with that.
.....
Ok well lets try the other folder "nxp_dtv"
OOOH THATS GOOD LETS SEARC-
Ill cut to the chase.. This lead nowhere. But NXP is the maker of the PNX chip that runs this TV. So keep that of note.
Alright lets now try "nxp_linux_solution_rev1"
ughhhhh...
I eventually went back and asked myself "Why am I searching up random keywords".. Because I need to find the source of xio. I cant find it by trying "xio" or searching for the strings that the thing produces on google. So Im doing this..
Well most likely this module came from NXP so maybe I could send a email ASKING if they made this module... Now of course they might not have records of SUCH a old 2010 linux kernel module but there's a chance. So I sent a email.
...
So lets go over this
I have to debug and emulate something that I have no date, no owner, no source, and no knowledge on what it even does, and no not even where it belongs. And I have to do ALL of this with no knowledge of internal schematics
Alright Bet...
Making our own Nand solution.
Now remember the kernel command line option <5>Kernel command line: console=ttyS0,38400n8 mem=48M tm0size=20M kgdb=ttyS1 root=/dev/mtdblock5 init=/init rw ip=off jffs2_gc_delay=20
This means were going to have to make a flash file where the partition5 is the rootfs.
Im not going to show you the long process of doing that but its basically filling all the other partitions with dummy information so that partition 5 will be considered our rootfs.
Now because IO information is different compared to other boards we need to make our own IO system.
Yeah this is the part where I give surface level explanations to what im doing.
Basically it asks for information we give it a output. The input and what its asking is determined by it reading a address
Anyways REMEMBER THIS PART RIGHT HERE
You see this
Eventually XIO is going to ask the nand by calling the address 0x828 asking "Ayo clanka whats your NAND ID"
and checks a table in it checking if it matches its supported devices
You see this? those are MANUFACTURER ids. See those numbers UNDER the manufacturers names. THOSE are the numbers that represent the string name up there.
The next is the DEVICE ID, which I similarly pulled.
Oh yeah one more thing we need to select a profile.
When XIO calls our NAND with this number "0x814" its asking it for its profile. A profile is information like "is it 8 bit or 16 bit" And yadda yadda. and is determined like this
0x00000013(Example one)
If I wanted to say the NAND was above 68 megabytes I would put the number 6 + the 1 for enable at the END of the hex value
Because there needs to be a ONE at the beginning to enable it would be
0x00000007 and because I need to put a 1 at the SECOND last to tell the thing that it is NAND it would be 0x00000017
THIS IS REQUIRED AND GETS PASSED OFF. Lets read what the XIO module is doing NORMALLY so I can give you guys a better picture
As with everything I have printf statements everywhere
You get the point.
Code:
[PCIXIO_READ] addr=0x814 size=4
[PCIXIO] *** SEL0PROF READ *** addr=0x814 size=4 returning=0x00000013
[PCIXIO] Bits: Enable=1 Type=2 Size=1 Bit23=0 Bit27=0
[PCI→PCIXIO] Forwarding read from PCI offset 0x40814 to PCIXIO offset 0x814 = 0x13
[PCIXIO_READ] addr=0x814 size=4
[PCIXIO] *** SEL0PROF READ *** addr=0x814 size=4 returning=0x00000013
[PCIXIO] Bits: Enable=1 Type=2 Size=1 Bit23=0 Bit27=0
[PCI→PCIXIO] Forwarding read from PCI offset 0x40814 to PCIXIO offset 0x814 = 0x13
[PNX PCI] Returning BASE18 = 0x10000000 (NAND base)
[PCIXIO_READ] addr=0x818 size=4
[PCI→PCIXIO] Forwarding read from PCI offset 0x40818 to PCIXIO offset 0x818 = 0x0
[PCIXIO_READ] addr=0x81c size=4
[PCI→PCIXIO] Forwarding read from PCI offset 0x4081c to PCIXIO offset 0x81c = 0x0
[PCIXIO_READ] addr=0x834 size=4
[PCI→PCIXIO] Forwarding read from PCI offset 0x40834 to PCIXIO offset 0x834 = 0x0
[PCIXIO_READ] addr=0x838 size=4
[PCI→PCIXIO] Forwarding read from PCI offset 0x40838 to PCIXIO offset 0x838 = 0x0
[PNX PCI CFG READ: addr=0x40084 (reg=65569) = 0x00000000]
[PNX PCI] Returning SETUP = 0x01c20003
[PNX PCI CFG WRITE: addr=0x40084 (reg=65569) val=0x1]
[PCI→PCIXIO] Forwarding write from PCI offset 0x40fd4 to PCIXIO offset 0xfd4 val=0x1000
[PCIXIO_WRITE_ALL] addr=0xfd4 val=0x1000
[PCIXIO WRITE: addr=0xfd4 val=0x1000]
[NAND] DMA interrupt enable = 0x1000
[PCI→PCIXIO] Forwarding write from PCI offset 0x40830 to PCIXIO offset 0x830 val=0x150090
[PCIXIO_WRITE_ALL] addr=0x830 val=0x150090
[PCIXIO WRITE: addr=0x830 val=0x150090]
[NAND] Flash control = 0x150090, Command = 0x90
[NAND] Auto-setting DONE bit after command
[PCI→PCIXIO] Forwarding write from PCI offset 0x40820 to PCIXIO offset 0x820 val=0x10000000
[PCIXIO_WRITE_ALL] addr=0x820 val=0x10000000
[PCIXIO WRITE: addr=0x820 val=0x10000000]
[NAND] Address = 0x10000000 (cycle 0)
[PCI→PCIXIO] Forwarding write from PCI offset 0x4082c to PCIXIO offset 0x82c val=0x50
[PCIXIO_WRITE_ALL] addr=0x82c val=0x50
[PCIXIO WRITE: addr=0x82c val=0x50]
[NAND] Operation initiated
[PCIXIO_READ] addr=0x82c size=4
[PCI→PCIXIO] Forwarding read from PCI offset 0x4082c to PCIXIO offset 0x82c = 0x100
[PCIXIO_READ] addr=0x828 size=4
[NAND] READ ID cycle 0: returning 0xec
[NAND] READ ID cycle 0: returning val=0x000000ec (size=4)
[PCI→PCIXIO] Forwarding read from PCI offset 0x40828 to PCIXIO offset 0x828 = 0xec
[PCI→PCIXIO] Forwarding write from PCI offset 0x40820 to PCIXIO offset 0x820 val=0x10000000
[PCIXIO_WRITE_ALL] addr=0x820 val=0x10000000
[PCIXIO WRITE: addr=0x820 val=0x10000000]
[NAND] Address = 0x10000000 (cycle 1)
[PCI→PCIXIO] Forwarding write from PCI offset 0x4082c to PCIXIO offset 0x82c val=0x50
[PCIXIO_WRITE_ALL] addr=0x82c val=0x50
[PCIXIO WRITE: addr=0x82c val=0x50]
[NAND] Operation initiated
[PCIXIO_READ] addr=0x82c size=4
[PCI→PCIXIO] Forwarding read from PCI offset 0x4082c to PCIXIO offset 0x82c = 0x100
[PCIXIO_READ] addr=0x828 size=4
[NAND] READ ID cycle 1: returning 0x33
[NAND] READ ID cycle 1: returning val=0x00000033 (size=4)
[PCI→PCIXIO] Forwarding read from PCI offset 0x40828 to PCIXIO offset 0x828 = 0x33
<4>No NAND device found!!!
Lets shorten the EXTREME overprinting that I did.
Code:
[PCIXIO] *** SEL0PROF READ *** addr=0x814 size=4 returning=0x00000013
[PCIXIO] *** SEL0PROF READ *** addr=0x814 size=4 returning=0x00000013
[PNX PCI CFG READ: addr=0x40084 (reg=65569) = 0x00000000]
[PNX PCI] Returning SETUP = 0x01c20003
[PNX PCI CFG WRITE: addr=0x40084 (reg=65569) val=0x1]
[PCI→PCIXIO] Forwarding write from PCI offset 0x40fd4 to PCIXIO offset 0xfd4 val=0x1000
[PCIXIO_WRITE_ALL] addr=0xfd4 val=0x1000
[PCIXIO WRITE: addr=0xfd4 val=0x1000]
[NAND] DMA interrupt enable = 0x1000
[NAND] Operation initiated
[PCI→PCIXIO] Forwarding read from PCI offset 0x4082c to PCIXIO offset 0x82c = 0x100
[NAND] READ ID cycle 0: returning 0xec
[NAND] READ ID cycle 0: returning val=0x000000ec (size=4)
[NAND] READ ID cycle 1: returning 0x33
[NAND] READ ID cycle 1: returning val=0x00000033 (size=4)
[PCI→PCIXIO] Forwarding read from PCI offset 0x40828 to PCIXIO offset 0x828 = 0x33
<4>No NAND device found!!!
Now it first GETS our NAND profile that we give it. It then reads the manufactor ID and then the DEVICE id and then.... says theres no nand devices without reading a SINGLE byte of nand???
FUCK... alright lets get out the reverse engineer software... I suck at it but maybe it can be used to help us.
I narrowed down the EXACT function that is causing us issues
The thing is with reverse engineering is that it can give you the internals of how something works but it will never give you the CONTEXT.
Variable names, function names(This depends sometimes it CAN be extracted automatically DEPENDING on how its compiled), heck sometimes even if statements or how addressees are written. ALL OF THAT gets lost, the CONTEXT gets lost and YOU have to fill it in using inferring skills. Its like a puzzle. A HUGE puzzle.
If im going to want to get the CONTEXT im going to need to use GDB to go through each instruction with QEMU and see what it does. That will give us a bigger picture. So I ran qemu and attached GDB and set a breakpoint to the function that scans the nand.
And i opened BOTH IDA and ghirda 2 disassemblers and wrote down EACH if statement that gets ran. Let me tell you it was a LONG DAY
Yes I set a breakpoint and then went one step AT A FUCKING TIME GOING UP AND UP and then matching the address I was at with fucking ghirda AND IDA and then wrote it down and then continued
Now if you don't know GDB can PAUSE a program(QEMU) and then allow us to run each operation ONE at a time, otherwise known as a STEP, meaning that the program is PAUSED. Now to the program time still runs the same meaning that it does not account for the time it took being FROZEN. However something weird happened while i was writing down in notepad and going one step at a time. The output to the console was different???
Well maybe there might be some issue with QEMU. Maybe doing 1 instruction at a time causes it to account time differently or in some weird way that messes things up. I have a pretty good theory but I lack the words to put my visual language into words on here.
Eventually I figured out that I was giving the information wrong after a LONG night with gdb... I FINALLY fixed the fucking thing by doing this
AND FINALLY with that it now spams a BUNCH of stuff
Code:
[PCI→PCIXIO] Forwarding read from PCI offset 0x40fd0 to PCIXIO offset 0xfd0 = 0x100
[PCIXIO_READ] addr=0xfd0 size=4
[PCI→PCIXIO] Forwarding read from PCI offset 0x40fd0 to PCIXIO offset 0xfd0 = 0x100
[PCIXIO_READ] addr=0xfd0 size=4
[PCI→PCIXIO] Forwarding read from PCI offset 0x40fd0 to PCIXIO offset 0xfd0 = 0x100
[PCIXIO_READ] addr=0xfd0 size=4
[PCI→PCIXIO] Forwarding read from PCI offset 0x40fd0 to PCIXIO offset 0xfd0 = 0x100
[PCIXIO_READ] addr=0xfd0 size=4
[PCI→PCIXIO] Forwarding read from PCI offset 0x40fd0 to PCIXIO offset 0xfd0 = 0x100
[PCIXIO_READ] addr=0xfd0 size=4
[PCI→PCIXIO] Forwarding read from PCI offset 0x40fd0 to PCIXIO offset 0xfd0 = 0x100
[PCIXIO_READ] addr=0xfd0 size=4
[PCI→PCIXIO] Forwarding read from PCI offset 0x40fd0 to PCIXIO offset 0xfd0 = 0x100
[PCIXIO_READ] addr=0xfd0 size=4
[PCI→PCIXIO] Forwarding read from PCI offset 0x40fd0 to PCIXIO offset 0xfd0 = 0x100
[PCIXIO_READ] addr=0xfd0 size=4
[PCI→PCIXIO] Forwarding read from PCI offset 0x40fd0 to PCIXIO offset 0xfd0 = 0x100
[PCIXIO_READ] addr=0xfd0 size=4
[PCI→PCIXIO] Forwarding read from PCI offset 0x40fd0 to PCIXIO offset 0xfd0 = 0x100
[PCIXIO_READ] addr=0xfd0 size=4
[PCI→PCIXIO] Forwarding read from PCI offset 0x40fd0 to PCIXIO offset 0xfd0 = 0x100
[PCIXIO_READ] addr=0xfd0 size=4
[PCI→PCIXIO] Forwarding read from PCI offset 0x40fd0 to PCIXIO offset 0xfd0 = 0x100
[PCIXIO_READ] addr=0xfd0 size=4
[PCI→PCIXIO] Forwarding read from PCI offset 0x40fd0 to PCIXIO offset 0xfd0 = 0x100
[PCIXIO_READ] addr=0xfd0 size=4
It spams this SO much that If I were to add > test.txt and it run for less than 10 seconds its over 12 MEGABYTES.. So my terminal would be filled to where I could not scroll up. BUT LOOK!!!!!
<6>NAND device: Manufacturer ID: 0xec, Chip ID: 0x73 (Samsung NAND 16MiB 3,3V 8-bit)
YEESSSSSS.
I later learned that 0xfd0 being spammed is normal. Its just the chip saying "I finished something" So we don't need to print it EVERY second.
Now lets fix that spam and make it get further
Code:
case 0x828: /* GPXIO_RD - NAND read data */
if (s->nand_cmd == 0x90) { /* READ ID command */
// Return all 4 bytes at once (little-endian)
val = 0x001573EC; // Mfr=EC, Dev=73, Byte2=15, Byte3=00
printf("[NAND] READ ID (all 4 bytes): returning 0x%08x\n", val);
} else {
printf("CALLED 828 WITHOUT THE READ ID FLAG\n");
val = 0xFFFFFFFF; /* Empty NAND */
}
break;
Code:
case 0xfd0: /* DMA_INT_STATUS - READ */
val = s->dma_status;
break;
case 0x800: /* DMA_EXT_ADDR - WRITE */
s->dma_ext_addr = val;
break;
case 0x804: /* DMA_INT_ADDR - WRITE */
s->dma_int_addr = val;
break;
case 0x808: /* DMA_TRANS_SIZE - WRITE */
s->dma_trans_size = val;
break;
And with some other fixes as well we can see
ITS READING OUR THING
AND ITS READING OUR PARTITION TABLE.
Ok so like I kinda filled the first 4 partitons with JUNK because I was lazy as shit(I filled it with 0s and then the 5th partition I put my squashfs)
So eventually yeah.