嵌入式(驱动-基础):10---内核模块“绕过”GPL(wrapper函数)

一、GPL与内核模块导出符号的关系

  • 我们前面介绍过,可以使用EXPORT_SYMBOL()或EXPORT_SYMBOL_GPL()导出内核模块符号
    • EXPORT_SYMBOL:不论内核模块是否包含GPL都可以使用
    • EXPORT_SYMBOL_GPL:只适用于包含GPL许可权的模块
  • 但是内核的Documentation/DocBook/kernel-hacking.tmpl指出(见下图):内核用EXPORT_SYMBOL_GPL()导出的符号是不可以被非GPL模块引用的

嵌入式(驱动-基础):10---内核模块“绕过”GPL(wrapper函数)

二、非法使用符号表

第一种情况

  • 由于相当多的内核符号都是以EXPORT_SYMBOL_GPL()导出的,所以历史上曾经有一些公司把内核的EXPORT_SYMBOL_GPL()直接改为EXPORT_SYMBOL(),然后将修改后的内核以GPL形式发布。这样修改内核之后,模块不再使用内核的EXPORT_SYMBOL_GPL()符号,因此模块不再需要GPL
  • 对此linus的回复是:“I think both them said that anybody who were to change a xyz_GPL to the non-GPL one in order to use it with a non-GPL module would almost immediately fall under the“willful infringement”thing, and that it would make it MUCH easier to get triple damages and/or injunctions,since they clearly knew about it”
  • 因此,这种做法可能构成“蓄意侵权(willful infringement)”

第二种情况

  • 另外一种做法是写一个wrapper内核模块(这个模块遵循GPL),把EXPORT_SYMBOL_GPL()导出的符号封装一次后再以EXPORT_SYMBOL()形式导出,而其他的模块不直接调用内核而是调用wrapper 函数
  • 如下图所示:

嵌入式(驱动-基础):10---内核模块“绕过”GPL(wrapper函数)

三、总结

  • 一般认为,保守的做法是Linux内核不能使用非GPL许可权