Он успешно работает в пользовательском пространстве, но можно обсуждать номера вызовов, наличие/отсутствие блокировок (я их не делал) и прочее.
То есть можно применять так как есть, а можно подумать над усовершенствованием его и (если понравится) включении в ядро.
kerneltblpatch.txt :
- Код: Выделить всё
- 1000 common spkon sys_spkon
 1001 common spkoff sys_spkoff
 1002 common spkplay sys_spkplay
kernelrwpatch.txt :
- Код: Выделить всё
 #include <linux/io.h>
 SYSCALL_DEFINE0(spkon)
 {
 outb_p(inb_p(0x61) | 3, 0x61);
 return 0;
 }
 SYSCALL_DEFINE0(spkoff)
 {
 outb(inb_p(0x61) & 0xFC, 0x61);
 return 0;
 }
 SYSCALL_DEFINE1(spkplay, unsigned short int, w)
 {
 outb_p(0xB6, 0x43);
 outb_p(w & 0xff, 0x42);
 outb((w >> 8) & 0xff, 0x42);
 return 0;
 }
spkpatch.sh :
- Код: Выделить всё
- #!/bin/bash
 cat kernelrwpatch.txt >> fs/read_write.c
 cat kerneltblpatch.txt >> tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
 cat kerneltblpatch.txt >> arch/x86/entry/syscalls/syscall_64.tbl
http://soft.self-made-free.ru/kernelpatchspk.tar.xz
Плеер для такого патча:
- Код: Выделить всё
- program gorg64_spkplay_syscalls;
 {$MODE OBJFPC}
 {$RANGECHECKS ON}
 {$LONGSTRINGS ON}
 {$SMARTLINK ON}
 {$ASMMODE INTEL}
 //{$CODEPAGE UTF8}
 {
 Program for playing melodys on PC-Speaker.
 For GNU/Linux 64 bit version. Root priveleges needed.
 Version: 2.
 Written on FreePascal (https://freepascal.org/).
 Copyright (C) 2021 Artyomov Alexander
 http://self-made-free.ru/ (Ex http://aralni.narod.ru/)
 aralni@mail.ru
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License as
 published by the Free Software Foundation, either version 3 of the
 License, or (at your option) any later version.
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 GNU Affero General Public License for more details.
 You should have received a copy of the GNU Affero General Public License
 along with this program. If not, see <https://www.gnu.org/licenses/>.
 }
 uses sysutils,unix,baseunix,linux;
 type
 TTW = packed record
 tone, duration : Word;
 end;
 TAoW = array of Word;
 TAoTW = array of TTW;
 TSpkFile = class(TObject)
 a : TAoTW;
 fFileName : utf8string;
 public
 function LoadFromFile(fn : utf8string) : boolean;
 end;
 procedure spkon; assembler;
 asm
 mov rax, 1000
 syscall
 end;
 procedure spkoff; assembler;
 asm
 mov rax, 1001
 syscall
 end;
 procedure spk(w : Qword); assembler;
 asm
 mov rax, 1002
 mov rdi, w
 syscall
 end;
 function TSpkFile.LoadFromFile(fn : utf8string) : boolean;
 var
 fp : File of TTW;
 fs : Int64;
 begin
 Assign(fp, fn);
 FileMode := 0;
 {$I-}
 ReSet(fp);
 {$I+} if IOResult <> 0 then Exit(true);
 {$I-}
 fs := FileSize(fp);
 {$I+} if IOResult <> 0 then Exit(true);
 SetLength(a, fs);
 {$I-}
 BlockRead(fp, a[0], fs);
 {$I+} if IOResult <> 0 then Exit(true);
 {$I-}
 Close(fp);
 {$I+} if IOResult <> 0 then Exit(true);
 fFileName := fn;
 Exit(false);
 end;
 const
 lockfilename = '/tmp/speaker.lock';
 var
 f, ff : Int64;
 oa,na : PSigActionRec;
 lockfile : File of Byte;
 Procedure DoSig(sig : cint);cdecl;
 begin
 writeln('Receiving signal: ',sig);
 spkoff;
 DeleteFile(lockfilename);
 halt(0);
 end;
 begin
 WriteLn('GALAXY ORGANIZER SPEAKER PLAYER Version 3');
 WriteLn('Artyomov Alexander 2022 License: GNU AGPLv3 and above');
 WriteLn('Use: gorg64_spkplay_syscalls or gorg64_spkplay_syscalls somemusic.speaker somemusic2.speaker ...');
 if FileExists(lockfilename) then begin WriteLn('Already running. Or just locked by (in that case delete it): ' + lockfilename); exit; end;
 Assign(lockfile, lockfilename);
 ReWrite(lockfile);
 Close(lockfile);
 new(na);
 new(oa);
 na^.sa_Handler:=SigActionHandler(@DoSig);
 fillchar(na^.Sa_Mask,sizeof(na^.sa_mask),#0);
 na^.Sa_Flags:=0;
 na^.Sa_Restorer:=Nil;
 if fpSigAction(SigTerm,na,oa)<>0 then
 begin
 writeln('Error: ',fpgeterrno,'.');
 DeleteFile(lockfilename);
 halt(1);
 end;
 if fpSigAction(SigHup,na,oa)<>0 then
 begin
 writeln('Error: ',fpgeterrno,'.');
 DeleteFile(lockfilename);
 halt(1);
 end;
 if fpSigAction(SigInt,na,oa)<>0 then
 begin
 writeln('Error: ',fpgeterrno,'.');
 DeleteFile(lockfilename);
 halt(1);
 end;
 if fpSigAction(SigQuit,na,oa)<>0 then
 begin
 writeln('Error: ',fpgeterrno,'.');
 DeleteFile(lockfilename);
 halt(1);
 end;
 if fpSigAction(SigTStp,na,oa)<>0 then
 begin
 writeln('Error: ',fpgeterrno,'.');
 DeleteFile(lockfilename);
 halt(1);
 end;
 //fpSystem('renice -n -19 -p ' + inttostr(fpgetpid));
 if ParamCount = 0 then begin
 spkon; spk(1000); sleep(2000); spk(300); sleep(2000); spkoff;
 DeleteFile(lockfilename);
 Halt;
 end;
 for ff := 1 to ParamCount do
 with TSpkFile.Create do begin
 if LoadFromFile(ParamStr(ff)) then begin
 WriteLn('Err'); spkon; spk(1000); sleep(1000); spk(300); sleep(1000); spkoff;
 DeleteFile(lockfilename); Halt(2);
 end;
 WriteLn(WideChar($1F) + '♪ ♫ Playing file: ' + fFileName);
 spkon;
 for f := 0 to High(a) do begin
 if a[f].duration < 1 then continue;
 if a[f].tone < 1 then begin
 spkoff;
 sleep(a[f].duration);
 spkon;
 end else begin
 spk(a[f].tone);
 sleep(a[f].duration);
 end;
 end;
 spkoff;
 Free;
 end;
 DeleteFile(lockfilename);
 end.



