mirror of
https://github.com/timmypidashev/web.git
synced 2026-04-14 02:53:51 +00:00
Add commands mdx component; continue work on coreboot post
This commit is contained in:
@@ -29,11 +29,13 @@
|
|||||||
"marked": "^15.0.8",
|
"marked": "^15.0.8",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
|
"react-icons": "^5.5.0",
|
||||||
"react-responsive": "^10.0.1",
|
"react-responsive": "^10.0.1",
|
||||||
"reading-time": "^1.5.0",
|
"reading-time": "^1.5.0",
|
||||||
"rehype-pretty-code": "^0.14.1",
|
"rehype-pretty-code": "^0.14.1",
|
||||||
"rehype-slug": "^6.0.0",
|
"rehype-slug": "^6.0.0",
|
||||||
"schema-dts": "^1.1.5",
|
"schema-dts": "^1.1.5",
|
||||||
"typewriter-effect": "^2.21.0"
|
"typewriter-effect": "^2.21.0",
|
||||||
|
"unist-util-visit": "^5.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
15
src/pnpm-lock.yaml
generated
15
src/pnpm-lock.yaml
generated
@@ -44,6 +44,9 @@ importers:
|
|||||||
react-dom:
|
react-dom:
|
||||||
specifier: ^18.3.1
|
specifier: ^18.3.1
|
||||||
version: 18.3.1(react@18.3.1)
|
version: 18.3.1(react@18.3.1)
|
||||||
|
react-icons:
|
||||||
|
specifier: ^5.5.0
|
||||||
|
version: 5.5.0(react@18.3.1)
|
||||||
react-responsive:
|
react-responsive:
|
||||||
specifier: ^10.0.1
|
specifier: ^10.0.1
|
||||||
version: 10.0.1(react@18.3.1)
|
version: 10.0.1(react@18.3.1)
|
||||||
@@ -62,6 +65,9 @@ importers:
|
|||||||
typewriter-effect:
|
typewriter-effect:
|
||||||
specifier: ^2.21.0
|
specifier: ^2.21.0
|
||||||
version: 2.21.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 2.21.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
|
unist-util-visit:
|
||||||
|
specifier: ^5.0.0
|
||||||
|
version: 5.0.0
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@astrojs/react':
|
'@astrojs/react':
|
||||||
specifier: ^4.2.4
|
specifier: ^4.2.4
|
||||||
@@ -1867,6 +1873,11 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
react: ^18.3.1
|
react: ^18.3.1
|
||||||
|
|
||||||
|
react-icons@5.5.0:
|
||||||
|
resolution: {integrity: sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==}
|
||||||
|
peerDependencies:
|
||||||
|
react: '*'
|
||||||
|
|
||||||
react-is@16.13.1:
|
react-is@16.13.1:
|
||||||
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
||||||
|
|
||||||
@@ -4636,6 +4647,10 @@ snapshots:
|
|||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
scheduler: 0.23.2
|
scheduler: 0.23.2
|
||||||
|
|
||||||
|
react-icons@5.5.0(react@18.3.1):
|
||||||
|
dependencies:
|
||||||
|
react: 18.3.1
|
||||||
|
|
||||||
react-is@16.13.1: {}
|
react-is@16.13.1: {}
|
||||||
|
|
||||||
react-refresh@0.17.0: {}
|
react-refresh@0.17.0: {}
|
||||||
|
|||||||
59
src/src/components/mdx/code-block.tsx
Normal file
59
src/src/components/mdx/code-block.tsx
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Check, Copy } from 'lucide-react';
|
||||||
|
|
||||||
|
interface CodeBlockProps {
|
||||||
|
children: React.ReactNode;
|
||||||
|
className?: string;
|
||||||
|
'data-language'?: string;
|
||||||
|
'data-theme'?: string;
|
||||||
|
raw?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CodeBlock: React.FC<CodeBlockProps> = ({
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
'data-language': language,
|
||||||
|
raw
|
||||||
|
}) => {
|
||||||
|
const [copied, setCopied] = useState(false);
|
||||||
|
|
||||||
|
const handleCopy = () => {
|
||||||
|
if (raw) {
|
||||||
|
navigator.clipboard.writeText(raw);
|
||||||
|
setCopied(true);
|
||||||
|
setTimeout(() => setCopied(false), 2000);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="relative group">
|
||||||
|
{language && (
|
||||||
|
<div className="absolute top-0 left-4 -translate-y-1/2">
|
||||||
|
<span className="inline-block px-2 py-1 text-xs font-bold text-foreground/80 bg-[#282828] rounded">
|
||||||
|
{language}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<button
|
||||||
|
onClick={handleCopy}
|
||||||
|
className="absolute top-0 right-0 -translate-y-[50%] hidden group-hover:flex items-center gap-1 px-2 py-1 text-xs font-medium text-foreground/80 bg-[#282828] rounded hover:text-foreground transition-colors"
|
||||||
|
aria-label="Copy code"
|
||||||
|
>
|
||||||
|
{copied ? (
|
||||||
|
<>
|
||||||
|
<Check size={14} />
|
||||||
|
Copied!
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Copy size={14} />
|
||||||
|
Copy
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
<pre className={className}>
|
||||||
|
<code>{children}</code>
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
188
src/src/components/mdx/command.tsx
Normal file
188
src/src/components/mdx/command.tsx
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Terminal, Copy, Check } from 'lucide-react';
|
||||||
|
// Import all required icons from react-icons
|
||||||
|
import { FaDebian, FaFedora } from 'react-icons/fa6';
|
||||||
|
import { SiGentoo, SiNixos, SiArchlinux } from 'react-icons/si';
|
||||||
|
|
||||||
|
const Commands = ({
|
||||||
|
commandId,
|
||||||
|
description,
|
||||||
|
archCommand,
|
||||||
|
debianCommand,
|
||||||
|
fedoraCommand,
|
||||||
|
gentooCommand,
|
||||||
|
nixCommand
|
||||||
|
}) => {
|
||||||
|
const [activeTab, setActiveTab] = useState('arch');
|
||||||
|
const [copied, setCopied] = useState(false);
|
||||||
|
|
||||||
|
const distros = [
|
||||||
|
{
|
||||||
|
id: 'arch',
|
||||||
|
name: 'Arch',
|
||||||
|
icon: SiArchlinux,
|
||||||
|
command: archCommand || 'echo "No command specified for Arch"'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'debian',
|
||||||
|
name: 'Debian',
|
||||||
|
icon: FaDebian,
|
||||||
|
command: debianCommand || 'echo "No command specified for Debian"'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'fedora',
|
||||||
|
name: 'Fedora',
|
||||||
|
icon: FaFedora,
|
||||||
|
command: fedoraCommand || 'echo "No command specified for Fedora"'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'gentoo',
|
||||||
|
name: 'Gentoo',
|
||||||
|
icon: SiGentoo,
|
||||||
|
command: gentooCommand || 'echo "No command specified for Gentoo"'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'nix',
|
||||||
|
name: 'NixOS',
|
||||||
|
icon: SiNixos,
|
||||||
|
command: nixCommand || 'echo "No command specified for NixOS"'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const copyToClipboard = (text) => {
|
||||||
|
navigator.clipboard.writeText(text)
|
||||||
|
.then(() => {
|
||||||
|
setCopied(true);
|
||||||
|
setTimeout(() => setCopied(false), 2000);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error('Failed to copy: ', err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="w-full rounded-md overflow-hidden border border-foreground/20 bg-background my-4">
|
||||||
|
{/* Header with Terminal Icon and Copy Button */}
|
||||||
|
<div className="bg-background border-b border-foreground/20 text-foreground p-2 flex items-center justify-between">
|
||||||
|
<div className="flex items-center">
|
||||||
|
<Terminal size={20} className="mr-2 text-yellow-bright" />
|
||||||
|
<div className="text-sm font-comic-code">
|
||||||
|
{description || "Terminal Command"}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
onClick={() => copyToClipboard(distros.find(d => d.id === activeTab).command)}
|
||||||
|
className="bg-background hover:bg-foreground/10 text-foreground text-xs px-2 py-1 rounded flex items-center"
|
||||||
|
>
|
||||||
|
{copied ? (
|
||||||
|
<>
|
||||||
|
<Check size={14} className="mr-1 text-green-bright" />
|
||||||
|
<span>Copied</span>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Copy size={14} className="mr-1 text-foreground/70" />
|
||||||
|
<span>Copy</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Tabs */}
|
||||||
|
<div className="flex flex-wrap border-b border-foreground/20 bg-background">
|
||||||
|
{distros.map((distro) => {
|
||||||
|
const IconComponent = distro.icon;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
key={distro.id}
|
||||||
|
className={`px-3 py-2 text-sm font-medium flex items-center ${
|
||||||
|
activeTab === distro.id
|
||||||
|
? 'bg-background border-b-2 border-blue-bright text-blue-bright'
|
||||||
|
: 'text-foreground/80 hover:text-foreground hover:bg-foreground/5'
|
||||||
|
}`}
|
||||||
|
onClick={() => setActiveTab(distro.id)}
|
||||||
|
>
|
||||||
|
<span className="mr-1 inline-flex items-center">
|
||||||
|
<IconComponent size={16} />
|
||||||
|
</span>
|
||||||
|
{distro.name}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Command Display with Horizontal Scrolling */}
|
||||||
|
<div className="bg-[#282828] text-foreground p-3 overflow-x-auto">
|
||||||
|
<div className="flex items-center font-comic-code text-sm whitespace-nowrap">
|
||||||
|
<span className="text-orange-bright mr-2">$</span>
|
||||||
|
<span className="text-purple-bright">
|
||||||
|
{distros.find(d => d.id === activeTab).command}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Also include a simpler command component for single commands
|
||||||
|
const Command = ({
|
||||||
|
command,
|
||||||
|
description,
|
||||||
|
shell = "bash"
|
||||||
|
}) => {
|
||||||
|
const [copied, setCopied] = useState(false);
|
||||||
|
|
||||||
|
const copyToClipboard = () => {
|
||||||
|
navigator.clipboard.writeText(command)
|
||||||
|
.then(() => {
|
||||||
|
setCopied(true);
|
||||||
|
setTimeout(() => setCopied(false), 2000);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error('Failed to copy: ', err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="w-full rounded-md overflow-hidden border border-foreground/20 bg-background my-4">
|
||||||
|
{/* Header with Terminal Icon and Copy Button */}
|
||||||
|
<div className="bg-background border-b border-foreground/20 text-foreground p-2 flex items-center justify-between">
|
||||||
|
<div className="flex items-center">
|
||||||
|
<Terminal size={20} className="mr-2 text-yellow-bright" />
|
||||||
|
<div className="text-sm font-comic-code">
|
||||||
|
{description || "Terminal Command"}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
onClick={copyToClipboard}
|
||||||
|
className="bg-background hover:bg-foreground/10 text-foreground text-xs px-2 py-1 rounded flex items-center"
|
||||||
|
>
|
||||||
|
{copied ? (
|
||||||
|
<>
|
||||||
|
<Check size={14} className="mr-1 text-green-bright" />
|
||||||
|
<span>Copied</span>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Copy size={14} className="mr-1 text-foreground/70" />
|
||||||
|
<span>Copy</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Command Display with Horizontal Scrolling */}
|
||||||
|
<div className="bg-[#282828] text-foreground p-3 overflow-x-auto">
|
||||||
|
<div className="flex items-center font-comic-code text-sm whitespace-nowrap">
|
||||||
|
<span className="text-orange-bright mr-2">$</span>
|
||||||
|
<span className="text-purple-bright">
|
||||||
|
{command}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { Commands, Command };
|
||||||
78
src/src/content/blog/thinkpad-t440p-coreboot-guide.mdx
Normal file
78
src/src/content/blog/thinkpad-t440p-coreboot-guide.mdx
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
---
|
||||||
|
title: Thinkpad T440p Coreboot Guide
|
||||||
|
description: The definitive guide on corebooting a Thinkpad T440p
|
||||||
|
author: Timothy Pidashev
|
||||||
|
tags: [t440p, coreboot, thinkpad]
|
||||||
|
date: 2025-01-15
|
||||||
|
image: "/blog/thinkpad-t440p-coreboot-guide/thumbnail.png"
|
||||||
|
---
|
||||||
|
|
||||||
|
import { Commands, Command } from "@/components/mdx/command";
|
||||||
|
|
||||||
|
> **Interactive Script Available!**
|
||||||
|
> Want to skip the manual steps in this guide?
|
||||||
|
> I've created an interactive script that can automate the entire process step by step as you follow along.
|
||||||
|
> This script supports Arch, Debian, Fedora, Gentoo, and Nix!
|
||||||
|
|
||||||
|
<Command
|
||||||
|
description="Interactive script"
|
||||||
|
command="curl -fsSL https://timmypidashev.dev/scripts/run.sh | sh -s -- -t coreboot-t440p"
|
||||||
|
client:load
|
||||||
|
/>
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
The Thinkpad T440p is a powerful and versatile laptop that can be further enhanced by installing coreboot,
|
||||||
|
an open-source BIOS replacement. This guide will walk you through the process of corebooting your T440p,
|
||||||
|
including flashing the BIOS chip and installing the necessary software.
|
||||||
|
|
||||||
|
## What You'll Need
|
||||||
|
|
||||||
|
Before getting started corebooting your T440p, make sure you have the following:
|
||||||
|
|
||||||
|
- **Thinkpad T440p**: This guide is specifically for the T440p model.
|
||||||
|
- **CH341A Programmer**: This is a USB device used to flash the BIOS chip.
|
||||||
|
- **Screwdriver**: A torx screwdriver is needed to open the laptop.
|
||||||
|
|
||||||
|
## Installing Dependencies
|
||||||
|
|
||||||
|
Install the following programs. These will be needed to compile coreboot and flash the BIOS.
|
||||||
|
|
||||||
|
<Commands
|
||||||
|
description="Install prerequisite packages"
|
||||||
|
archCommand="sudo pacman -S base-devel curl git gcc-ada ncurses zlib nasm sharutils unzip flashrom"
|
||||||
|
debianCommand="sudo apt install build-essential curl git gnat libncurses-dev zlib1g-dev nasm sharutils unzip flashrom"
|
||||||
|
fedoraCommand="sudo dnf install @development-tools curl git gcc-gnat ncurses-devel zlib-devel nasm sharutils unzip flashrom"
|
||||||
|
gentooCommand="sudo emerge --ask sys-devel/base-devel net-misc/curl dev-vcs/git sys-devel/gcc ncurses dev-libs/zlib dev-lang/nasm app-arch/sharutils app-arch/unzip sys-apps/flashrom"
|
||||||
|
nixCommand="nix-env -i stdenv curl git gcc gnat ncurses zlib nasm sharutils unzip flashrom"
|
||||||
|
client:load
|
||||||
|
/>
|
||||||
|
|
||||||
|
## Disassembling the Laptop
|
||||||
|
1. **Power off your laptop**: Make sure your T440p is completely powered off and unplugged from any power source.
|
||||||
|
2. **Remove the battery**: Flip the laptop over and remove the battery by sliding the latch to the unlock position and lifting it out.
|
||||||
|
3. **Unscrew the back panel**: Use a torx screwdriver to remove the screws securing the back panel.
|
||||||
|
|
||||||
|
## Locating the EEPROM Chips
|
||||||
|
|
||||||
|
In order to flash the laptop, you will need to have access to two EEPROM chips located next to the sodimm RAM.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Assembling the SPI Flasher
|
||||||
|
|
||||||
|
Place the SPI flasher ribbon cable into the correct slot and make sure its the 3.3v variant
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
After the flasher is ready, connect it to your machine and ensure its ready to use:
|
||||||
|
|
||||||
|
<Command
|
||||||
|
description="Ensure the CH341A flasher is being detected"
|
||||||
|
command="flashrom --programmer ch341a_spi"
|
||||||
|
/>
|
||||||
|
|
||||||
|
Flashrom should report that programmer initialization was a success.
|
||||||
|
|
||||||
|
## Extracting Original BIOS
|
||||||
|
|
||||||
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
---
|
|
||||||
title: Thinkpad T440p Coreboot Guide
|
|
||||||
description: The definitive guide on corebooting a Thinkpad T440p
|
|
||||||
author: Timothy Pidashev
|
|
||||||
tags: [t440p, coreboot, thinkpad]
|
|
||||||
date: 2025-01-15
|
|
||||||
image: "/blog/thinkpad-t440p-coreboot-guide/thumbnail.png"
|
|
||||||
---
|
|
||||||
|
|
||||||
> **Interactive Script Available!**
|
|
||||||
> Want to skip the manual steps in this guide?
|
|
||||||
> I've created an interactive script that can automate the entire process step by step as you follow along.
|
|
||||||
> Simply run the following command in your terminal to get started:
|
|
||||||
>
|
|
||||||
> ```
|
|
||||||
> curl -fsSL https://timmypidashev.dev/scripts/run.sh | sh -s -- -t coreboot-t440p
|
|
||||||
> ```
|
|
||||||
> NOTE: This script supports Arch, Debian, Fedora, Gentoo, and Nix linux distributions!
|
|
||||||
|
|
||||||
## Getting Started
|
|
||||||
The Thinkpad T440p is a powerful and versatile laptop that can be further enhanced by installing coreboot,
|
|
||||||
an open-source BIOS replacement. This guide will walk you through the process of corebooting your T440p,
|
|
||||||
including flashing the BIOS chip and installing the necessary software.
|
|
||||||
|
|
||||||
## What You'll Need
|
|
||||||
|
|
||||||
Before getting started corebooting your T440p, make sure you have the following:
|
|
||||||
|
|
||||||
- **Thinkpad T440p**: This guide is specifically for the T440p model.
|
|
||||||
- **CH341A Programmer**: This is a USB device used to flash the BIOS chip.
|
|
||||||
- **Screwdriver**: A torx screwdriver is needed to open the laptop.
|
|
||||||
|
|
||||||
## Disassembling the Laptop
|
|
||||||
1. **Power off your laptop**: Make sure your T440p is completely powered off and unplugged from any power source.
|
|
||||||
2. **Remove the battery**: Flip the laptop over and remove the battery by sliding the latch to the unlock position and lifting it out.
|
|
||||||
3. **Unscrew the back panel**: Use a torx screwdriver to remove the screws securing the back panel.
|
|
||||||
|
|
||||||
## Locating the EEPROM Chips
|
|
||||||
Reference in New Issue
Block a user