Note: This article will be part of PlayStation Camera article series in near future:
See also for historical purposes. All was done at that time in user land, and with usb traffic sniffer:
Do you remember E3 presentations with Dr Richard Marks and Phill Harrison in 2003 and 2005 with the infamous ruber duck and EyeToy? It was amazing. It was the first time you saw AR stuff in a game console.
I made my first usb driver for PlayStation 2 platform. It was a full IOP module replacement for original Sony EyeToy driver, streaming ipu frames and full audio support reversing the original ov519.irx module in 2004. It was done using ps2dis, a pencil and notebook(no Ida then a piece of paper with a assembler list and my brain XD old school you know). I took a sabbatical year from my work for personal matters and I learnt a lot about usb specticification, and a deep knowledge about chips inside Sony PlayStation 2(ee,iop,dmac,ipu,gs,vu). It was a very fun year indeed.
It was my first contact with Omnivsion, usb bridge asics and cmos sensors, and since then i have made reverse engineering of all Omnivision chips that Sony have been using. Sony have been making incredible and very cheap camera devices since 2003 (EyeToy, PlayStation Eye and PlayStation Camera) and thanks to that i had a lot of fun reversing them. That feeling when you get the first frame from a camera device with no internal information about their chips is incredible. Without challenge there is not fun at all :P.
There are 2 Playstation Camera models:
I began my research in december 2013 just after bought it. It was using a propietary connector called AUX, Erik Wilson figured out that AUX was only an usb3 connector made by Sony so we tryed to get, with man in the middle approach, with a beagle usb 3 sniffer the traffic between the PlayStation 4 and PlayStation Camera.
After that,we analyzed all usb 3 traffic and we figured out that device was in boot mode waiting for firmware. We extracted the firmware from the usb traffic and after that i got all initialization done under osx on March 2014.
First streaming video test with ps4eye camera isoc part done! ! . I must improve yuyv to rgb ugly code
— psxdev (@psxdev) March 1, 2014
I released later a PS4EYECam driver using libusb for MacOS. Some people and researcher have been working with it porting to linux but windows has not a good support for libusb and it is difficult to get it up and running in an easy way, that zadig thing is a pain in the ass. There is other option for windows using Windows Media Framework after loading the firmware to device but firmware used is from our usb sniffer capture from kernel lower than 1.76 and it is veeery old.
I know that some researchers have been testing and looking for PlayStation Camera integration with PlayStation VR on pc and someone ask me if i could come back and work again in a proper driver for PlayStation Camera for Windows. I will try to get it up and running but i can share all my research from these years about it at low level in kernel land just now.
So let's go!!!! Luke...
PlayStation 4 Operating System is based on Freebsd 9 and it is called Orbis. Like all operating systems it has drivers for many devices.
PlayStation Camera is an usb 3 camera device with a propietary connector called AUX. It is managed by a kernel driver called Luke. It is like all kernel drivers for devices that you can see in a vanilla Freebsd Kernel. User land applications or games are using a library called libSceCamera.sprx and that library speaks with Luke using ioctl calls.
Recommended lecture for newbies "FreeBSD Device Drivers: A Guide for the Intrepid" by Joseph Kong.So do you want to have a lot of fun reversing code from PlayStation 4 Kernel? Always :P.
The first surprise, first versions of PlayStation Kernels let to use PlayStation Camera from AUX port and USB ports. Sony fixed that on firmware 1.75, i have not Kernel between 1.62 and 1.75 so only i can confirm that 1.62 still can use PlayStation Camera from front usb ports in the PlayStation 4. Initial Kernels only support first camera model.
Second surprise there are two firmwares embed on Kernel for PlayStation Camera, one of them it is the same in all Kernels it is for a special UAC mode, the other one the UVC mode has different revisions but we will speak about that later don't worry take it easy.
Code from Kernel 5.05:
int luke_probe(device_t dev)
{
struct usb_attach_arg *uaa = device_get_ivars(dev);
int result=ENXIO;//6
usb_device_descriptor *device;
if(uaa!=NULL)
{
if(uaa->usb_mode!=0)
{
device=usbd_get_device_descriptor(uaa->device);
if(device->idVendor==0x05a9)
{
if(device->idProduct-0x580>0xb)
{
return result;
}
if(device->idProduct!=0x58a && device->idProduct!=0x58b && device->idProduct!=0x580)
{
return result;
}
//uacmoode is 0 you can set to 1 with ioctl 0xC0088E09 called from libSceCamera.sprx
if(uacmode==1 && device->idProduct&0xFFFE==0x58A )
{
printf("camera driver return ENXIO in probe for UAC\n");
return ENXIO;
}
result=0;
uint8_t index=usbd_get_bus_index(uaa->device);
if(index!=2)
{
printf("PlayStation(R)Camera is supporting only AUX Port. index:%x\n",index);
return ENXIO;
}
}
}
}
return result;
}
This function has a place where the size of 2 kind of PlayStation Camera firmwares is hardcoded , you can easily find the place in each Kernel looking for "camera attach: UAC mode!\n"
For 5.05:
loc_67D801:
or byte ptr cs:dword_27A80C0, 1
cmp uacmode, 0
mov cs:dword_27A8034, 140000h
jz short loc_67D830
lea rdi, aCameraAttachUa ; "camera attach: UAC mode!\n"
xor eax, eax
call printf
mov eax, 64036
jmp short loc_67D835
loc_67D830:
mov eax, 67924
loc_67D835:
mov firmwareSize, eax
So uacmode firmware size in 5.05 is 64036 bytes. We will see later that that mode have the same size and same content for all firmwares.
The other one have size of 67924 bytes in 5.05. This one change for each new PlayStation Camera firmware revision.
This function will check if device is in boot mode to prepare transfer that in usb callback will call finally to luke_fw_cb funtion that will load the firmware.
This function have the information about where is each firmware. UAC firmware is the same for all kernels, UVC firmware has different revisions.
3.50 is the first firmware we have that it supports second PlayStation Camera model. You can confirm that in luke_probe function easily.
Table with retail firmware versions, offset in kernel, size in bytes of PlayStation Camera firmware, name if it is present on kernel, md5, and type of fimware UAC or UVC.
firmware | offset | size | kernel name | md5 | type |
---|---|---|---|---|---|
0.915_010 | 7329A0 | 62952 | 4322f2c5541dfa67edec7dd3d33c2d60 | UVC | |
0.915_010 | 741F90 | 64036 | luke_rom_image | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
0.915_020 | 7329A0 | 62952 | 4322f2c5541dfa67edec7dd3d33c2d60 | UVC | |
0.915_020 | 741F90 | 64036 | luke_rom_image | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
0.915_040 | 7369A0 | 62952 | 4322f2c5541dfa67edec7dd3d33c2d60 | UVC | |
0.915_040 | 745F90 | 64036 | luke_rom_image | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
0.920_030 | 7680D0 | 65384 | 155eb994ad3b95e2af99aac18b6a6fea | UVC | |
0.920_030 | 778040 | 64036 | luke_rom_image | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
1.00_devkit | 84C4C0 | 66576 | luke_fw | 3a6ff06e3ff57615c4019b0a5c2e47ca | UVC |
1.00_devkit | 84C8E0 | 64036 | luke_rom_image | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
1.01 | 84C4C0 | 66576 | 3a6ff06e3ff57615c4019b0a5c2e47ca | UVC | |
1.01 | 85C8E0 | 64036 | luke_rom_image | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
1.05 | 7204C0 | 66576 | 3a6ff06e3ff57615c4019b0a5c2e47ca | UVC | |
1.05 | 7308E0 | 64036 | luke_rom_image | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
1.50b | 738530 | 66608 | e70ad69b3faab612e8115960f568a924 | UVC | |
1.50b | 748970 | 64036 | luke_rom_image | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
1.51 | 738530 | 66608 | e70ad69b3faab612e8115960f568a924 | UVC | |
1.51 | 748970 | 64036 | luke_rom_image | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
1.52 | 738530 | 66608 | e70ad69b3faab612e8115960f568a924 | UVC | |
1.52 | 748970 | 64036 | luke_rom_image | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
1.60 | 73C530 | 66608 | e70ad69b3faab612e8115960f568a924 | UVC | |
1.60 | 74C970 | 64036 | luke_rom_image | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
1.61 | 73C530 | 66608 | e70ad69b3faab612e8115960f568a924 | UVC | |
1.61 | 74C970 | 64036 | luke_rom_image | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
1.62 | 73C530 | 66608 | e70ad69b3faab612e8115960f568a924 | UVC | |
1.62 | 74C970 | 64036 | luke_rom_image | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
1.75 | 961990 | 66608 | e70ad69b3faab612e8115960f568a924 | UVC | |
1.75 | 971DD0 | 64036 | luke_rom_image | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
1.76 | 8489F0 | 66608 | e70ad69b3faab612e8115960f568a924 | UVC | |
1.76 | 858E30 | 64036 | luke_rom_image | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
3.15 | 913F00 | 66608 | e70ad69b3faab612e8115960f568a924 | UVC | |
3.15 | 9244D0 | 64036 | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC | |
3.50 | 8FEB30 | 67924 | 9e7ddcb8b891d7227ac0bdc998ddbfe7 | UVC | |
3.50 | 90F640 | 64036 | ov580_full_UAC_20120918_21307.bin | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
3.55 | 8FF3D0 | 67924 | 9e7ddcb8b891d7227ac0bdc998ddbfe7 | UVC | |
3.55 | 90FEE0 | 64036 | ov580_full_UAC_20120918_21307.bin | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
4.00 | 936B20 | 64036 | ov580_full_UAC_20120918_21307.bin | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
4.00 | 948380 | 67924 | 9e7ddcb8b891d7227ac0bdc998ddbfe7 | UVC | |
4.01 | 936A80 | 64036 | ov580_full_UAC_20120918_21307.bin | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
4.01 | 9482E0 | 67924 | 9e7ddcb8b891d7227ac0bdc998ddbfe7 | UVC | |
4.05 | 936D20 | 64036 | ov580_full_UAC_20120918_21307.bin | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
4.05 | 948580 | 67924 | 9e7ddcb8b891d7227ac0bdc998ddbfe7 | UVC | |
4.06 | 936E70 | 64036 | ov580_full_UAC_20120918_21307.bin | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
4.06 | 9486D0 | 67924 | 9e7ddcb8b891d7227ac0bdc998ddbfe7 | UVC | |
4.07 | 936FB0 | 64036 | ov580_full_UAC_20120918_21307.bin | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
4.07 | 948810 | 67924 | 9e7ddcb8b891d7227ac0bdc998ddbfe7 | UVC | |
4.55 | A3E4E0 | 67924 | 9e7ddcb8b891d7227ac0bdc998ddbfe7 | UVC | |
4.55 | A4FFD0 | 64036 | ov580_full_UAC_20120918_21307.bin | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
5.00 | A71350 | 64036 | ov580_full_UAC_20120918_21307.bin | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
5.00 | A82D00 | 67924 | 9e7ddcb8b891d7227ac0bdc998ddbfe7 | UVC | |
5.05 | A71750 | 64036 | ov580_full_UAC_20120918_21307.bin | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
5.05 | A83100 | 67924 | 9e7ddcb8b891d7227ac0bdc998ddbfe7 | UVC | |
5.05_devkit | C53980 | 64036 | ov580_full_UAC_20120918_21307.bin | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
5.05_devkit | C65330 | 67924 | 9e7ddcb8b891d7227ac0bdc998ddbfe7 | UVC | |
6.00 | B0A82F | 68032 | 24afe3c941dc599aafd23ac5170a4d14 | UVC | |
6.00 | B1D8BE | 64036 | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC | |
6.50 | B0CFC0 | 68032 | 24afe3c941dc599aafd23ac5170a4d14 | UVC | |
6.50 | B1F6E1 | 64036 | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC | |
7.00 | B1BA24 | 68032 | 24afe3c941dc599aafd23ac5170a4d14 | UVC | |
7.00 | B0C000 | 64036 | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC | |
7.02 | B1BA24 | 68032 | 24afe3c941dc599aafd23ac5170a4d14 | UVC | |
7.02 | B0C000 | 64036 | 99ca1e97ea2bb9edaf4c6f511292b4e2 | UAC |
I will use 5.05 UVC for a proper driver check luke_firmwares repository to find all firmwares if you have not access to a PlayStation Kernel yourself to extract using the offset and size published here.
This function receive ioctl commands and buffer with parameters
This table is for kernel and libSceCamera.sprx from 5.05
cmd | libSceCamera.sprx caller |
libSceCamera.sprx call from user or internal |
---|---|---|
0xC0188E16 | sub_10A0 | sceCameraSetConfig,sceCameraSetConfigInternal |
0xC0188E18 | sub_1670 | sceCameraGetConnfig |
0xC0188E1A | sub_1960 | sceCameraStop,sceCameraStopByHandle |
0xC0208E19 | sub_1740 | sceCameraStart,sceCameraStartByHandle |
0xC0148E1E | sub_3E80 | sceCameraIsAttached |
0xC0108E26 | sub_1A90 | sceCameraSetVideoSync,sceCameraSetVideoSyncInternal |
0xC0288E14 | sub_AF0 | sceCameraOpen,sceCameraOpenByModuleId |
0xC0388E1B | sub_39A0 | sceCameraSet* |
0xC0388E1C | sub_3390 | sceCameraGetAttribute |
0xC0388E1C | sub_3300 | sceCameraGetAutoExposureGain,sceCameraGetAutoWhiteBalance |
0xC0468E02 | sub_5000 | sceCameraGetRegister |
0xC0468E03 | sub_5210 | sceCameraSetRegister |
0xC0388E1D | sub_1B80 | sceCameraGetFrameData |
0xC0048E23 | sub_3250 | sceCameraIsValidFrame |
0x40408E22 | sub_AF0 | |
0x40308E24 | sub_5930 | hftC5A1C8OQ_F_A |
0xC0088E08 | sub_4180 | sceCameraGetDeviceInfo |
0xC0088E09 | nnR7KAIDPv8_F_A_0 | nnR7KAIDPv8_F_A |
0xC0088E0A | sub_5D10 | |
0xC0088E17 | ||
0xC0088E20 | sub_49C0 | sceCameraSetCalibData |
0xC0088E21 | sub_4080 | sceCameraSetForceActivate |
0xC0088E28 | sub_5FB0 | sceCameraSetVrTrackerMode |
0xC0048E27 | sub_5EC0 | sceCameraSetDebugStop |
0xC0108E15 | sub_EF0 | sceCameraClose,sceCameraCloseByHandle |