A razão não é histórica, mas prática. Existem muitos e muitos programas que são executados no kernel do Linux; se uma interface do kernel quebrar esses programas, todos precisarão atualizar esses programas.
Agora é verdade que a maioria dos programas não depende de fato das interfaces do kernel diretamente (as chamadas do sistema ), mas apenas nas interfaces da biblioteca padrão C (C wrappers ao redor das chamadas do sistema). Ah, mas qual biblioteca padrão? Glibc? uClibC? Dietlibc? Biônico? Musl? etc.
Mas também há muitos programas que implementam serviços específicos do sistema operacional e dependem de interfaces de kernel que não são expostas pela biblioteca padrão. (No Linux, muitos deles são oferecidos por /proc
e /sys
.)
E depois há binários estaticamente compilados. Se uma atualização do kernel quebrar uma dessas, a única solução seria recompilá-las. Se você tem a fonte: o Linux também suporta software proprietário.
Mesmo quando a fonte está disponível, reunir tudo pode ser uma dor. Especialmente quando você está atualizando seu kernel para consertar um bug com seu hardware. As pessoas geralmente atualizam seu kernel independentemente do resto do sistema porque precisam do suporte de hardware. Nas palavras Linus Torvalds :
Breaking user programs simply isn't acceptable. (…) We know that people use old binaries for years and years, and that making a new release doesn't mean that you can just throw that out. You can trust us.
Ele também explica que uma das razões para tornar isso uma regra strong é evitar a dependência onde você Não apenas temos que atualizar outro programa para fazer com que um novo kernel funcione, mas também atualizar outro programa, e outro, e outro, porque tudo depende de uma certa versão de tudo.
It's somewhat ok to have a well-defined one-way dependency. It's sad, but inevitable sometimes. (…) What is NOT ok is to have a two-way dependency. If user-space HAL code depends on a new kernel, that's ok, although I suspect users would hope that it wouldn't be "kernel of the week", but more a "kernel of the last few months" thing.
But if you have a TWO-WAY dependency, you're screwed. That means that you have to upgrade in lock-step, and that just IS NOT ACCEPTABLE. It's horrible for the user, but even more importantly, it's horrible for developers, because it means that you can't say "a bug happened" and do things like try to narrow it down with bisection or similar.
No userspace, essas dependências mútuas geralmente são resolvidas mantendo-se diferentes versões de bibliotecas; mas você só precisa rodar um kernel, então ele tem que suportar tudo que as pessoas possam querer fazer com ele.
backward compatibility for [system calls declared stable] will be guaranteed for at least 2 years.
Na prática,
Most interfaces (like syscalls) are expected to never change and always be available.
O que muda com mais frequência são as interfaces que só devem ser usadas por programas relacionados a hardware, em /sys
. ( /proc
, por outro lado, que desde a introdução de /sys
foi reservada para serviços não relacionados a hardware, praticamente nunca quebra de maneiras incompatíveis.)
Em resumo,
breaking user space would require fixes on the application level
e isso é ruim porque existe apenas um kernel, que as pessoas querem atualizar independentemente do resto do sistema, mas existem muitos aplicativos com interdependências complexas. É mais fácil manter o kernel estável para manter milhares de aplicativos atualizados em milhões de configurações diferentes.