Ключевые слова:patch, kernel, (найти похожие документы)
- RU.LINUX (2:5077/15.22) ------------------------------------------ RU.LINUX -
From : Mikel Ivanov aka ABS 2:5009/3.46 29 Mar 00 14:34:46
Subj : ATX - выключать в реалмоде
-------------------------------------------------------------------------------
Hello Kirill!
28 Mar 00 16:16, Kirill Petroff wrote to Mikel Ivanov Aka Abs:
MA>> Есть такой трабл, характерен для матерей на неинтеловских
MA>> чипсетах, лечится либо патченьем ядра на предмет выключения тачки
MA>> в реалмоде (там 15h прерывание юзается) либо переходом на
MA>> 2.3.x/2.4.x ядра. У них эта опция (выключать в реале) встроенна.
KP> и как это ядро пропатчить по этому поводу? где патч взять и прочие
KP> доки?
док нету, патча тоже (если интересно то можешь поискать в инете (патч от
Линуса)), остался токма кусочек process.c
=== Cut ===#if defined(CONFIG_APM) && defined(CONFIG_APM_POWER_OFF)
/*
This is 16-bit protected mode code to disable paging and the cache,
switch to real mode and jump to the BIOS APM poweroff code.
*/
unsigned char apm_real_mode_poweroff [] ={
0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */
0x66, 0x83, 0xe0, 0x11, /* andl $0x00000011,%eax
*/
0x66, 0x0d, 0x00, 0x00, 0x00, 0x60, /* orl $0x60000000,%eax
*/
0x66, 0x0f, 0x22, 0xc0, /* movl %eax,%cr0 */
0x66, 0x0f, 0x22, 0xd8, /* movl %eax,%cr3 */
0x66, 0x0f, 0x20, 0xc3, /* movl %cr0,%ebx */
0x66, 0x81, 0xe3, 0x00, 0x00, 0x00, 0x60, /* andl $0x60000000,%ebx
*/
0x74, 0x02, /* jz f */
0x0f, 0x08, /* invd */
0x24, 0x10, /* f: andb $0x10,al */
0x66, 0x0f, 0x22, 0xc0, /* movl %eax,%cr0 */
0xea, 0xed, 0x0f, 0x00, 0x00, /* ljmp g */
0xb8, 0x00, 0x10, /* g: movw $0x1000,ax */
0x8e, 0xd0, /* movw ax,ss */
0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
0xb8, 0x04, 0x53, /* movw $0x5304,ax */
0xbb, 0x00, 0x00, /* movw $0x0000,bx */
0xb9, 0x00, 0x00, /* movw $0x0000,cx */
0xcd, 0x15, /* int $0x15 */
0xb8, 0x01, 0x53, /* movw $0x5301,ax */
0xbb, 0x00, 0x00, /* movw $0x0000,bx */
0xb9, 0x00, 0x00, /* movw $0x0000,cx */
0xcd, 0x15, /* int $0x15 */
0xb8, 0x0E, 0x53, /* movw $0x530E,ax */
0xbb, 0x01, 0x00, /* movw $0x0000,bx */
0xb9, 0x02, 0x01, /* movw $0x0102,cx */
0xcd, 0x15, /* int $0x15 */
0xb8, 0x07, 0x53, /* movw $0x5307,ax */
0xbb, 0x01, 0x00, /* movw $0x0001,bx */
0xb9, 0x03, 0x00, /* movw $0x0003,cx */
0xcd, 0x15 /* int $0x15 */
};
void apm_realmode_poweroff(void)
{
cli ();
/*
Remap the kernel at virtual address zero, as well as offset zero
from the kernel segment. This assumes the kernel segment starts at
virtual address 0xc0000000.
*/
memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
/*
Make sure the first page is mapped to the start of physical memory.
It is normally not mapped, to trap kernel NULL pointer dereferences.
*/
pg0 [0] = 7;
/*
Use `swapper_pg_dir' as our page directory. We bother with
`SET_PAGE_DIR' because although might be rebooting, but if we change
the way we set root page dir in the future, then we wont break a
seldom used feature ;)
*/
SET_PAGE_DIR(current,swapper_pg_dir);
/*
For the switch to real mode, copy some code to low memory. It has
to be in the first 64k because it is running in 16-bit mode, and it
has to have the same physical and virtual address, because it turns
off paging. Copy it near the end of the first page, out of the way
of BIOS variables.
*/
memcpy ((void *) (0x1000 - sizeof (apm_real_mode_poweroff)),
apm_real_mode_poweroff, sizeof (apm_real_mode_poweroff));
/*
Set up the IDT for real mode.
*/
__asm__ __volatile__ ("lidt %0" : : "m" (real_mode_idt));
/*
Set up a GDT from which we can load segment descriptors for real
mode. The GDT is not used in real mode; it is just needed here to
prepare the descriptors.
*/
__asm__ __volatile__ ("lgdt %0" : : "m" (real_mode_gdt));
/*
Load the data segment registers, and thus the descriptors ready for
real mode. The base address of each segment is 0x100, 16 times the
selector value being loaded here. This is so that the segment
registers don't have to be reloaded after switching to real mode:
the values are consistent for real mode operation already.
*/
__asm__ __volatile__ ("movw $0x0010,%%ax\n"
"\tmovw %%ax,%%ds\n"
"\tmovw %%ax,%%es\n"
"\tmovw %%ax,%%fs\n"
"\tmovw %%ax,%%gs\n"
"\tmovw %%ax,%%ss" : : : "eax");
/*
Jump to the 16-bit code that we copied earlier. It disables paging
and the cache, switches to real mode, and jumps to the BIOS APM
entry point.
*/
__asm__ __volatile__ ("ljmp $0x0008,%0"
:
: "i" ((void *) (0x1000 - sizeof
(apm_real_mode_poweroff))));
}
#endif
void machine_power_off(void)
{
#if defined(CONFIG_APM) && defined(CONFIG_APM_POWER_OFF)
apm_realmode_poweroff();
#endif
}
=== Cut ==
добавить в process.c, немножко подправить (если нужно) и можно юзать. У меня
работал, пока не поменял мамку на нормальную.
С уважением Mikel
--- GoldED/W32 3.0.1 * Origin: Сначала дуумают, потом квакают... (2:5009/3.46)