예전에 만든 사인은 VGA 리눅스 커널 패치를 공양한다

4132 단어 현장커널리눅스

소개



그 옛날, NAS 조립 키트의 현장 HG 가 있어, 유지의 데비안화 킷으로 보통의 리눅스로서 동작했습니다. 현상 HG는 디스플레이 출력 단자가 없기 때문에 리모트 접속 밖에 할 수 없었습니다만 같은 시기에 USB를 VGA 출력으로 변환한다 사인은 VGA .

무엇이 문제였는지



사인은 VGA가 나왔을 때는 이미 sisusb로서 Linux 드라이버가 있었습니다만, 이하의 문제에 의해 동작하지 않았습니다.
  • 여러 장치 ID와 호환되지 않음
  • ppc (big endian) 미대응

  • 첫 번째는 제품의 색상 변형에서 장치 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로 콘솔 출력한 것


    링크


  • 현장 HG
  • 사인은 VGA
  • Bug 7000 - patch for correct endianness to sisusb
  • 좋은 웹페이지 즐겨찾기