예전에 만든 사인은 VGA 리눅스 커널 패치를 공양한다
소개
그 옛날, NAS 조립 키트의 현장 HG 가 있어, 유지의 데비안화 킷으로 보통의 리눅스로서 동작했습니다. 현상 HG는 디스플레이 출력 단자가 없기 때문에 리모트 접속 밖에 할 수 없었습니다만 같은 시기에 USB를 VGA 출력으로 변환한다 사인은 VGA .
무엇이 문제였는지
사인은 VGA가 나왔을 때는 이미 sisusb로서 Linux 드라이버가 있었습니다만, 이하의 문제에 의해 동작하지 않았습니다.
사인은 VGA가 나왔을 때는 이미 sisusb로서 Linux 드라이버가 있었습니다만, 이하의 문제에 의해 동작하지 않았습니다.
첫 번째는 제품의 색상 변형에서 장치 ID가 다르며 드라이버에 정의되지 않은 것은 인식되지 않습니다.
두 번째는 현장 HG의 CPU는 ppp로 big endian이므로 데이터의 저장 순서가 다르고 정상적으로 디스플레이 표시할 수 없습니다.
2번째는 어떻게 발견했는지 잊어버렸습니다만 그래픽 드라이버이므로
printk
라고 커널 로그만으로 조사한 기억이 있습니다.패치 본체
패치 대상 커널은 Debian/etch의 2.6.18-rc4입니다.
이것으로 콘솔과 X Window System은 표시되었습니다만 일부의 컬러 모드로 표시가 이상했기 때문에 불완전하거나 X의 드라이버에도 문제가 있었을지도 모릅니다.
diff -ru a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c
--- a/drivers/usb/misc/sisusbvga/sisusb.c 2006-07-30 15:15:36.000000000 +0900
+++ b/drivers/usb/misc/sisusbvga/sisusb.c 2006-07-31 00:08:10.000000000 +0900
@@ -76,6 +76,16 @@
DEFINE_MUTEX(disconnect_mutex);
+#ifdef __BIG_ENDIAN
+static void
+correct_endianness_buffer(u16* data, const int length)
+{
+ int i;
+ for (i = 0; i < length; i++)
+ *(data+i) = cpu_to_le16(*(data+i));
+}
+#endif
+
static void
sisusb_free_buffers(struct sisusb_usb_data *sisusb)
{
@@ -411,6 +421,10 @@
memcpy(buffer, kernbuffer, passsize);
kernbuffer += passsize;
+#ifdef __BIG_ENDIAN
+ if ((len & 3) == 0)
+ correct_endianness_buffer((u16 *)buffer, thispass/2);
+#endif
}
retry = 5;
@@ -906,9 +920,13 @@
if (userbuffer) {
if (get_user(swap32, (u32 __user *)userbuffer))
return -EFAULT;
- } else
+ } else {
swap32 = *((u32 *)kernbuffer);
+#ifdef __BIG_ENDIAN
+ swap32 = ((swap32 << 16) & 0xffff0000) | ((swap32 >> 16) & 0xffff);
+#endif
+ }
ret = sisusb_write_memio_long(sisusb,
SISUSB_TYPE_MEM,
addr,
@@ -1259,7 +1277,11 @@
userbuffer += 4;
} else {
+#ifdef __BIG_ENDIAN
+ *((u32 *)kernbuffer) = ((swap32 << 16) & 0xffff0000) | ((swap32 >> 16) & 0xffff);
+#else
*((u32 *)kernbuffer) = swap32;
+#endif
kernbuffer += 4;
}
addr += 4;
@@ -3435,6 +3457,9 @@
static struct usb_device_id sisusb_table [] = {
{ USB_DEVICE(0x0711, 0x0900) },
+ { USB_DEVICE(0x0711, 0x0901) },
+ { USB_DEVICE(0x0711, 0x0902) },
+ { USB_DEVICE(0x0711, 0x0920) },
{ USB_DEVICE(0x182d, 0x021c) },
{ USB_DEVICE(0x182d, 0x0269) },
{ }
현장 HG와 사인은 VGA로 콘솔 출력한 것
링크
diff -ru a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c
--- a/drivers/usb/misc/sisusbvga/sisusb.c 2006-07-30 15:15:36.000000000 +0900
+++ b/drivers/usb/misc/sisusbvga/sisusb.c 2006-07-31 00:08:10.000000000 +0900
@@ -76,6 +76,16 @@
DEFINE_MUTEX(disconnect_mutex);
+#ifdef __BIG_ENDIAN
+static void
+correct_endianness_buffer(u16* data, const int length)
+{
+ int i;
+ for (i = 0; i < length; i++)
+ *(data+i) = cpu_to_le16(*(data+i));
+}
+#endif
+
static void
sisusb_free_buffers(struct sisusb_usb_data *sisusb)
{
@@ -411,6 +421,10 @@
memcpy(buffer, kernbuffer, passsize);
kernbuffer += passsize;
+#ifdef __BIG_ENDIAN
+ if ((len & 3) == 0)
+ correct_endianness_buffer((u16 *)buffer, thispass/2);
+#endif
}
retry = 5;
@@ -906,9 +920,13 @@
if (userbuffer) {
if (get_user(swap32, (u32 __user *)userbuffer))
return -EFAULT;
- } else
+ } else {
swap32 = *((u32 *)kernbuffer);
+#ifdef __BIG_ENDIAN
+ swap32 = ((swap32 << 16) & 0xffff0000) | ((swap32 >> 16) & 0xffff);
+#endif
+ }
ret = sisusb_write_memio_long(sisusb,
SISUSB_TYPE_MEM,
addr,
@@ -1259,7 +1277,11 @@
userbuffer += 4;
} else {
+#ifdef __BIG_ENDIAN
+ *((u32 *)kernbuffer) = ((swap32 << 16) & 0xffff0000) | ((swap32 >> 16) & 0xffff);
+#else
*((u32 *)kernbuffer) = swap32;
+#endif
kernbuffer += 4;
}
addr += 4;
@@ -3435,6 +3457,9 @@
static struct usb_device_id sisusb_table [] = {
{ USB_DEVICE(0x0711, 0x0900) },
+ { USB_DEVICE(0x0711, 0x0901) },
+ { USB_DEVICE(0x0711, 0x0902) },
+ { USB_DEVICE(0x0711, 0x0920) },
{ USB_DEVICE(0x182d, 0x021c) },
{ USB_DEVICE(0x182d, 0x0269) },
{ }
Reference
이 문제에 관하여(예전에 만든 사인은 VGA 리눅스 커널 패치를 공양한다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/shiena/items/acc4f819ea9da322fb2d텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)